diff options
author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-12-18 22:12:54 -0800 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-12-18 22:12:54 -0800 |
commit | 890171b36ac42cf60f6fe0c8c2082899f4438e6a (patch) | |
tree | 37c006e826b3e15de25f9fd7f0e649a60320d44c | |
parent | 3c678d0c216d2c232cde41c942e8745bd66d1ddb (diff) | |
download | ltsi-kernel-890171b36ac42cf60f6fe0c8c2082899f4438e6a.tar.gz |
zynq patches added
109 files changed, 9448 insertions, 0 deletions
diff --git a/patches.zynq/0001-ARM-zynq-Remove-init_irq-declaration-in-machine-desc.patch b/patches.zynq/0001-ARM-zynq-Remove-init_irq-declaration-in-machine-desc.patch new file mode 100644 index 00000000000000..27cd187239fb58 --- /dev/null +++ b/patches.zynq/0001-ARM-zynq-Remove-init_irq-declaration-in-machine-desc.patch @@ -0,0 +1,43 @@ +From 3126ef4e090161d7a9dfcde771a5819ca050232e Mon Sep 17 00:00:00 2001 +From: Maxime Ripard <maxime.ripard@free-electrons.com> +Date: Tue, 14 May 2013 17:38:35 +0200 +Subject: ARM: zynq: Remove init_irq declaration in machine description + +Commit ebafed7a ("ARM: irq: Call irqchip_init if no init_irq function is +specified") removed the need to explictly setup the init_irq field in +the machine description when using only irqchip_init. Remove that +declaration for zynq as well. + +Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com> +Acked-by: Michal Simek <monstr@monstr.eu> +Signed-off-by: Michal Simek <michal.simek@xilinx.com> +(cherry picked from commit 7ac161c43506f60b07684bc8a98eeb50d8e8664c) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + arch/arm/mach-zynq/common.c | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/arch/arm/mach-zynq/common.c b/arch/arm/mach-zynq/common.c +index 5bfe7035b73d..4c0199b88a04 100644 +--- a/arch/arm/mach-zynq/common.c ++++ b/arch/arm/mach-zynq/common.c +@@ -25,7 +25,6 @@ + #include <linux/of_irq.h> + #include <linux/of_platform.h> + #include <linux/of.h> +-#include <linux/irqchip.h> + + #include <asm/mach/arch.h> + #include <asm/mach/map.h> +@@ -106,7 +105,6 @@ static const char * const zynq_dt_match[] = { + MACHINE_START(XILINX_EP107, "Xilinx Zynq Platform") + .smp = smp_ops(zynq_smp_ops), + .map_io = zynq_map_io, +- .init_irq = irqchip_init, + .init_machine = zynq_init_machine, + .init_time = zynq_timer_init, + .dt_compat = zynq_dt_match, +-- +1.8.5.rc3 + diff --git a/patches.zynq/0002-ARM-zynq-Not-to-rewrite-jump-code-when-starting-addr.patch b/patches.zynq/0002-ARM-zynq-Not-to-rewrite-jump-code-when-starting-addr.patch new file mode 100644 index 00000000000000..675801e0a0631b --- /dev/null +++ b/patches.zynq/0002-ARM-zynq-Not-to-rewrite-jump-code-when-starting-addr.patch @@ -0,0 +1,83 @@ +From 8dd1075f90304e8e02a60da019f44e511c98ef12 Mon Sep 17 00:00:00 2001 +From: Michal Simek <michal.simek@xilinx.com> +Date: Fri, 24 May 2013 17:58:55 +0200 +Subject: ARM: zynq: Not to rewrite jump code when starting address is 0x0 + +This configuration is used by remoteproc. + +Signed-off-by: Michal Simek <michal.simek@xilinx.com> +(cherry picked from commit 88cd4e882de73c2e62c38591abfe8c13fcc8386a) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + arch/arm/mach-zynq/platsmp.c | 52 ++++++++++++++++++++++---------------------- + 1 file changed, 26 insertions(+), 26 deletions(-) + +diff --git a/arch/arm/mach-zynq/platsmp.c b/arch/arm/mach-zynq/platsmp.c +index 5fc167e07619..023f225493f2 100644 +--- a/arch/arm/mach-zynq/platsmp.c ++++ b/arch/arm/mach-zynq/platsmp.c +@@ -53,34 +53,34 @@ int __cpuinit zynq_cpun_start(u32 address, int cpu) + &zynq_secondary_trampoline; + + zynq_slcr_cpu_stop(cpu); +- +- if (__pa(PAGE_OFFSET)) { +- zero = ioremap(0, trampoline_code_size); +- if (!zero) { +- pr_warn("BOOTUP jump vectors not accessible\n"); +- return -1; ++ if (address) { ++ if (__pa(PAGE_OFFSET)) { ++ zero = ioremap(0, trampoline_code_size); ++ if (!zero) { ++ pr_warn("BOOTUP jump vectors not accessible\n"); ++ return -1; ++ } ++ } else { ++ zero = (__force u8 __iomem *)PAGE_OFFSET; + } +- } else { +- zero = (__force u8 __iomem *)PAGE_OFFSET; +- } +- +- /* +- * This is elegant way how to jump to any address +- * 0x0: Load address at 0x8 to r0 +- * 0x4: Jump by mov instruction +- * 0x8: Jumping address +- */ +- memcpy((__force void *)zero, &zynq_secondary_trampoline, +- trampoline_size); +- writel(address, zero + trampoline_size); +- +- flush_cache_all(); +- outer_flush_range(0, trampoline_code_size); +- smp_wmb(); +- +- if (__pa(PAGE_OFFSET)) +- iounmap(zero); + ++ /* ++ * This is elegant way how to jump to any address ++ * 0x0: Load address at 0x8 to r0 ++ * 0x4: Jump by mov instruction ++ * 0x8: Jumping address ++ */ ++ memcpy((__force void *)zero, &zynq_secondary_trampoline, ++ trampoline_size); ++ writel(address, zero + trampoline_size); ++ ++ flush_cache_all(); ++ outer_flush_range(0, trampoline_code_size); ++ smp_wmb(); ++ ++ if (__pa(PAGE_OFFSET)) ++ iounmap(zero); ++ } + zynq_slcr_cpu_start(cpu); + + return 0; +-- +1.8.5.rc3 + diff --git a/patches.zynq/0003-arm-zynq-Remove-board-specific-compatibility-string.patch b/patches.zynq/0003-arm-zynq-Remove-board-specific-compatibility-string.patch new file mode 100644 index 00000000000000..d9ba446bd563ed --- /dev/null +++ b/patches.zynq/0003-arm-zynq-Remove-board-specific-compatibility-string.patch @@ -0,0 +1,34 @@ +From 11eab4485cd8a4466acfc3c36837d2e4fcac78ba Mon Sep 17 00:00:00 2001 +From: Soren Brinkmann <soren.brinkmann@xilinx.com> +Date: Thu, 13 Jun 2013 09:37:15 -0700 +Subject: arm: zynq: Remove board specific compatibility string + +It is not necessary to have board specific compatibility strings +in the platform code. The board dts files can use the more generic +'xlnx,zynq-7000' string. + +Signed-off-by: Soren Brinkmann <soren.brinkmann@xilinx.com> +Reviewed-by: Steffen Trumtrar <s.trumtrar@pengutronix.de> +Signed-off-by: Michal Simek <michal.simek@xilinx.com> +(cherry picked from commit 7fa5ac3fa2103ad4f8334373e786857ee6a3ba9f) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + arch/arm/mach-zynq/common.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/arch/arm/mach-zynq/common.c b/arch/arm/mach-zynq/common.c +index 4c0199b88a04..4130e65a0e3f 100644 +--- a/arch/arm/mach-zynq/common.c ++++ b/arch/arm/mach-zynq/common.c +@@ -97,7 +97,6 @@ static void zynq_system_reset(char mode, const char *cmd) + } + + static const char * const zynq_dt_match[] = { +- "xlnx,zynq-zc702", + "xlnx,zynq-7000", + NULL + }; +-- +1.8.5.rc3 + diff --git a/patches.zynq/0004-ARM-zynq-use-DT_MACHINE_START.patch b/patches.zynq/0004-ARM-zynq-use-DT_MACHINE_START.patch new file mode 100644 index 00000000000000..88311bb374e39d --- /dev/null +++ b/patches.zynq/0004-ARM-zynq-use-DT_MACHINE_START.patch @@ -0,0 +1,33 @@ +From cf5f4028141186f861bb0a32d50258d53f059b23 Mon Sep 17 00:00:00 2001 +From: Arnd Bergmann <arnd@arndb.de> +Date: Thu, 13 Jun 2013 14:13:37 +0200 +Subject: ARM: zynq: use DT_MACHINE_START + +The zynq platform code only supports DT based booting, so we +should use DT_MACHINE_START rather than MACHINE_START. + +Signed-off-by: Arnd Bergmann <arnd@arndb.de> +Cc: Michal Simek <michal.simek@xilinx.com> +(cherry picked from commit 514a590847ff42dc00ba6c6165736128ad7730a8) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + arch/arm/mach-zynq/common.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm/mach-zynq/common.c b/arch/arm/mach-zynq/common.c +index 4130e65a0e3f..5b799c29886e 100644 +--- a/arch/arm/mach-zynq/common.c ++++ b/arch/arm/mach-zynq/common.c +@@ -101,7 +101,7 @@ static const char * const zynq_dt_match[] = { + NULL + }; + +-MACHINE_START(XILINX_EP107, "Xilinx Zynq Platform") ++DT_MACHINE_START(XILINX_EP107, "Xilinx Zynq Platform") + .smp = smp_ops(zynq_smp_ops), + .map_io = zynq_map_io, + .init_machine = zynq_init_machine, +-- +1.8.5.rc3 + diff --git a/patches.zynq/0005-arm-zynq-slcr-Remove-redundant-header-includes.patch b/patches.zynq/0005-arm-zynq-slcr-Remove-redundant-header-includes.patch new file mode 100644 index 00000000000000..e81ae28452551c --- /dev/null +++ b/patches.zynq/0005-arm-zynq-slcr-Remove-redundant-header-includes.patch @@ -0,0 +1,40 @@ +From b6557492b29644237eda88551d2e09cb21769ae4 Mon Sep 17 00:00:00 2001 +From: Soren Brinkmann <soren.brinkmann@xilinx.com> +Date: Wed, 17 Jul 2013 10:10:13 -0700 +Subject: arm: zynq: slcr: Remove redundant header #includes + +Signed-off-by: Soren Brinkmann <soren.brinkmann@xilinx.com> +Signed-off-by: Michal Simek <michal.simek@xilinx.com> +(cherry picked from commit c323f2a188e333a6d8ee5ebb7cd2460020459f74) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + arch/arm/mach-zynq/slcr.c | 10 ---------- + 1 file changed, 10 deletions(-) + +diff --git a/arch/arm/mach-zynq/slcr.c b/arch/arm/mach-zynq/slcr.c +index c70969b9c258..ee1128998d6b 100644 +--- a/arch/arm/mach-zynq/slcr.c ++++ b/arch/arm/mach-zynq/slcr.c +@@ -14,18 +14,8 @@ + * 02139, USA. + */ + +-#include <linux/export.h> + #include <linux/io.h> +-#include <linux/fs.h> +-#include <linux/interrupt.h> +-#include <linux/init.h> +-#include <linux/kernel.h> +-#include <linux/module.h> + #include <linux/of_address.h> +-#include <linux/uaccess.h> +-#include <linux/platform_device.h> +-#include <linux/slab.h> +-#include <linux/string.h> + #include <linux/clk/zynq.h> + #include "common.h" + +-- +1.8.5.rc3 + diff --git a/patches.zynq/0006-arm-zynq-slcr-Clean-up-defines.patch b/patches.zynq/0006-arm-zynq-slcr-Clean-up-defines.patch new file mode 100644 index 00000000000000..d9f188c9cfd342 --- /dev/null +++ b/patches.zynq/0006-arm-zynq-slcr-Clean-up-defines.patch @@ -0,0 +1,100 @@ +From ff9feda6e107182a66031c7c4f269c8ab733bab1 Mon Sep 17 00:00:00 2001 +From: Soren Brinkmann <soren.brinkmann@xilinx.com> +Date: Wed, 17 Jul 2013 10:10:14 -0700 +Subject: arm: zynq: slcr: Clean up #defines + +Use a common naming scheme for register offset #defines: +Some of those used a '_OFFSET' suffix to distinguish them from others. +This scheme is used for all register offsets now. + +Separate the register offset #defines from others and sort them in +increasing order. + +Signed-off-by: Soren Brinkmann <soren.brinkmann@xilinx.com> +Signed-off-by: Michal Simek <michal.simek@xilinx.com> +(cherry picked from commit b5f177ff305b3db63b5ea273e6471708790133f2) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + arch/arm/mach-zynq/slcr.c | 25 ++++++++++++------------- + 1 file changed, 12 insertions(+), 13 deletions(-) + +diff --git a/arch/arm/mach-zynq/slcr.c b/arch/arm/mach-zynq/slcr.c +index ee1128998d6b..743b4825ebf5 100644 +--- a/arch/arm/mach-zynq/slcr.c ++++ b/arch/arm/mach-zynq/slcr.c +@@ -19,17 +19,16 @@ + #include <linux/clk/zynq.h> + #include "common.h" + +-#define SLCR_UNLOCK_MAGIC 0xDF0D +-#define SLCR_UNLOCK 0x8 /* SCLR unlock register */ +- ++/* register offsets */ ++#define SLCR_UNLOCK_OFFSET 0x8 /* SCLR unlock register */ + #define SLCR_PS_RST_CTRL_OFFSET 0x200 /* PS Software Reset Control */ ++#define SLCR_A9_CPU_RST_CTRL_OFFSET 0x244 /* CPU Software Reset Control */ ++#define SLCR_REBOOT_STATUS_OFFSET 0x258 /* PS Reboot Status */ + ++#define SLCR_UNLOCK_MAGIC 0xDF0D + #define SLCR_A9_CPU_CLKSTOP 0x10 + #define SLCR_A9_CPU_RST 0x1 + +-#define SLCR_A9_CPU_RST_CTRL 0x244 /* CPU Software Reset Control */ +-#define SLCR_REBOOT_STATUS 0x258 /* PS Reboot Status */ +- + void __iomem *zynq_slcr_base; + + /** +@@ -44,15 +43,15 @@ void zynq_slcr_system_reset(void) + * Note that this seems to require raw i/o + * functions or there's a lockup? + */ +- writel(SLCR_UNLOCK_MAGIC, zynq_slcr_base + SLCR_UNLOCK); ++ writel(SLCR_UNLOCK_MAGIC, zynq_slcr_base + SLCR_UNLOCK_OFFSET); + + /* + * Clear 0x0F000000 bits of reboot status register to workaround + * the FSBL not loading the bitstream after soft-reboot + * This is a temporary solution until we know more. + */ +- reboot = readl(zynq_slcr_base + SLCR_REBOOT_STATUS); +- writel(reboot & 0xF0FFFFFF, zynq_slcr_base + SLCR_REBOOT_STATUS); ++ reboot = readl(zynq_slcr_base + SLCR_REBOOT_STATUS_OFFSET); ++ writel(reboot & 0xF0FFFFFF, zynq_slcr_base + SLCR_REBOOT_STATUS_OFFSET); + writel(1, zynq_slcr_base + SLCR_PS_RST_CTRL_OFFSET); + } + +@@ -64,9 +63,9 @@ void zynq_slcr_cpu_start(int cpu) + { + /* enable CPUn */ + writel(SLCR_A9_CPU_CLKSTOP << cpu, +- zynq_slcr_base + SLCR_A9_CPU_RST_CTRL); ++ zynq_slcr_base + SLCR_A9_CPU_RST_CTRL_OFFSET); + /* enable CLK for CPUn */ +- writel(0x0 << cpu, zynq_slcr_base + SLCR_A9_CPU_RST_CTRL); ++ writel(0x0 << cpu, zynq_slcr_base + SLCR_A9_CPU_RST_CTRL_OFFSET); + } + + /** +@@ -77,7 +76,7 @@ void zynq_slcr_cpu_stop(int cpu) + { + /* stop CLK and reset CPUn */ + writel((SLCR_A9_CPU_CLKSTOP | SLCR_A9_CPU_RST) << cpu, +- zynq_slcr_base + SLCR_A9_CPU_RST_CTRL); ++ zynq_slcr_base + SLCR_A9_CPU_RST_CTRL_OFFSET); + } + + /** +@@ -103,7 +102,7 @@ int __init zynq_slcr_init(void) + } + + /* unlock the SLCR so that registers can be changed */ +- writel(SLCR_UNLOCK_MAGIC, zynq_slcr_base + SLCR_UNLOCK); ++ writel(SLCR_UNLOCK_MAGIC, zynq_slcr_base + SLCR_UNLOCK_OFFSET); + + pr_info("%s mapped to %p\n", np->name, zynq_slcr_base); + +-- +1.8.5.rc3 + diff --git a/patches.zynq/0007-arm-zynq-slcr-Use-read-modify-write-for-register-wri.patch b/patches.zynq/0007-arm-zynq-slcr-Use-read-modify-write-for-register-wri.patch new file mode 100644 index 00000000000000..8d35b61388c11f --- /dev/null +++ b/patches.zynq/0007-arm-zynq-slcr-Use-read-modify-write-for-register-wri.patch @@ -0,0 +1,55 @@ +From d1413800f639ccb4577bfcd207f197575b5c845b Mon Sep 17 00:00:00 2001 +From: Soren Brinkmann <soren.brinkmann@xilinx.com> +Date: Wed, 17 Jul 2013 10:10:15 -0700 +Subject: arm: zynq: slcr: Use read-modify-write for register writes + +zynq_slcr_cpu_start/stop() ignored the current register state when +writing to a register. Fixing this by implementing proper +read-modify-write. + +Signed-off-by: Soren Brinkmann <soren.brinkmann@xilinx.com> +Signed-off-by: Michal Simek <michal.simek@xilinx.com> +(cherry picked from commit 3db9e86029349c2c84928b5a0f7c7cf324243b4f) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + arch/arm/mach-zynq/slcr.c | 16 ++++++++-------- + 1 file changed, 8 insertions(+), 8 deletions(-) + +diff --git a/arch/arm/mach-zynq/slcr.c b/arch/arm/mach-zynq/slcr.c +index 743b4825ebf5..884dace227d5 100644 +--- a/arch/arm/mach-zynq/slcr.c ++++ b/arch/arm/mach-zynq/slcr.c +@@ -61,11 +61,11 @@ void zynq_slcr_system_reset(void) + */ + void zynq_slcr_cpu_start(int cpu) + { +- /* enable CPUn */ +- writel(SLCR_A9_CPU_CLKSTOP << cpu, +- zynq_slcr_base + SLCR_A9_CPU_RST_CTRL_OFFSET); +- /* enable CLK for CPUn */ +- writel(0x0 << cpu, zynq_slcr_base + SLCR_A9_CPU_RST_CTRL_OFFSET); ++ u32 reg = readl(zynq_slcr_base + SLCR_A9_CPU_RST_CTRL_OFFSET); ++ reg &= ~(SLCR_A9_CPU_RST << cpu); ++ writel(reg, zynq_slcr_base + SLCR_A9_CPU_RST_CTRL_OFFSET); ++ reg &= ~(SLCR_A9_CPU_CLKSTOP << cpu); ++ writel(reg, zynq_slcr_base + SLCR_A9_CPU_RST_CTRL_OFFSET); + } + + /** +@@ -74,9 +74,9 @@ void zynq_slcr_cpu_start(int cpu) + */ + void zynq_slcr_cpu_stop(int cpu) + { +- /* stop CLK and reset CPUn */ +- writel((SLCR_A9_CPU_CLKSTOP | SLCR_A9_CPU_RST) << cpu, +- zynq_slcr_base + SLCR_A9_CPU_RST_CTRL_OFFSET); ++ u32 reg = readl(zynq_slcr_base + SLCR_A9_CPU_RST_CTRL_OFFSET); ++ reg |= (SLCR_A9_CPU_CLKSTOP | SLCR_A9_CPU_RST) << cpu; ++ writel(reg, zynq_slcr_base + SLCR_A9_CPU_RST_CTRL_OFFSET); + } + + /** +-- +1.8.5.rc3 + diff --git a/patches.zynq/0008-arm-zynq-hotplug-Remove-unreachable-code.patch b/patches.zynq/0008-arm-zynq-hotplug-Remove-unreachable-code.patch new file mode 100644 index 00000000000000..c3f5cd5cff07d2 --- /dev/null +++ b/patches.zynq/0008-arm-zynq-hotplug-Remove-unreachable-code.patch @@ -0,0 +1,96 @@ +From ffe4cca718489eddaa6a98f2587388b7e6539a35 Mon Sep 17 00:00:00 2001 +From: Soren Brinkmann <soren.brinkmann@xilinx.com> +Date: Thu, 1 Aug 2013 09:36:53 -0700 +Subject: arm: zynq: hotplug: Remove unreachable code + +zynq_platform_do_lowpower() does never return. Hence remove +all code which relies on that function returning and consolidate the +remains. + +Signed-off-by: Soren Brinkmann <soren.brinkmann@xilinx.com> +Signed-off-by: Michal Simek <michal.simek@xilinx.com> +(cherry picked from commit b522877b53cf3f26d7f072616a45e10fe579cd19) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + arch/arm/mach-zynq/hotplug.c | 55 ++++---------------------------------------- + 1 file changed, 5 insertions(+), 50 deletions(-) + +diff --git a/arch/arm/mach-zynq/hotplug.c b/arch/arm/mach-zynq/hotplug.c +index c89672bd1de2..5052c70326e4 100644 +--- a/arch/arm/mach-zynq/hotplug.c ++++ b/arch/arm/mach-zynq/hotplug.c +@@ -40,44 +40,6 @@ static inline void zynq_cpu_enter_lowpower(void) + : "cc"); + } + +-static inline void zynq_cpu_leave_lowpower(void) +-{ +- unsigned int v; +- +- asm volatile( +- " mrc p15, 0, %0, c1, c0, 0\n" +- " orr %0, %0, %1\n" +- " mcr p15, 0, %0, c1, c0, 0\n" +- " mrc p15, 0, %0, c1, c0, 1\n" +- " orr %0, %0, #0x40\n" +- " mcr p15, 0, %0, c1, c0, 1\n" +- : "=&r" (v) +- : "Ir" (CR_C) +- : "cc"); +-} +- +-static inline void zynq_platform_do_lowpower(unsigned int cpu, int *spurious) +-{ +- /* +- * there is no power-control hardware on this platform, so all +- * we can do is put the core into WFI; this is safe as the calling +- * code will have already disabled interrupts +- */ +- for (;;) { +- dsb(); +- wfi(); +- +- /* +- * Getting here, means that we have come out of WFI without +- * having been woken up - this shouldn't happen +- * +- * Just note it happening - when we're woken, we can report +- * its occurrence. +- */ +- (*spurious)++; +- } +-} +- + /* + * platform-specific code to shutdown a CPU + * +@@ -85,20 +47,13 @@ static inline void zynq_platform_do_lowpower(unsigned int cpu, int *spurious) + */ + void zynq_platform_cpu_die(unsigned int cpu) + { +- int spurious = 0; +- +- /* +- * we're ready for shutdown now, so do it +- */ + zynq_cpu_enter_lowpower(); +- zynq_platform_do_lowpower(cpu, &spurious); + + /* +- * bring this CPU back into the world of cache +- * coherency, and then restore interrupts ++ * there is no power-control hardware on this platform, so all ++ * we can do is put the core into WFI; this is safe as the calling ++ * code will have already disabled interrupts + */ +- zynq_cpu_leave_lowpower(); +- +- if (spurious) +- pr_warn("CPU%u: %u spurious wakeup calls\n", cpu, spurious); ++ for (;;) ++ cpu_do_idle(); + } +-- +1.8.5.rc3 + diff --git a/patches.zynq/0009-arm-zynq-Enable-arm_global_timer.patch b/patches.zynq/0009-arm-zynq-Enable-arm_global_timer.patch new file mode 100644 index 00000000000000..54cb4b69123251 --- /dev/null +++ b/patches.zynq/0009-arm-zynq-Enable-arm_global_timer.patch @@ -0,0 +1,53 @@ +From 226d0e6cf38882473183f833e8e78f84fc0c5cc5 Mon Sep 17 00:00:00 2001 +From: Soren Brinkmann <soren.brinkmann@xilinx.com> +Date: Wed, 18 Sep 2013 11:48:38 -0700 +Subject: arm: zynq: Enable arm_global_timer + +Zynq is based on an ARM Cortex-A9 MPCore, which features the +arm_global_timer in its SCU. Therefore enable the timer for Zynq. + +Signed-off-by: Soren Brinkmann <soren.brinkmann@xilinx.com> +Acked-by: Daniel Lezcano <daniel.lezcano@linaro.org> +Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org> +Acked-by: Michal Simek <michal.simek@xilinx.com> +(cherry picked from commit fa94bd57b5a5b2206e5fdd0ed2dbacff199121f2) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + arch/arm/boot/dts/zynq-7000.dtsi | 8 ++++++++ + arch/arm/mach-zynq/Kconfig | 1 + + 2 files changed, 9 insertions(+) + +diff --git a/arch/arm/boot/dts/zynq-7000.dtsi b/arch/arm/boot/dts/zynq-7000.dtsi +index 14fb2e609bab..4265b0fd1e20 100644 +--- a/arch/arm/boot/dts/zynq-7000.dtsi ++++ b/arch/arm/boot/dts/zynq-7000.dtsi +@@ -117,6 +117,14 @@ + }; + }; + ++ global_timer: timer@f8f00200 { ++ compatible = "arm,cortex-a9-global-timer"; ++ reg = <0xf8f00200 0x20>; ++ interrupts = <1 11 0x301>; ++ interrupt-parent = <&intc>; ++ clocks = <&clkc 4>; ++ }; ++ + ttc0: ttc0@f8001000 { + interrupt-parent = <&intc>; + interrupts = < 0 10 4 0 11 4 0 12 4 >; +diff --git a/arch/arm/mach-zynq/Kconfig b/arch/arm/mach-zynq/Kconfig +index c1d61f281e68..854575c18000 100644 +--- a/arch/arm/mach-zynq/Kconfig ++++ b/arch/arm/mach-zynq/Kconfig +@@ -13,5 +13,6 @@ config ARCH_ZYNQ + select HAVE_SMP + select SPARSE_IRQ + select CADENCE_TTC_TIMER ++ select ARM_GLOBAL_TIMER + help + Support for Xilinx Zynq ARM Cortex A9 Platform +-- +1.8.5.rc3 + diff --git a/patches.zynq/0010-ARM-zynq-Add-cpuidle-support.patch b/patches.zynq/0010-ARM-zynq-Add-cpuidle-support.patch new file mode 100644 index 00000000000000..d099591d9c31ca --- /dev/null +++ b/patches.zynq/0010-ARM-zynq-Add-cpuidle-support.patch @@ -0,0 +1,149 @@ +From 162cdee2033c61c65064d72592d471b96611f212 Mon Sep 17 00:00:00 2001 +From: Michal Simek <michal.simek@xilinx.com> +Date: Tue, 4 Jun 2013 07:17:39 +0000 +Subject: ARM: zynq: Add cpuidle support + +Add cpuidle support for Xilinx Zynq. + +Signed-off-by: Michal Simek <michal.simek@xilinx.com> +Acked-by: Daniel Lezcano <daniel.lezcano@linaro.org> +Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> +(cherry picked from commit bd2a337a25dd22bcd6b3fb1f99461f6991773e68) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + MAINTAINERS | 1 + + drivers/cpuidle/Kconfig | 6 +++ + drivers/cpuidle/Makefile | 1 + + drivers/cpuidle/cpuidle-zynq.c | 83 ++++++++++++++++++++++++++++++++++++++++++ + 4 files changed, 91 insertions(+) + create mode 100644 drivers/cpuidle/cpuidle-zynq.c + +diff --git a/MAINTAINERS b/MAINTAINERS +index 48c748080c96..30f6d87daadd 100644 +--- a/MAINTAINERS ++++ b/MAINTAINERS +@@ -1309,6 +1309,7 @@ W: http://wiki.xilinx.com + T: git git://git.xilinx.com/linux-xlnx.git + S: Supported + F: arch/arm/mach-zynq/ ++F: drivers/cpuidle/cpuidle-zynq.c + + ARM64 PORT (AARCH64 ARCHITECTURE) + M: Catalin Marinas <catalin.marinas@arm.com> +diff --git a/drivers/cpuidle/Kconfig b/drivers/cpuidle/Kconfig +index c4cc27e5c8a5..8272a08b137b 100644 +--- a/drivers/cpuidle/Kconfig ++++ b/drivers/cpuidle/Kconfig +@@ -39,4 +39,10 @@ config CPU_IDLE_CALXEDA + help + Select this to enable cpuidle on Calxeda processors. + ++config CPU_IDLE_ZYNQ ++ bool "CPU Idle Driver for Xilinx Zynq processors" ++ depends on ARCH_ZYNQ ++ help ++ Select this to enable cpuidle on Xilinx Zynq processors. ++ + endif +diff --git a/drivers/cpuidle/Makefile b/drivers/cpuidle/Makefile +index 0d8bd55e776f..8767a7b3eb91 100644 +--- a/drivers/cpuidle/Makefile ++++ b/drivers/cpuidle/Makefile +@@ -7,3 +7,4 @@ obj-$(CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED) += coupled.o + + obj-$(CONFIG_CPU_IDLE_CALXEDA) += cpuidle-calxeda.o + obj-$(CONFIG_ARCH_KIRKWOOD) += cpuidle-kirkwood.o ++obj-$(CONFIG_CPU_IDLE_ZYNQ) += cpuidle-zynq.o +diff --git a/drivers/cpuidle/cpuidle-zynq.c b/drivers/cpuidle/cpuidle-zynq.c +new file mode 100644 +index 000000000000..38e03a183591 +--- /dev/null ++++ b/drivers/cpuidle/cpuidle-zynq.c +@@ -0,0 +1,83 @@ ++/* ++ * Copyright (C) 2012-2013 Xilinx ++ * ++ * CPU idle support for Xilinx Zynq ++ * ++ * based on arch/arm/mach-at91/cpuidle.c ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms and conditions of the GNU General Public License, ++ * version 2, as published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>. ++ * ++ * The cpu idle uses wait-for-interrupt and RAM self refresh in order ++ * to implement two idle states - ++ * #1 wait-for-interrupt ++ * #2 wait-for-interrupt and RAM self refresh ++ * ++ * Maintainer: Michal Simek <michal.simek@xilinx.com> ++ */ ++ ++#include <linux/init.h> ++#include <linux/cpu_pm.h> ++#include <linux/cpuidle.h> ++#include <linux/of.h> ++#include <asm/proc-fns.h> ++#include <asm/cpuidle.h> ++ ++#define ZYNQ_MAX_STATES 2 ++ ++/* Actual code that puts the SoC in different idle states */ ++static int zynq_enter_idle(struct cpuidle_device *dev, ++ struct cpuidle_driver *drv, int index) ++{ ++ /* Devices must be stopped here */ ++ cpu_pm_enter(); ++ ++ /* Add code for DDR self refresh start */ ++ cpu_do_idle(); ++ ++ /* Add code for DDR self refresh stop */ ++ cpu_pm_exit(); ++ ++ return index; ++} ++ ++static struct cpuidle_driver zynq_idle_driver = { ++ .name = "zynq_idle", ++ .owner = THIS_MODULE, ++ .states = { ++ ARM_CPUIDLE_WFI_STATE, ++ { ++ .enter = zynq_enter_idle, ++ .exit_latency = 10, ++ .target_residency = 10000, ++ .flags = CPUIDLE_FLAG_TIME_VALID | ++ CPUIDLE_FLAG_TIMER_STOP, ++ .name = "RAM_SR", ++ .desc = "WFI and RAM Self Refresh", ++ }, ++ }, ++ .safe_state_index = 0, ++ .state_count = ZYNQ_MAX_STATES, ++}; ++ ++/* Initialize CPU idle by registering the idle states */ ++static int __init zynq_cpuidle_init(void) ++{ ++ if (!of_machine_is_compatible("xlnx,zynq-7000")) ++ return -ENODEV; ++ ++ pr_info("Xilinx Zynq CpuIdle Driver started\n"); ++ ++ return cpuidle_register(&zynq_idle_driver, NULL); ++} ++ ++device_initcall(zynq_cpuidle_init); +-- +1.8.5.rc3 + diff --git a/patches.zynq/0011-ARM-zynq-cpuidle-Remove-useless-compatibility-string.patch b/patches.zynq/0011-ARM-zynq-cpuidle-Remove-useless-compatibility-string.patch new file mode 100644 index 00000000000000..dc537f9be0f14a --- /dev/null +++ b/patches.zynq/0011-ARM-zynq-cpuidle-Remove-useless-compatibility-string.patch @@ -0,0 +1,42 @@ +From fb90b2d616862222143739e23ddb11f37eb1b208 Mon Sep 17 00:00:00 2001 +From: Daniel Lezcano <daniel.lezcano@linaro.org> +Date: Fri, 27 Sep 2013 09:46:09 +0200 +Subject: ARM: zynq: cpuidle: Remove useless compatibility string + +All zynq platforms have this compatibility string and there is no any other +clone. + +Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org> +Acked-by: Michal Simek <michal.simek@xilinx.com> +(cherry picked from commit 4aa88fbe6d6f78a8a464445eb6b55a360e3d3733) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + drivers/cpuidle/cpuidle-zynq.c | 4 ---- + 1 file changed, 4 deletions(-) + +diff --git a/drivers/cpuidle/cpuidle-zynq.c b/drivers/cpuidle/cpuidle-zynq.c +index 38e03a183591..ab6c4b4ffc7b 100644 +--- a/drivers/cpuidle/cpuidle-zynq.c ++++ b/drivers/cpuidle/cpuidle-zynq.c +@@ -28,7 +28,6 @@ + #include <linux/init.h> + #include <linux/cpu_pm.h> + #include <linux/cpuidle.h> +-#include <linux/of.h> + #include <asm/proc-fns.h> + #include <asm/cpuidle.h> + +@@ -72,9 +71,6 @@ static struct cpuidle_driver zynq_idle_driver = { + /* Initialize CPU idle by registering the idle states */ + static int __init zynq_cpuidle_init(void) + { +- if (!of_machine_is_compatible("xlnx,zynq-7000")) +- return -ENODEV; +- + pr_info("Xilinx Zynq CpuIdle Driver started\n"); + + return cpuidle_register(&zynq_idle_driver, NULL); +-- +1.8.5.rc3 + diff --git a/patches.zynq/0012-ARM-zynq-cpuidle-convert-to-platform-driver.patch b/patches.zynq/0012-ARM-zynq-cpuidle-convert-to-platform-driver.patch new file mode 100644 index 00000000000000..0a6475041ba0ab --- /dev/null +++ b/patches.zynq/0012-ARM-zynq-cpuidle-convert-to-platform-driver.patch @@ -0,0 +1,79 @@ +From e57006f7a0506afce94f5047f80a213312843097 Mon Sep 17 00:00:00 2001 +From: Daniel Lezcano <daniel.lezcano@linaro.org> +Date: Sat, 21 Sep 2013 18:41:02 +0200 +Subject: ARM: zynq: cpuidle: convert to platform driver + +As the ux500 and the kirkwood driver, make the zynq driver a platform driver + +Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org> +Acked-by: Michal Simek <michal.simek@xilinx.com> +Tested-by: Soren Brinkmann <soren.brinkmann@xilinx.com> +(cherry picked from commit 3e8ceca6c76ec2d5ee47ece0420cf10d041cf58f) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + arch/arm/mach-zynq/common.c | 6 ++++++ + drivers/cpuidle/cpuidle-zynq.c | 13 +++++++++++-- + 2 files changed, 17 insertions(+), 2 deletions(-) + +diff --git a/arch/arm/mach-zynq/common.c b/arch/arm/mach-zynq/common.c +index 5b799c29886e..94a248b3b89b 100644 +--- a/arch/arm/mach-zynq/common.c ++++ b/arch/arm/mach-zynq/common.c +@@ -44,6 +44,10 @@ static struct of_device_id zynq_of_bus_ids[] __initdata = { + {} + }; + ++static struct platform_device zynq_cpuidle_device = { ++ .name = "cpuidle-zynq", ++}; ++ + /** + * zynq_init_machine - System specific initialization, intended to be + * called from board specific initialization. +@@ -56,6 +60,8 @@ static void __init zynq_init_machine(void) + l2x0_of_init(0x02060000, 0xF0F0FFFF); + + of_platform_bus_probe(NULL, zynq_of_bus_ids, NULL); ++ ++ platform_device_register(&zynq_cpuidle_device); + } + + static void __init zynq_timer_init(void) +diff --git a/drivers/cpuidle/cpuidle-zynq.c b/drivers/cpuidle/cpuidle-zynq.c +index ab6c4b4ffc7b..aded75928028 100644 +--- a/drivers/cpuidle/cpuidle-zynq.c ++++ b/drivers/cpuidle/cpuidle-zynq.c +@@ -28,6 +28,7 @@ + #include <linux/init.h> + #include <linux/cpu_pm.h> + #include <linux/cpuidle.h> ++#include <linux/platform_device.h> + #include <asm/proc-fns.h> + #include <asm/cpuidle.h> + +@@ -69,11 +70,19 @@ static struct cpuidle_driver zynq_idle_driver = { + }; + + /* Initialize CPU idle by registering the idle states */ +-static int __init zynq_cpuidle_init(void) ++static int zynq_cpuidle_probe(struct platform_device *pdev) + { + pr_info("Xilinx Zynq CpuIdle Driver started\n"); + + return cpuidle_register(&zynq_idle_driver, NULL); + } + +-device_initcall(zynq_cpuidle_init); ++static struct platform_driver zynq_cpuidle_driver = { ++ .driver = { ++ .name = "cpuidle-zynq", ++ .owner = THIS_MODULE, ++ }, ++ .probe = zynq_cpuidle_probe, ++}; ++ ++module_platform_driver(zynq_cpuidle_driver); +-- +1.8.5.rc3 + diff --git a/patches.zynq/0013-tty-xuartps-Remove-suspend-resume-functions.patch b/patches.zynq/0013-tty-xuartps-Remove-suspend-resume-functions.patch new file mode 100644 index 00000000000000..4d78520adf59ce --- /dev/null +++ b/patches.zynq/0013-tty-xuartps-Remove-suspend-resume-functions.patch @@ -0,0 +1,70 @@ +From 664379fd28a8af165267f4d322a1bf250c8228c2 Mon Sep 17 00:00:00 2001 +From: Soren Brinkmann <soren.brinkmann@xilinx.com> +Date: Mon, 13 May 2013 10:46:35 -0700 +Subject: tty: xuartps: Remove suspend/resume functions + +Currently Zynq does not support suspend/resume. +The driver callbacks are never used or tested, broken and using the old +PM interface. + +Signed-off-by: Soren Brinkmann <soren.brinkmann@xilinx.com> +Cc: Jiri Slaby <jslaby@suse.cz> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +(cherry picked from commit e424259e2e27290c457f65161ae62f7c89215b88) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + drivers/tty/serial/xilinx_uartps.c | 30 ------------------------------ + 1 file changed, 30 deletions(-) + +diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c +index 4e5c77834c50..b5f655d10098 100644 +--- a/drivers/tty/serial/xilinx_uartps.c ++++ b/drivers/tty/serial/xilinx_uartps.c +@@ -1006,34 +1006,6 @@ static int xuartps_remove(struct platform_device *pdev) + return rc; + } + +-/** +- * xuartps_suspend - suspend event +- * @pdev: Pointer to the platform device structure +- * @state: State of the device +- * +- * Returns 0 +- **/ +-static int xuartps_suspend(struct platform_device *pdev, pm_message_t state) +-{ +- /* Call the API provided in serial_core.c file which handles +- * the suspend. +- */ +- uart_suspend_port(&xuartps_uart_driver, &xuartps_port[pdev->id]); +- return 0; +-} +- +-/** +- * xuartps_resume - Resume after a previous suspend +- * @pdev: Pointer to the platform device structure +- * +- * Returns 0 +- **/ +-static int xuartps_resume(struct platform_device *pdev) +-{ +- uart_resume_port(&xuartps_uart_driver, &xuartps_port[pdev->id]); +- return 0; +-} +- + /* Match table for of_platform binding */ + static struct of_device_id xuartps_of_match[] = { + { .compatible = "xlnx,xuartps", }, +@@ -1044,8 +1016,6 @@ MODULE_DEVICE_TABLE(of, xuartps_of_match); + static struct platform_driver xuartps_platform_driver = { + .probe = xuartps_probe, /* Probe method */ + .remove = xuartps_remove, /* Detach method */ +- .suspend = xuartps_suspend, /* Suspend */ +- .resume = xuartps_resume, /* Resume after a suspend */ + .driver = { + .owner = THIS_MODULE, + .name = XUARTPS_NAME, /* Driver name */ +-- +1.8.5.rc3 + diff --git a/patches.zynq/0014-arm-zynq-Migrate-platform-to-clock-controller.patch b/patches.zynq/0014-arm-zynq-Migrate-platform-to-clock-controller.patch new file mode 100644 index 00000000000000..5787407505a03d --- /dev/null +++ b/patches.zynq/0014-arm-zynq-Migrate-platform-to-clock-controller.patch @@ -0,0 +1,432 @@ +From 036eae88dd3e2eee9c2227661f0a21060529ecef Mon Sep 17 00:00:00 2001 +From: Soren Brinkmann <soren.brinkmann@xilinx.com> +Date: Mon, 13 May 2013 10:46:38 -0700 +Subject: arm: zynq: Migrate platform to clock controller + +Migrate the Zynq platform and its drivers to use the new clock +controller driver. + +Signed-off-by: Soren Brinkmann <soren.brinkmann@xilinx.com> +Cc: John Stultz <john.stultz@linaro.org> +Cc: Thomas Gleixner <tglx@linutronix.de> +Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Cc: Jiri Slaby <jslaby@suse.cz> +Cc: linux-serial@vger.kernel.org +Signed-off-by: Michal Simek <michal.simek@xilinx.com> +Acked-by: Mike Turquette <mturquette@linaro.org> +(cherry picked from commit 30e1e28598c2674c133148d8aec6d431d7acd314) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + arch/arm/boot/dts/zynq-7000.dtsi | 71 ++++++++------------------- + arch/arm/boot/dts/zynq-zc702.dts | 4 -- + arch/arm/mach-zynq/slcr.c | 2 +- + drivers/clk/Makefile | 2 +- + drivers/clk/zynq/Makefile | 3 ++ + drivers/clocksource/cadence_ttc_timer.c | 23 +++++++-- + drivers/tty/serial/xilinx_uartps.c | 85 ++++++++++++++++++++++++++------- + include/linux/clk/zynq.h | 8 +++- + 8 files changed, 118 insertions(+), 80 deletions(-) + create mode 100644 drivers/clk/zynq/Makefile + +diff --git a/arch/arm/boot/dts/zynq-7000.dtsi b/arch/arm/boot/dts/zynq-7000.dtsi +index 4265b0fd1e20..952b61d39b0a 100644 +--- a/arch/arm/boot/dts/zynq-7000.dtsi ++++ b/arch/arm/boot/dts/zynq-7000.dtsi +@@ -49,16 +49,18 @@ + + uart0: uart@e0000000 { + compatible = "xlnx,xuartps"; ++ clocks = <&clkc 23>, <&clkc 40>; ++ clock-names = "ref_clk", "aper_clk"; + reg = <0xE0000000 0x1000>; + interrupts = <0 27 4>; +- clocks = <&uart_clk 0>; + }; + + uart1: uart@e0001000 { + compatible = "xlnx,xuartps"; ++ clocks = <&clkc 24>, <&clkc 41>; ++ clock-names = "ref_clk", "aper_clk"; + reg = <0xE0001000 0x1000>; + interrupts = <0 50 4>; +- clocks = <&uart_clk 1>; + }; + + slcr: slcr@f8000000 { +@@ -69,50 +71,21 @@ + #address-cells = <1>; + #size-cells = <0>; + +- ps_clk: ps_clk { +- #clock-cells = <0>; +- compatible = "fixed-clock"; +- /* clock-frequency set in board-specific file */ +- clock-output-names = "ps_clk"; +- }; +- armpll: armpll { +- #clock-cells = <0>; +- compatible = "xlnx,zynq-pll"; +- clocks = <&ps_clk>; +- reg = <0x100 0x110>; +- clock-output-names = "armpll"; +- }; +- ddrpll: ddrpll { +- #clock-cells = <0>; +- compatible = "xlnx,zynq-pll"; +- clocks = <&ps_clk>; +- reg = <0x104 0x114>; +- clock-output-names = "ddrpll"; +- }; +- iopll: iopll { +- #clock-cells = <0>; +- compatible = "xlnx,zynq-pll"; +- clocks = <&ps_clk>; +- reg = <0x108 0x118>; +- clock-output-names = "iopll"; +- }; +- uart_clk: uart_clk { ++ clkc: clkc { + #clock-cells = <1>; +- compatible = "xlnx,zynq-periph-clock"; +- clocks = <&iopll &armpll &ddrpll>; +- reg = <0x154>; +- clock-output-names = "uart0_ref_clk", +- "uart1_ref_clk"; +- }; +- cpu_clk: cpu_clk { +- #clock-cells = <1>; +- compatible = "xlnx,zynq-cpu-clock"; +- clocks = <&iopll &armpll &ddrpll>; +- reg = <0x120 0x1C4>; +- clock-output-names = "cpu_6x4x", +- "cpu_3x2x", +- "cpu_2x", +- "cpu_1x"; ++ compatible = "xlnx,ps7-clkc"; ++ ps-clk-frequency = <33333333>; ++ clock-output-names = "armpll", "ddrpll", "iopll", "cpu_6or4x", ++ "cpu_3or2x", "cpu_2x", "cpu_1x", "ddr2x", "ddr3x", ++ "dci", "lqspi", "smc", "pcap", "gem0", "gem1", ++ "fclk0", "fclk1", "fclk2", "fclk3", "can0", "can1", ++ "sdio0", "sdio1", "uart0", "uart1", "spi0", "spi1", ++ "dma", "usb0_aper", "usb1_aper", "gem0_aper", ++ "gem1_aper", "sdio0_aper", "sdio1_aper", ++ "spi0_aper", "spi1_aper", "can0_aper", "can1_aper", ++ "i2c0_aper", "i2c1_aper", "uart0_aper", "uart1_aper", ++ "gpio_aper", "lqspi_aper", "smc_aper", "swdt", ++ "dbg_trc", "dbg_apb"; + }; + }; + }; +@@ -129,9 +102,8 @@ + interrupt-parent = <&intc>; + interrupts = < 0 10 4 0 11 4 0 12 4 >; + compatible = "cdns,ttc"; ++ clocks = <&clkc 6>; + reg = <0xF8001000 0x1000>; +- clocks = <&cpu_clk 3>; +- clock-names = "cpu_1x"; + clock-ranges; + }; + +@@ -139,9 +111,8 @@ + interrupt-parent = <&intc>; + interrupts = < 0 37 4 0 38 4 0 39 4 >; + compatible = "cdns,ttc"; ++ clocks = <&clkc 6>; + reg = <0xF8002000 0x1000>; +- clocks = <&cpu_clk 3>; +- clock-names = "cpu_1x"; + clock-ranges; + }; + scutimer: scutimer@f8f00600 { +@@ -149,7 +120,7 @@ + interrupts = < 1 13 0x301 >; + compatible = "arm,cortex-a9-twd-timer"; + reg = < 0xf8f00600 0x20 >; +- clocks = <&cpu_clk 1>; ++ clocks = <&clkc 4>; + } ; + }; + }; +diff --git a/arch/arm/boot/dts/zynq-zc702.dts b/arch/arm/boot/dts/zynq-zc702.dts +index 86f44d5b0265..e25a307438ad 100644 +--- a/arch/arm/boot/dts/zynq-zc702.dts ++++ b/arch/arm/boot/dts/zynq-zc702.dts +@@ -28,7 +28,3 @@ + }; + + }; +- +-&ps_clk { +- clock-frequency = <33333330>; +-}; +diff --git a/arch/arm/mach-zynq/slcr.c b/arch/arm/mach-zynq/slcr.c +index 884dace227d5..1836d5a34606 100644 +--- a/arch/arm/mach-zynq/slcr.c ++++ b/arch/arm/mach-zynq/slcr.c +@@ -106,7 +106,7 @@ int __init zynq_slcr_init(void) + + pr_info("%s mapped to %p\n", np->name, zynq_slcr_base); + +- xilinx_zynq_clocks_init(zynq_slcr_base); ++ zynq_clock_init(zynq_slcr_base); + + of_node_put(np); + +diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile +index 137d3e730f86..fa435bcf9f1a 100644 +--- a/drivers/clk/Makefile ++++ b/drivers/clk/Makefile +@@ -27,7 +27,7 @@ obj-$(CONFIG_MACH_LOONGSON1) += clk-ls1x.o + obj-$(CONFIG_ARCH_SUNXI) += sunxi/ + obj-$(CONFIG_ARCH_U8500) += ux500/ + obj-$(CONFIG_ARCH_VT8500) += clk-vt8500.o +-obj-$(CONFIG_ARCH_ZYNQ) += clk-zynq.o ++obj-$(CONFIG_ARCH_ZYNQ) += zynq/ + obj-$(CONFIG_ARCH_TEGRA) += tegra/ + obj-$(CONFIG_PLAT_SAMSUNG) += samsung/ + +diff --git a/drivers/clk/zynq/Makefile b/drivers/clk/zynq/Makefile +new file mode 100644 +index 000000000000..156d923f4fa9 +--- /dev/null ++++ b/drivers/clk/zynq/Makefile +@@ -0,0 +1,3 @@ ++# Zynq clock specific Makefile ++ ++obj-$(CONFIG_ARCH_ZYNQ) += clkc.o pll.o +diff --git a/drivers/clocksource/cadence_ttc_timer.c b/drivers/clocksource/cadence_ttc_timer.c +index 685bc60e210a..4cbe28c74631 100644 +--- a/drivers/clocksource/cadence_ttc_timer.c ++++ b/drivers/clocksource/cadence_ttc_timer.c +@@ -51,6 +51,8 @@ + + #define TTC_CNT_CNTRL_DISABLE_MASK 0x1 + ++#define TTC_CLK_CNTRL_CSRC_MASK (1 << 5) /* clock source */ ++ + /* + * Setup the timers to use pre-scaling, using a fixed value for now that will + * work across most input frequency, but it may need to be more dynamic +@@ -396,8 +398,9 @@ static void __init ttc_timer_init(struct device_node *timer) + { + unsigned int irq; + void __iomem *timer_baseaddr; +- struct clk *clk; ++ struct clk *clk_cs, *clk_ce; + static int initialized; ++ int clksel; + + if (initialized) + return; +@@ -421,14 +424,24 @@ static void __init ttc_timer_init(struct device_node *timer) + BUG(); + } + +- clk = of_clk_get_by_name(timer, "cpu_1x"); +- if (IS_ERR(clk)) { ++ clksel = __raw_readl(timer_baseaddr + TTC_CLK_CNTRL_OFFSET); ++ clksel = !!(clksel & TTC_CLK_CNTRL_CSRC_MASK); ++ clk_cs = of_clk_get(timer, clksel); ++ if (IS_ERR(clk_cs)) { ++ pr_err("ERROR: timer input clock not found\n"); ++ BUG(); ++ } ++ ++ clksel = __raw_readl(timer_baseaddr + 4 + TTC_CLK_CNTRL_OFFSET); ++ clksel = !!(clksel & TTC_CLK_CNTRL_CSRC_MASK); ++ clk_ce = of_clk_get(timer, clksel); ++ if (IS_ERR(clk_ce)) { + pr_err("ERROR: timer input clock not found\n"); + BUG(); + } + +- ttc_setup_clocksource(clk, timer_baseaddr); +- ttc_setup_clockevent(clk, timer_baseaddr + 4, irq); ++ ttc_setup_clocksource(clk_cs, timer_baseaddr); ++ ttc_setup_clockevent(clk_ce, timer_baseaddr + 4, irq); + + pr_info("%s #0 at %p, irq=%d\n", timer->name, timer_baseaddr, irq); + } +diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c +index b5f655d10098..916305a573b8 100644 +--- a/drivers/tty/serial/xilinx_uartps.c ++++ b/drivers/tty/serial/xilinx_uartps.c +@@ -14,6 +14,7 @@ + #include <linux/platform_device.h> + #include <linux/serial.h> + #include <linux/serial_core.h> ++#include <linux/slab.h> + #include <linux/tty.h> + #include <linux/tty_flip.h> + #include <linux/console.h> +@@ -139,6 +140,16 @@ + #define XUARTPS_SR_RXTRIG 0x00000001 /* Rx Trigger */ + + /** ++ * struct xuartps - device data ++ * @refclk Reference clock ++ * @aperclk APB clock ++ */ ++struct xuartps { ++ struct clk *refclk; ++ struct clk *aperclk; ++}; ++ ++/** + * xuartps_isr - Interrupt handler + * @irq: Irq number + * @dev_id: Id of the port +@@ -936,34 +947,55 @@ static int xuartps_probe(struct platform_device *pdev) + int rc; + struct uart_port *port; + struct resource *res, *res2; +- struct clk *clk; ++ struct xuartps *xuartps_data; + +- clk = of_clk_get(pdev->dev.of_node, 0); +- if (IS_ERR(clk)) { +- dev_err(&pdev->dev, "no clock specified\n"); +- return PTR_ERR(clk); ++ xuartps_data = kzalloc(sizeof(*xuartps_data), GFP_KERNEL); ++ if (!xuartps_data) ++ return -ENOMEM; ++ ++ xuartps_data->aperclk = clk_get(&pdev->dev, "aper_clk"); ++ if (IS_ERR(xuartps_data->aperclk)) { ++ dev_err(&pdev->dev, "aper_clk clock not found.\n"); ++ rc = PTR_ERR(xuartps_data->aperclk); ++ goto err_out_free; ++ } ++ xuartps_data->refclk = clk_get(&pdev->dev, "ref_clk"); ++ if (IS_ERR(xuartps_data->refclk)) { ++ dev_err(&pdev->dev, "ref_clk clock not found.\n"); ++ rc = PTR_ERR(xuartps_data->refclk); ++ goto err_out_clk_put_aper; + } + +- rc = clk_prepare_enable(clk); ++ rc = clk_prepare_enable(xuartps_data->aperclk); ++ if (rc) { ++ dev_err(&pdev->dev, "Unable to enable APER clock.\n"); ++ goto err_out_clk_put; ++ } ++ rc = clk_prepare_enable(xuartps_data->refclk); + if (rc) { +- dev_err(&pdev->dev, "could not enable clock\n"); +- return -EBUSY; ++ dev_err(&pdev->dev, "Unable to enable device clock.\n"); ++ goto err_out_clk_dis_aper; + } + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); +- if (!res) +- return -ENODEV; ++ if (!res) { ++ rc = -ENODEV; ++ goto err_out_clk_disable; ++ } + + res2 = platform_get_resource(pdev, IORESOURCE_IRQ, 0); +- if (!res2) +- return -ENODEV; ++ if (!res2) { ++ rc = -ENODEV; ++ goto err_out_clk_disable; ++ } + + /* Initialize the port structure */ + port = xuartps_get_port(); + + if (!port) { + dev_err(&pdev->dev, "Cannot get uart_port structure\n"); +- return -ENODEV; ++ rc = -ENODEV; ++ goto err_out_clk_disable; + } else { + /* Register the port. + * This function also registers this device with the tty layer +@@ -972,18 +1004,31 @@ static int xuartps_probe(struct platform_device *pdev) + port->mapbase = res->start; + port->irq = res2->start; + port->dev = &pdev->dev; +- port->uartclk = clk_get_rate(clk); +- port->private_data = clk; ++ port->uartclk = clk_get_rate(xuartps_data->refclk); ++ port->private_data = xuartps_data; + dev_set_drvdata(&pdev->dev, port); + rc = uart_add_one_port(&xuartps_uart_driver, port); + if (rc) { + dev_err(&pdev->dev, + "uart_add_one_port() failed; err=%i\n", rc); + dev_set_drvdata(&pdev->dev, NULL); +- return rc; ++ goto err_out_clk_disable; + } + return 0; + } ++ ++err_out_clk_disable: ++ clk_disable_unprepare(xuartps_data->refclk); ++err_out_clk_dis_aper: ++ clk_disable_unprepare(xuartps_data->aperclk); ++err_out_clk_put: ++ clk_put(xuartps_data->refclk); ++err_out_clk_put_aper: ++ clk_put(xuartps_data->aperclk); ++err_out_free: ++ kfree(xuartps_data); ++ ++ return rc; + } + + /** +@@ -995,14 +1040,18 @@ static int xuartps_probe(struct platform_device *pdev) + static int xuartps_remove(struct platform_device *pdev) + { + struct uart_port *port = dev_get_drvdata(&pdev->dev); +- struct clk *clk = port->private_data; ++ struct xuartps *xuartps_data = port->private_data; + int rc; + + /* Remove the xuartps port from the serial core */ + rc = uart_remove_one_port(&xuartps_uart_driver, port); + dev_set_drvdata(&pdev->dev, NULL); + port->mapbase = 0; +- clk_disable_unprepare(clk); ++ clk_disable_unprepare(xuartps_data->refclk); ++ clk_disable_unprepare(xuartps_data->aperclk); ++ clk_put(xuartps_data->refclk); ++ clk_put(xuartps_data->aperclk); ++ kfree(xuartps_data); + return rc; + } + +diff --git a/include/linux/clk/zynq.h b/include/linux/clk/zynq.h +index 56be7cd9aa8b..e062d317ccce 100644 +--- a/include/linux/clk/zynq.h ++++ b/include/linux/clk/zynq.h +@@ -1,4 +1,5 @@ + /* ++ * Copyright (C) 2013 Xilinx Inc. + * Copyright (C) 2012 National Instruments + * + * This program is free software; you can redistribute it and/or modify +@@ -19,6 +20,11 @@ + #ifndef __LINUX_CLK_ZYNQ_H_ + #define __LINUX_CLK_ZYNQ_H_ + +-void __init xilinx_zynq_clocks_init(void __iomem *slcr); ++#include <linux/spinlock.h> + ++void zynq_clock_init(void __iomem *slcr); ++ ++struct clk *clk_register_zynq_pll(const char *name, const char *parent, ++ void __iomem *pll_ctrl, void __iomem *pll_status, u8 lock_index, ++ spinlock_t *lock); + #endif +-- +1.8.5.rc3 + diff --git a/patches.zynq/0015-serial-use-platform_-get-set-_drvdata.patch b/patches.zynq/0015-serial-use-platform_-get-set-_drvdata.patch new file mode 100644 index 00000000000000..abf27e91aadb29 --- /dev/null +++ b/patches.zynq/0015-serial-use-platform_-get-set-_drvdata.patch @@ -0,0 +1,58 @@ +From 24151ccc15c826111d385037d237f6f2d7c06473 Mon Sep 17 00:00:00 2001 +From: Jingoo Han <jg1.han@samsung.com> +Date: Mon, 2 Dec 2013 09:24:29 +0900 +Subject: serial: use platform_{get,set}_drvdata() + + Use the wrapper functions for getting and setting the driver data using + platform_device instead of using dev_{get,set}_drvdata() with &pdev->dev, + so we can directly pass a struct platform_device. + + Also, unnecessary dev_set_drvdata() is removed, because the driver core + clears the driver data to NULL after device_release or on probe failure. + + Signed-off-by: Jingoo Han <jg1.han@samsung.com> + Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> + (cherry picked from commit 696faedd616e202f5c510cd03dcc8853c11ca6db) + Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> + +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + drivers/tty/serial/xilinx_uartps.c | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c +index 916305a573b8..2f76ad938b4b 100644 +--- a/drivers/tty/serial/xilinx_uartps.c ++++ b/drivers/tty/serial/xilinx_uartps.c +@@ -1006,12 +1006,11 @@ static int xuartps_probe(struct platform_device *pdev) + port->dev = &pdev->dev; + port->uartclk = clk_get_rate(xuartps_data->refclk); + port->private_data = xuartps_data; +- dev_set_drvdata(&pdev->dev, port); ++ platform_set_drvdata(pdev, port); + rc = uart_add_one_port(&xuartps_uart_driver, port); + if (rc) { + dev_err(&pdev->dev, + "uart_add_one_port() failed; err=%i\n", rc); +- dev_set_drvdata(&pdev->dev, NULL); + goto err_out_clk_disable; + } + return 0; +@@ -1039,13 +1038,12 @@ err_out_free: + **/ + static int xuartps_remove(struct platform_device *pdev) + { +- struct uart_port *port = dev_get_drvdata(&pdev->dev); ++ struct uart_port *port = platform_get_drvdata(pdev); + struct xuartps *xuartps_data = port->private_data; + int rc; + + /* Remove the xuartps port from the serial core */ + rc = uart_remove_one_port(&xuartps_uart_driver, port); +- dev_set_drvdata(&pdev->dev, NULL); + port->mapbase = 0; + clk_disable_unprepare(xuartps_data->refclk); + clk_disable_unprepare(xuartps_data->aperclk); +-- +1.8.5.rc3 + diff --git a/patches.zynq/0016-tty-xuartps-Use-devm_clk_get.patch b/patches.zynq/0016-tty-xuartps-Use-devm_clk_get.patch new file mode 100644 index 00000000000000..9e21eeedf27ade --- /dev/null +++ b/patches.zynq/0016-tty-xuartps-Use-devm_clk_get.patch @@ -0,0 +1,71 @@ +From ddc3257df7309ac066b59ac6c67a0463320414a0 Mon Sep 17 00:00:00 2001 +From: Soren Brinkmann <soren.brinkmann@xilinx.com> +Date: Thu, 17 Oct 2013 14:08:04 -0700 +Subject: tty: xuartps: Use devm_clk_get() + +Use the device managed interface for clocks, simplifying error paths. + +Signed-off-by: Soren Brinkmann <soren.brinkmann@xilinx.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +(cherry picked from commit 991fc259361eb812ebf6c4527343d60ab4b2e1a6) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + drivers/tty/serial/xilinx_uartps.c | 14 ++++---------- + 1 file changed, 4 insertions(+), 10 deletions(-) + +diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c +index 2f76ad938b4b..afa3a2d6856f 100644 +--- a/drivers/tty/serial/xilinx_uartps.c ++++ b/drivers/tty/serial/xilinx_uartps.c +@@ -953,23 +953,23 @@ static int xuartps_probe(struct platform_device *pdev) + if (!xuartps_data) + return -ENOMEM; + +- xuartps_data->aperclk = clk_get(&pdev->dev, "aper_clk"); ++ xuartps_data->aperclk = devm_clk_get(&pdev->dev, "aper_clk"); + if (IS_ERR(xuartps_data->aperclk)) { + dev_err(&pdev->dev, "aper_clk clock not found.\n"); + rc = PTR_ERR(xuartps_data->aperclk); + goto err_out_free; + } +- xuartps_data->refclk = clk_get(&pdev->dev, "ref_clk"); ++ xuartps_data->refclk = devm_clk_get(&pdev->dev, "ref_clk"); + if (IS_ERR(xuartps_data->refclk)) { + dev_err(&pdev->dev, "ref_clk clock not found.\n"); + rc = PTR_ERR(xuartps_data->refclk); +- goto err_out_clk_put_aper; ++ goto err_out_free; + } + + rc = clk_prepare_enable(xuartps_data->aperclk); + if (rc) { + dev_err(&pdev->dev, "Unable to enable APER clock.\n"); +- goto err_out_clk_put; ++ goto err_out_free; + } + rc = clk_prepare_enable(xuartps_data->refclk); + if (rc) { +@@ -1020,10 +1020,6 @@ err_out_clk_disable: + clk_disable_unprepare(xuartps_data->refclk); + err_out_clk_dis_aper: + clk_disable_unprepare(xuartps_data->aperclk); +-err_out_clk_put: +- clk_put(xuartps_data->refclk); +-err_out_clk_put_aper: +- clk_put(xuartps_data->aperclk); + err_out_free: + kfree(xuartps_data); + +@@ -1047,8 +1043,6 @@ static int xuartps_remove(struct platform_device *pdev) + port->mapbase = 0; + clk_disable_unprepare(xuartps_data->refclk); + clk_disable_unprepare(xuartps_data->aperclk); +- clk_put(xuartps_data->refclk); +- clk_put(xuartps_data->aperclk); + kfree(xuartps_data); + return rc; + } +-- +1.8.5.rc3 + diff --git a/patches.zynq/0017-tty-xuartps-Use-devm_kzalloc.patch b/patches.zynq/0017-tty-xuartps-Use-devm_kzalloc.patch new file mode 100644 index 00000000000000..b1cc2426c7440f --- /dev/null +++ b/patches.zynq/0017-tty-xuartps-Use-devm_kzalloc.patch @@ -0,0 +1,74 @@ +From 1603078a9e33591ba9d89b4b4a6cc58c84debf02 Mon Sep 17 00:00:00 2001 +From: Soren Brinkmann <soren.brinkmann@xilinx.com> +Date: Thu, 17 Oct 2013 14:08:05 -0700 +Subject: tty: xuartps: Use devm_kzalloc + +Use the device managed interface for memory allocation, simplifying +error paths. + +Signed-off-by: Soren Brinkmann <soren.brinkmann@xilinx.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +(cherry picked from commit c03cae1791407f4f4f9bc6b0354ecaeb50df787f) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + drivers/tty/serial/xilinx_uartps.c | 14 +++++--------- + 1 file changed, 5 insertions(+), 9 deletions(-) + +diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c +index afa3a2d6856f..2b3fe10362ba 100644 +--- a/drivers/tty/serial/xilinx_uartps.c ++++ b/drivers/tty/serial/xilinx_uartps.c +@@ -949,27 +949,26 @@ static int xuartps_probe(struct platform_device *pdev) + struct resource *res, *res2; + struct xuartps *xuartps_data; + +- xuartps_data = kzalloc(sizeof(*xuartps_data), GFP_KERNEL); ++ xuartps_data = devm_kzalloc(&pdev->dev, sizeof(*xuartps_data), ++ GFP_KERNEL); + if (!xuartps_data) + return -ENOMEM; + + xuartps_data->aperclk = devm_clk_get(&pdev->dev, "aper_clk"); + if (IS_ERR(xuartps_data->aperclk)) { + dev_err(&pdev->dev, "aper_clk clock not found.\n"); +- rc = PTR_ERR(xuartps_data->aperclk); +- goto err_out_free; ++ return PTR_ERR(xuartps_data->aperclk); + } + xuartps_data->refclk = devm_clk_get(&pdev->dev, "ref_clk"); + if (IS_ERR(xuartps_data->refclk)) { + dev_err(&pdev->dev, "ref_clk clock not found.\n"); +- rc = PTR_ERR(xuartps_data->refclk); +- goto err_out_free; ++ return PTR_ERR(xuartps_data->refclk); + } + + rc = clk_prepare_enable(xuartps_data->aperclk); + if (rc) { + dev_err(&pdev->dev, "Unable to enable APER clock.\n"); +- goto err_out_free; ++ return rc; + } + rc = clk_prepare_enable(xuartps_data->refclk); + if (rc) { +@@ -1020,8 +1019,6 @@ err_out_clk_disable: + clk_disable_unprepare(xuartps_data->refclk); + err_out_clk_dis_aper: + clk_disable_unprepare(xuartps_data->aperclk); +-err_out_free: +- kfree(xuartps_data); + + return rc; + } +@@ -1043,7 +1040,6 @@ static int xuartps_remove(struct platform_device *pdev) + port->mapbase = 0; + clk_disable_unprepare(xuartps_data->refclk); + clk_disable_unprepare(xuartps_data->aperclk); +- kfree(xuartps_data); + return rc; + } + +-- +1.8.5.rc3 + diff --git a/patches.zynq/0018-tty-xuartps-Implement-BREAK-detection-add-SYSRQ-supp.patch b/patches.zynq/0018-tty-xuartps-Implement-BREAK-detection-add-SYSRQ-supp.patch new file mode 100644 index 00000000000000..ec2b4204849084 --- /dev/null +++ b/patches.zynq/0018-tty-xuartps-Implement-BREAK-detection-add-SYSRQ-supp.patch @@ -0,0 +1,111 @@ +From dda80081e00ca6472b11591293a7c46cb7ef6527 Mon Sep 17 00:00:00 2001 +From: Vlad Lungu <vlad.lungu@windriver.com> +Date: Thu, 17 Oct 2013 14:08:06 -0700 +Subject: tty: xuartps: Implement BREAK detection, add SYSRQ support + +The Cadence UART does not do break detection, even if the +datasheet says it does. This patch adds break detection in +software (tested in 8N1 mode only) and enables SYSRQ, +allowing for Break-g to enter KDB and all the other goodies. + +Signed-off-by: Vlad Lungu <vlad.lungu@windriver.com> +Signed-off-by: Soren Brinkmann <soren.brinkmann@xilinx.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +(cherry picked from commit 0c0c47bc40a2e358d593b2d7fb93b50027fbfc0c) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + drivers/tty/serial/xilinx_uartps.c | 50 +++++++++++++++++++++++++++++++++++++- + 1 file changed, 49 insertions(+), 1 deletion(-) + +diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c +index 2b3fe10362ba..2f94b8b2512e 100644 +--- a/drivers/tty/serial/xilinx_uartps.c ++++ b/drivers/tty/serial/xilinx_uartps.c +@@ -11,13 +11,17 @@ + * + */ + ++#if defined(CONFIG_SERIAL_XILINX_PS_UART_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) ++#define SUPPORT_SYSRQ ++#endif ++ + #include <linux/platform_device.h> + #include <linux/serial.h> ++#include <linux/console.h> + #include <linux/serial_core.h> + #include <linux/slab.h> + #include <linux/tty.h> + #include <linux/tty_flip.h> +-#include <linux/console.h> + #include <linux/clk.h> + #include <linux/irq.h> + #include <linux/io.h> +@@ -128,6 +132,9 @@ + #define XUARTPS_IXR_RXEMPTY 0x00000002 /* RX FIFO empty interrupt. */ + #define XUARTPS_IXR_MASK 0x00001FFF /* Valid bit mask */ + ++/* Goes in read_status_mask for break detection as the HW doesn't do it*/ ++#define XUARTPS_IXR_BRK 0x80000000 ++ + /** Channel Status Register + * + * The channel status register (CSR) is provided to enable the control logic +@@ -171,6 +178,23 @@ static irqreturn_t xuartps_isr(int irq, void *dev_id) + */ + isrstatus = xuartps_readl(XUARTPS_ISR_OFFSET); + ++ /* ++ * There is no hardware break detection, so we interpret framing ++ * error with all-zeros data as a break sequence. Most of the time, ++ * there's another non-zero byte at the end of the sequence. ++ */ ++ ++ if (isrstatus & XUARTPS_IXR_FRAMING) { ++ while (!(xuartps_readl(XUARTPS_SR_OFFSET) & ++ XUARTPS_SR_RXEMPTY)) { ++ if (!xuartps_readl(XUARTPS_FIFO_OFFSET)) { ++ port->read_status_mask |= XUARTPS_IXR_BRK; ++ isrstatus &= ~XUARTPS_IXR_FRAMING; ++ } ++ } ++ xuartps_writel(XUARTPS_IXR_FRAMING, XUARTPS_ISR_OFFSET); ++ } ++ + /* drop byte with parity error if IGNPAR specified */ + if (isrstatus & port->ignore_status_mask & XUARTPS_IXR_PARITY) + isrstatus &= ~(XUARTPS_IXR_RXTRIG | XUARTPS_IXR_TOUT); +@@ -184,6 +208,30 @@ static irqreturn_t xuartps_isr(int irq, void *dev_id) + while ((xuartps_readl(XUARTPS_SR_OFFSET) & + XUARTPS_SR_RXEMPTY) != XUARTPS_SR_RXEMPTY) { + data = xuartps_readl(XUARTPS_FIFO_OFFSET); ++ ++ /* Non-NULL byte after BREAK is garbage (99%) */ ++ if (data && (port->read_status_mask & ++ XUARTPS_IXR_BRK)) { ++ port->read_status_mask &= ~XUARTPS_IXR_BRK; ++ port->icount.brk++; ++ if (uart_handle_break(port)) ++ continue; ++ } ++ ++ /* ++ * uart_handle_sysrq_char() doesn't work if ++ * spinlocked, for some reason ++ */ ++ if (port->sysrq) { ++ spin_unlock(&port->lock); ++ if (uart_handle_sysrq_char(port, ++ (unsigned char)data)) { ++ spin_lock(&port->lock); ++ continue; ++ } ++ spin_lock(&port->lock); ++ } ++ + port->icount.rx++; + + if (isrstatus & XUARTPS_IXR_PARITY) { +-- +1.8.5.rc3 + diff --git a/patches.zynq/0019-tty-xuartps-Add-polled-mode-support-for-xuartps.patch b/patches.zynq/0019-tty-xuartps-Add-polled-mode-support-for-xuartps.patch new file mode 100644 index 00000000000000..3fec51cfd6c25a --- /dev/null +++ b/patches.zynq/0019-tty-xuartps-Add-polled-mode-support-for-xuartps.patch @@ -0,0 +1,90 @@ +From 68c9e7ed1cb3dbfa9cdfbd043dcc6e237b5ed7a7 Mon Sep 17 00:00:00 2001 +From: Vlad Lungu <vlad.lungu@windriver.com> +Date: Thu, 17 Oct 2013 14:08:07 -0700 +Subject: tty: xuartps: Add polled mode support for xuartps + +This allows KDB/KGDB to run. + +Signed-off-by: Vlad Lungu <vlad.lungu@windriver.com> +Signed-off-by: Soren Brinkmann <soren.brinkmann@xilinx.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +(cherry picked from commit 6ee04c6c5488b2b7fdfa22c771c127411f86e610) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + drivers/tty/serial/xilinx_uartps.c | 52 ++++++++++++++++++++++++++++++++++++++ + 1 file changed, 52 insertions(+) + +diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c +index 2f94b8b2512e..5a0489fc3e11 100644 +--- a/drivers/tty/serial/xilinx_uartps.c ++++ b/drivers/tty/serial/xilinx_uartps.c +@@ -775,6 +775,54 @@ static void xuartps_enable_ms(struct uart_port *port) + /* N/A */ + } + ++#ifdef CONFIG_CONSOLE_POLL ++static int xuartps_poll_get_char(struct uart_port *port) ++{ ++ u32 imr; ++ int c; ++ ++ /* Disable all interrupts */ ++ imr = xuartps_readl(XUARTPS_IMR_OFFSET); ++ xuartps_writel(imr, XUARTPS_IDR_OFFSET); ++ ++ /* Check if FIFO is empty */ ++ if (xuartps_readl(XUARTPS_SR_OFFSET) & XUARTPS_SR_RXEMPTY) ++ c = NO_POLL_CHAR; ++ else /* Read a character */ ++ c = (unsigned char) xuartps_readl(XUARTPS_FIFO_OFFSET); ++ ++ /* Enable interrupts */ ++ xuartps_writel(imr, XUARTPS_IER_OFFSET); ++ ++ return c; ++} ++ ++static void xuartps_poll_put_char(struct uart_port *port, unsigned char c) ++{ ++ u32 imr; ++ ++ /* Disable all interrupts */ ++ imr = xuartps_readl(XUARTPS_IMR_OFFSET); ++ xuartps_writel(imr, XUARTPS_IDR_OFFSET); ++ ++ /* Wait until FIFO is empty */ ++ while (!(xuartps_readl(XUARTPS_SR_OFFSET) & XUARTPS_SR_TXEMPTY)) ++ cpu_relax(); ++ ++ /* Write a character */ ++ xuartps_writel(c, XUARTPS_FIFO_OFFSET); ++ ++ /* Wait until FIFO is empty */ ++ while (!(xuartps_readl(XUARTPS_SR_OFFSET) & XUARTPS_SR_TXEMPTY)) ++ cpu_relax(); ++ ++ /* Enable interrupts */ ++ xuartps_writel(imr, XUARTPS_IER_OFFSET); ++ ++ return; ++} ++#endif ++ + /** The UART operations structure + */ + static struct uart_ops xuartps_ops = { +@@ -807,6 +855,10 @@ static struct uart_ops xuartps_ops = { + .config_port = xuartps_config_port, /* Configure when driver + * adds a xuartps port + */ ++#ifdef CONFIG_CONSOLE_POLL ++ .poll_get_char = xuartps_poll_get_char, ++ .poll_put_char = xuartps_poll_put_char, ++#endif + }; + + static struct uart_port xuartps_port[2]; +-- +1.8.5.rc3 + diff --git a/patches.zynq/0020-tty-xuartps-support-64-byte-FIFO-size.patch b/patches.zynq/0020-tty-xuartps-support-64-byte-FIFO-size.patch new file mode 100644 index 00000000000000..a10e00e66d12e6 --- /dev/null +++ b/patches.zynq/0020-tty-xuartps-support-64-byte-FIFO-size.patch @@ -0,0 +1,90 @@ +From 8f0f5797bba6f41237925f535eed94e29a549998 Mon Sep 17 00:00:00 2001 +From: Suneel <suneelg@xilinx.com> +Date: Thu, 17 Oct 2013 14:08:08 -0700 +Subject: tty: xuartps: support 64 byte FIFO size + +Changes to use the 64 byte FIFO depth and fix the issue +by clearing the txempty interrupt in isr status for tx +after filling in data in start_tx function + +Signed-off-by: Suneel Garapati <suneelg@xilinx.com> +Signed-off-by: Soren Brinkmann <soren.brinkmann@xilinx.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +(cherry picked from commit 85baf542d54ec321642194b0ebfa7316e3190dc2) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + drivers/tty/serial/xilinx_uartps.c | 30 +++++++++++++++++++++++------- + 1 file changed, 23 insertions(+), 7 deletions(-) + +diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c +index 5a0489fc3e11..4a1f6080ef59 100644 +--- a/drivers/tty/serial/xilinx_uartps.c ++++ b/drivers/tty/serial/xilinx_uartps.c +@@ -33,12 +33,22 @@ + #define XUARTPS_MAJOR 0 /* use dynamic node allocation */ + #define XUARTPS_MINOR 0 /* works best with devtmpfs */ + #define XUARTPS_NR_PORTS 2 +-#define XUARTPS_FIFO_SIZE 16 /* FIFO size */ ++#define XUARTPS_FIFO_SIZE 64 /* FIFO size */ + #define XUARTPS_REGISTER_SPACE 0xFFF + + #define xuartps_readl(offset) ioread32(port->membase + offset) + #define xuartps_writel(val, offset) iowrite32(val, port->membase + offset) + ++/* Rx Trigger level */ ++static int rx_trigger_level = 56; ++module_param(rx_trigger_level, uint, S_IRUGO); ++MODULE_PARM_DESC(rx_trigger_level, "Rx trigger level, 1-63 bytes"); ++ ++/* Rx Timeout */ ++static int rx_timeout = 10; ++module_param(rx_timeout, uint, S_IRUGO); ++MODULE_PARM_DESC(rx_timeout, "Rx timeout, 1-255"); ++ + /********************************Register Map********************************/ + /** UART + * +@@ -394,7 +404,7 @@ static void xuartps_start_tx(struct uart_port *port) + port->state->xmit.tail = (port->state->xmit.tail + 1) & + (UART_XMIT_SIZE - 1); + } +- ++ xuartps_writel(XUARTPS_IXR_TXEMPTY, XUARTPS_ISR_OFFSET); + /* Enable the TX Empty interrupt */ + xuartps_writel(XUARTPS_IXR_TXEMPTY, XUARTPS_IER_OFFSET); + +@@ -528,7 +538,7 @@ static void xuartps_set_termios(struct uart_port *port, + | (XUARTPS_CR_TX_EN | XUARTPS_CR_RX_EN), + XUARTPS_CR_OFFSET); + +- xuartps_writel(10, XUARTPS_RXTOUT_OFFSET); ++ xuartps_writel(rx_timeout, XUARTPS_RXTOUT_OFFSET); + + port->read_status_mask = XUARTPS_IXR_TXEMPTY | XUARTPS_IXR_RXTRIG | + XUARTPS_IXR_OVERRUN | XUARTPS_IXR_TOUT; +@@ -631,11 +641,17 @@ static int xuartps_startup(struct uart_port *port) + | XUARTPS_MR_PARITY_NONE | XUARTPS_MR_CHARLEN_8_BIT, + XUARTPS_MR_OFFSET); + +- /* Set the RX FIFO Trigger level to 14 assuming FIFO size as 16 */ +- xuartps_writel(14, XUARTPS_RXWM_OFFSET); ++ /* ++ * Set the RX FIFO Trigger level to use most of the FIFO, but it ++ * can be tuned with a module parameter ++ */ ++ xuartps_writel(rx_trigger_level, XUARTPS_RXWM_OFFSET); + +- /* Receive Timeout register is enabled with value of 10 */ +- xuartps_writel(10, XUARTPS_RXTOUT_OFFSET); ++ /* ++ * Receive Timeout register is enabled but it ++ * can be tuned with a module parameter ++ */ ++ xuartps_writel(rx_timeout, XUARTPS_RXTOUT_OFFSET); + + /* Clear out any pending interrupts before enabling them */ + xuartps_writel(xuartps_readl(XUARTPS_ISR_OFFSET), XUARTPS_ISR_OFFSET); +-- +1.8.5.rc3 + diff --git a/patches.zynq/0021-tty-xuartps-Force-enable-the-UART-in-xuartps_console.patch b/patches.zynq/0021-tty-xuartps-Force-enable-the-UART-in-xuartps_console.patch new file mode 100644 index 00000000000000..d67c13b81a458f --- /dev/null +++ b/patches.zynq/0021-tty-xuartps-Force-enable-the-UART-in-xuartps_console.patch @@ -0,0 +1,59 @@ +From 2de507b6c59647a1a907c18f62785ddf8d36ed50 Mon Sep 17 00:00:00 2001 +From: Lars-Peter Clausen <lars@metafoo.de> +Date: Thu, 17 Oct 2013 14:08:09 -0700 +Subject: tty: xuartps: Force enable the UART in xuartps_console_write + +It is possible that under certain circumstances xuartps_console_write is entered +while the UART disabled. When this happens the code will busy loop in +xuartps_console_putchar, since the character is never written and the TXEMPTY +flag is never set. The result is a system lockup. This patch force enables the +UART for the duration of xuartps_console_write to avoid this. + +Signed-off-by: Lars-Peter Clausen <lars@metafoo.de> +Signed-off-by: John Linn <john.linn@xilinx.com> +Signed-off-by: Michal Simek <michal.simek@xilinx.com> +Signed-off-by: Soren Brinkmann <soren.brinkmann@xilinx.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +(cherry picked from commit d3755f5e6cd222cd5aff949228d32aa8446023a5) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + drivers/tty/serial/xilinx_uartps.c | 12 +++++++++++- + 1 file changed, 11 insertions(+), 1 deletion(-) + +diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c +index 4a1f6080ef59..cf5487841362 100644 +--- a/drivers/tty/serial/xilinx_uartps.c ++++ b/drivers/tty/serial/xilinx_uartps.c +@@ -953,7 +953,7 @@ static void xuartps_console_write(struct console *co, const char *s, + { + struct uart_port *port = &xuartps_port[co->index]; + unsigned long flags; +- unsigned int imr; ++ unsigned int imr, ctrl; + int locked = 1; + + if (oops_in_progress) +@@ -965,9 +965,19 @@ static void xuartps_console_write(struct console *co, const char *s, + imr = xuartps_readl(XUARTPS_IMR_OFFSET); + xuartps_writel(imr, XUARTPS_IDR_OFFSET); + ++ /* ++ * Make sure that the tx part is enabled. Set the TX enable bit and ++ * clear the TX disable bit to enable the transmitter. ++ */ ++ ctrl = xuartps_readl(XUARTPS_CR_OFFSET); ++ xuartps_writel((ctrl & ~XUARTPS_CR_TX_DIS) | XUARTPS_CR_TX_EN, ++ XUARTPS_CR_OFFSET); ++ + uart_console_write(port, s, count, xuartps_console_putchar); + xuartps_console_wait_tx(port); + ++ xuartps_writel(ctrl, XUARTPS_CR_OFFSET); ++ + /* restore interrupt state, it seems like there may be a h/w bug + * in that the interrupt enable register should not need to be + * written based on the data sheet +-- +1.8.5.rc3 + diff --git a/patches.zynq/0022-tty-xuartps-Updating-set_baud_rate.patch b/patches.zynq/0022-tty-xuartps-Updating-set_baud_rate.patch new file mode 100644 index 00000000000000..0411c86c77ecc5 --- /dev/null +++ b/patches.zynq/0022-tty-xuartps-Updating-set_baud_rate.patch @@ -0,0 +1,218 @@ +From 9ad9305ff9d38b67ab53642596bd59555f92658e Mon Sep 17 00:00:00 2001 +From: Soren Brinkmann <soren.brinkmann@xilinx.com> +Date: Thu, 17 Oct 2013 14:08:10 -0700 +Subject: tty: xuartps: Updating set_baud_rate() + +The original algorithm to find the best baud rate dividers does not necessarily +find the best set of dividers. And in the worst case may even write illegal +values to the hardware. +The new function should make better use of the hardware capabilities and be able +to provide valid settings for a wider range of baud rates and also input clocks. + +Signed-off-by: Soren Brinkmann <soren.brinkmann@xilinx.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +(cherry picked from commit e6b39bfd0db207d2e9f3f78468d18f529f3b7901) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + drivers/tty/serial/xilinx_uartps.c | 136 +++++++++++++++++++++++++------------ + 1 file changed, 93 insertions(+), 43 deletions(-) + +diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c +index cf5487841362..3f15e8048448 100644 +--- a/drivers/tty/serial/xilinx_uartps.c ++++ b/drivers/tty/serial/xilinx_uartps.c +@@ -156,6 +156,11 @@ MODULE_PARM_DESC(rx_timeout, "Rx timeout, 1-255"); + #define XUARTPS_SR_TXFULL 0x00000010 /* TX FIFO full */ + #define XUARTPS_SR_RXTRIG 0x00000001 /* Rx Trigger */ + ++/* baud dividers min/max values */ ++#define XUARTPS_BDIV_MIN 4 ++#define XUARTPS_BDIV_MAX 255 ++#define XUARTPS_CD_MAX 65535 ++ + /** + * struct xuartps - device data + * @refclk Reference clock +@@ -305,59 +310,94 @@ static irqreturn_t xuartps_isr(int irq, void *dev_id) + } + + /** +- * xuartps_set_baud_rate - Calculate and set the baud rate +- * @port: Handle to the uart port structure +- * @baud: Baud rate to set +- * ++ * xuartps_calc_baud_divs - Calculate baud rate divisors ++ * @clk: UART module input clock ++ * @baud: Desired baud rate ++ * @rbdiv: BDIV value (return value) ++ * @rcd: CD value (return value) ++ * @div8: Value for clk_sel bit in mod (return value) + * Returns baud rate, requested baud when possible, or actual baud when there +- * was too much error +- **/ +-static unsigned int xuartps_set_baud_rate(struct uart_port *port, +- unsigned int baud) ++ * was too much error, zero if no valid divisors are found. ++ * ++ * Formula to obtain baud rate is ++ * baud_tx/rx rate = clk/CD * (BDIV + 1) ++ * input_clk = (Uart User Defined Clock or Apb Clock) ++ * depends on UCLKEN in MR Reg ++ * clk = input_clk or input_clk/8; ++ * depends on CLKS in MR reg ++ * CD and BDIV depends on values in ++ * baud rate generate register ++ * baud rate clock divisor register ++ */ ++static unsigned int xuartps_calc_baud_divs(unsigned int clk, unsigned int baud, ++ u32 *rbdiv, u32 *rcd, int *div8) + { +- unsigned int sel_clk; +- unsigned int calc_baud = 0; +- unsigned int brgr_val, brdiv_val; ++ u32 cd, bdiv; ++ unsigned int calc_baud; ++ unsigned int bestbaud = 0; + unsigned int bauderror; ++ unsigned int besterror = ~0; + +- /* Formula to obtain baud rate is +- * baud_tx/rx rate = sel_clk/CD * (BDIV + 1) +- * input_clk = (Uart User Defined Clock or Apb Clock) +- * depends on UCLKEN in MR Reg +- * sel_clk = input_clk or input_clk/8; +- * depends on CLKS in MR reg +- * CD and BDIV depends on values in +- * baud rate generate register +- * baud rate clock divisor register +- */ +- sel_clk = port->uartclk; +- if (xuartps_readl(XUARTPS_MR_OFFSET) & XUARTPS_MR_CLKSEL) +- sel_clk = sel_clk / 8; +- +- /* Find the best values for baud generation */ +- for (brdiv_val = 4; brdiv_val < 255; brdiv_val++) { ++ if (baud < clk / ((XUARTPS_BDIV_MAX + 1) * XUARTPS_CD_MAX)) { ++ *div8 = 1; ++ clk /= 8; ++ } else { ++ *div8 = 0; ++ } + +- brgr_val = sel_clk / (baud * (brdiv_val + 1)); +- if (brgr_val < 2 || brgr_val > 65535) ++ for (bdiv = XUARTPS_BDIV_MIN; bdiv <= XUARTPS_BDIV_MAX; bdiv++) { ++ cd = DIV_ROUND_CLOSEST(clk, baud * (bdiv + 1)); ++ if (cd < 1 || cd > XUARTPS_CD_MAX) + continue; + +- calc_baud = sel_clk / (brgr_val * (brdiv_val + 1)); ++ calc_baud = clk / (cd * (bdiv + 1)); + + if (baud > calc_baud) + bauderror = baud - calc_baud; + else + bauderror = calc_baud - baud; + +- /* use the values when percent error is acceptable */ +- if (((bauderror * 100) / baud) < 3) { +- calc_baud = baud; +- break; ++ if (besterror > bauderror) { ++ *rbdiv = bdiv; ++ *rcd = cd; ++ bestbaud = calc_baud; ++ besterror = bauderror; + } + } ++ /* use the values when percent error is acceptable */ ++ if (((besterror * 100) / baud) < 3) ++ bestbaud = baud; ++ ++ return bestbaud; ++} + +- /* Set the values for the new baud rate */ +- xuartps_writel(brgr_val, XUARTPS_BAUDGEN_OFFSET); +- xuartps_writel(brdiv_val, XUARTPS_BAUDDIV_OFFSET); ++/** ++ * xuartps_set_baud_rate - Calculate and set the baud rate ++ * @port: Handle to the uart port structure ++ * @baud: Baud rate to set ++ * Returns baud rate, requested baud when possible, or actual baud when there ++ * was too much error, zero if no valid divisors are found. ++ */ ++static unsigned int xuartps_set_baud_rate(struct uart_port *port, ++ unsigned int baud) ++{ ++ unsigned int calc_baud; ++ u32 cd, bdiv; ++ u32 mreg; ++ int div8; ++ ++ calc_baud = xuartps_calc_baud_divs(port->uartclk, baud, &bdiv, &cd, ++ &div8); ++ ++ /* Write new divisors to hardware */ ++ mreg = xuartps_readl(XUARTPS_MR_OFFSET); ++ if (div8) ++ mreg |= XUARTPS_MR_CLKSEL; ++ else ++ mreg &= ~XUARTPS_MR_CLKSEL; ++ xuartps_writel(mreg, XUARTPS_MR_OFFSET); ++ xuartps_writel(cd, XUARTPS_BAUDGEN_OFFSET); ++ xuartps_writel(bdiv, XUARTPS_BAUDDIV_OFFSET); + + return calc_baud; + } +@@ -495,7 +535,7 @@ static void xuartps_set_termios(struct uart_port *port, + struct ktermios *termios, struct ktermios *old) + { + unsigned int cval = 0; +- unsigned int baud; ++ unsigned int baud, minbaud, maxbaud; + unsigned long flags; + unsigned int ctrl_reg, mode_reg; + +@@ -512,8 +552,14 @@ static void xuartps_set_termios(struct uart_port *port, + (XUARTPS_CR_TX_DIS | XUARTPS_CR_RX_DIS), + XUARTPS_CR_OFFSET); + +- /* Min baud rate = 6bps and Max Baud Rate is 10Mbps for 100Mhz clk */ +- baud = uart_get_baud_rate(port, termios, old, 0, 10000000); ++ /* ++ * Min baud rate = 6bps and Max Baud Rate is 10Mbps for 100Mhz clk ++ * min and max baud should be calculated here based on port->uartclk. ++ * this way we get a valid baud and can safely call set_baud() ++ */ ++ minbaud = port->uartclk / ((XUARTPS_BDIV_MAX + 1) * XUARTPS_CD_MAX * 8); ++ maxbaud = port->uartclk / (XUARTPS_BDIV_MIN + 1); ++ baud = uart_get_baud_rate(port, termios, old, minbaud, maxbaud); + baud = xuartps_set_baud_rate(port, baud); + if (tty_termios_baud_rate(termios)) + tty_termios_encode_baud_rate(termios, baud, baud); +@@ -589,13 +635,17 @@ static void xuartps_set_termios(struct uart_port *port, + cval |= XUARTPS_MR_PARITY_MARK; + else + cval |= XUARTPS_MR_PARITY_SPACE; +- } else if (termios->c_cflag & PARODD) ++ } else { ++ if (termios->c_cflag & PARODD) + cval |= XUARTPS_MR_PARITY_ODD; + else + cval |= XUARTPS_MR_PARITY_EVEN; +- } else ++ } ++ } else { + cval |= XUARTPS_MR_PARITY_NONE; +- xuartps_writel(cval , XUARTPS_MR_OFFSET); ++ } ++ cval |= mode_reg & 1; ++ xuartps_writel(cval, XUARTPS_MR_OFFSET); + + spin_unlock_irqrestore(&port->lock, flags); + } +-- +1.8.5.rc3 + diff --git a/patches.zynq/0023-tty-xuartps-Dynamically-adjust-to-input-frequency-ch.patch b/patches.zynq/0023-tty-xuartps-Dynamically-adjust-to-input-frequency-ch.patch new file mode 100644 index 00000000000000..1e6eaadd12cc1c --- /dev/null +++ b/patches.zynq/0023-tty-xuartps-Dynamically-adjust-to-input-frequency-ch.patch @@ -0,0 +1,215 @@ +From 287e3beb8f7e3e2176b426f418b27f46daa42df9 Mon Sep 17 00:00:00 2001 +From: Soren Brinkmann <soren.brinkmann@xilinx.com> +Date: Thu, 17 Oct 2013 14:08:11 -0700 +Subject: tty: xuartps: Dynamically adjust to input frequency changes + +Add a clock notifier to dynamically handle frequency changes of the +input clock by reprogramming the UART in order to keep the baud rate +constant. + +Signed-off-by: Soren Brinkmann <soren.brinkmann@xilinx.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +(cherry picked from commit c4b0510cc1571ff44e1d6024d92683d49a8bcfde) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + drivers/tty/serial/xilinx_uartps.c | 125 +++++++++++++++++++++++++++++++++++-- + 1 file changed, 120 insertions(+), 5 deletions(-) + +diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c +index 3f15e8048448..82195040e906 100644 +--- a/drivers/tty/serial/xilinx_uartps.c ++++ b/drivers/tty/serial/xilinx_uartps.c +@@ -163,13 +163,20 @@ MODULE_PARM_DESC(rx_timeout, "Rx timeout, 1-255"); + + /** + * struct xuartps - device data +- * @refclk Reference clock +- * @aperclk APB clock ++ * @port Pointer to the UART port ++ * @refclk Reference clock ++ * @aperclk APB clock ++ * @baud Current baud rate ++ * @clk_rate_change_nb Notifier block for clock changes + */ + struct xuartps { ++ struct uart_port *port; + struct clk *refclk; + struct clk *aperclk; ++ unsigned int baud; ++ struct notifier_block clk_rate_change_nb; + }; ++#define to_xuartps(_nb) container_of(_nb, struct xuartps, clk_rate_change_nb); + + /** + * xuartps_isr - Interrupt handler +@@ -385,6 +392,7 @@ static unsigned int xuartps_set_baud_rate(struct uart_port *port, + u32 cd, bdiv; + u32 mreg; + int div8; ++ struct xuartps *xuartps = port->private_data; + + calc_baud = xuartps_calc_baud_divs(port->uartclk, baud, &bdiv, &cd, + &div8); +@@ -398,10 +406,105 @@ static unsigned int xuartps_set_baud_rate(struct uart_port *port, + xuartps_writel(mreg, XUARTPS_MR_OFFSET); + xuartps_writel(cd, XUARTPS_BAUDGEN_OFFSET); + xuartps_writel(bdiv, XUARTPS_BAUDDIV_OFFSET); ++ xuartps->baud = baud; + + return calc_baud; + } + ++/** ++ * xuartps_clk_notitifer_cb - Clock notifier callback ++ * @nb: Notifier block ++ * @event: Notify event ++ * @data: Notifier data ++ * Returns NOTIFY_OK on success, NOTIFY_BAD on error. ++ */ ++static int xuartps_clk_notifier_cb(struct notifier_block *nb, ++ unsigned long event, void *data) ++{ ++ u32 ctrl_reg; ++ struct uart_port *port; ++ int locked = 0; ++ struct clk_notifier_data *ndata = data; ++ unsigned long flags = 0; ++ struct xuartps *xuartps = to_xuartps(nb); ++ ++ port = xuartps->port; ++ if (port->suspended) ++ return NOTIFY_OK; ++ ++ switch (event) { ++ case PRE_RATE_CHANGE: ++ { ++ u32 bdiv; ++ u32 cd; ++ int div8; ++ ++ /* ++ * Find out if current baud-rate can be achieved with new clock ++ * frequency. ++ */ ++ if (!xuartps_calc_baud_divs(ndata->new_rate, xuartps->baud, ++ &bdiv, &cd, &div8)) ++ return NOTIFY_BAD; ++ ++ spin_lock_irqsave(&xuartps->port->lock, flags); ++ ++ /* Disable the TX and RX to set baud rate */ ++ xuartps_writel(xuartps_readl(XUARTPS_CR_OFFSET) | ++ (XUARTPS_CR_TX_DIS | XUARTPS_CR_RX_DIS), ++ XUARTPS_CR_OFFSET); ++ ++ spin_unlock_irqrestore(&xuartps->port->lock, flags); ++ ++ return NOTIFY_OK; ++ } ++ case POST_RATE_CHANGE: ++ /* ++ * Set clk dividers to generate correct baud with new clock ++ * frequency. ++ */ ++ ++ spin_lock_irqsave(&xuartps->port->lock, flags); ++ ++ locked = 1; ++ port->uartclk = ndata->new_rate; ++ ++ xuartps->baud = xuartps_set_baud_rate(xuartps->port, ++ xuartps->baud); ++ /* fall through */ ++ case ABORT_RATE_CHANGE: ++ if (!locked) ++ spin_lock_irqsave(&xuartps->port->lock, flags); ++ ++ /* Set TX/RX Reset */ ++ xuartps_writel(xuartps_readl(XUARTPS_CR_OFFSET) | ++ (XUARTPS_CR_TXRST | XUARTPS_CR_RXRST), ++ XUARTPS_CR_OFFSET); ++ ++ while (xuartps_readl(XUARTPS_CR_OFFSET) & ++ (XUARTPS_CR_TXRST | XUARTPS_CR_RXRST)) ++ cpu_relax(); ++ ++ /* ++ * Clear the RX disable and TX disable bits and then set the TX ++ * enable bit and RX enable bit to enable the transmitter and ++ * receiver. ++ */ ++ xuartps_writel(rx_timeout, XUARTPS_RXTOUT_OFFSET); ++ ctrl_reg = xuartps_readl(XUARTPS_CR_OFFSET); ++ xuartps_writel( ++ (ctrl_reg & ~(XUARTPS_CR_TX_DIS | XUARTPS_CR_RX_DIS)) | ++ (XUARTPS_CR_TX_EN | XUARTPS_CR_RX_EN), ++ XUARTPS_CR_OFFSET); ++ ++ spin_unlock_irqrestore(&xuartps->port->lock, flags); ++ ++ return NOTIFY_OK; ++ default: ++ return NOTIFY_DONE; ++ } ++} ++ + /*----------------------Uart Operations---------------------------*/ + + /** +@@ -1164,13 +1267,19 @@ static int xuartps_probe(struct platform_device *pdev) + goto err_out_clk_disable; + } + ++ xuartps_data->clk_rate_change_nb.notifier_call = ++ xuartps_clk_notifier_cb; ++ if (clk_notifier_register(xuartps_data->refclk, ++ &xuartps_data->clk_rate_change_nb)) ++ dev_warn(&pdev->dev, "Unable to register clock notifier.\n"); ++ + /* Initialize the port structure */ + port = xuartps_get_port(); + + if (!port) { + dev_err(&pdev->dev, "Cannot get uart_port structure\n"); + rc = -ENODEV; +- goto err_out_clk_disable; ++ goto err_out_notif_unreg; + } else { + /* Register the port. + * This function also registers this device with the tty layer +@@ -1181,16 +1290,20 @@ static int xuartps_probe(struct platform_device *pdev) + port->dev = &pdev->dev; + port->uartclk = clk_get_rate(xuartps_data->refclk); + port->private_data = xuartps_data; +- platform_set_drvdata(pdev, port); ++ xuartps_data->port = port; ++ platform_set_drvdata(pdev, port); + rc = uart_add_one_port(&xuartps_uart_driver, port); + if (rc) { + dev_err(&pdev->dev, + "uart_add_one_port() failed; err=%i\n", rc); +- goto err_out_clk_disable; ++ goto err_out_notif_unreg; + } + return 0; + } + ++err_out_notif_unreg: ++ clk_notifier_unregister(xuartps_data->refclk, ++ &xuartps_data->clk_rate_change_nb); + err_out_clk_disable: + clk_disable_unprepare(xuartps_data->refclk); + err_out_clk_dis_aper: +@@ -1212,6 +1325,8 @@ static int xuartps_remove(struct platform_device *pdev) + int rc; + + /* Remove the xuartps port from the serial core */ ++ clk_notifier_unregister(xuartps_data->refclk, ++ &xuartps_data->clk_rate_change_nb); + rc = uart_remove_one_port(&xuartps_uart_driver, port); + port->mapbase = 0; + clk_disable_unprepare(xuartps_data->refclk); +-- +1.8.5.rc3 + diff --git a/patches.zynq/0024-tty-xuartps-Implement-suspend-resume-callbacks.patch b/patches.zynq/0024-tty-xuartps-Implement-suspend-resume-callbacks.patch new file mode 100644 index 00000000000000..354b21e117716a --- /dev/null +++ b/patches.zynq/0024-tty-xuartps-Implement-suspend-resume-callbacks.patch @@ -0,0 +1,152 @@ +From 11c054affc9e6d0074cbf7978f0af3511fc2d19d Mon Sep 17 00:00:00 2001 +From: Soren Brinkmann <soren.brinkmann@xilinx.com> +Date: Thu, 17 Oct 2013 14:08:12 -0700 +Subject: tty: xuartps: Implement suspend/resume callbacks + +Implement suspend and resume callbacks in order to support system +suspend/hibernation. + +Signed-off-by: Soren Brinkmann <soren.brinkmann@xilinx.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +(cherry picked from commit 4b47d9aa1e3b54b73f9399f3d64b47495cc67a1e) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + drivers/tty/serial/xilinx_uartps.c | 114 +++++++++++++++++++++++++++++++++++++ + 1 file changed, 114 insertions(+) + +diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c +index 82195040e906..9ecd8ea4f3ae 100644 +--- a/drivers/tty/serial/xilinx_uartps.c ++++ b/drivers/tty/serial/xilinx_uartps.c +@@ -1198,6 +1198,119 @@ console_initcall(xuartps_console_init); + + #endif /* CONFIG_SERIAL_XILINX_PS_UART_CONSOLE */ + ++#ifdef CONFIG_PM_SLEEP ++/** ++ * xuartps_suspend - suspend event ++ * @device: Pointer to the device structure ++ * ++ * Returns 0 ++ */ ++static int xuartps_suspend(struct device *device) ++{ ++ struct uart_port *port = dev_get_drvdata(device); ++ struct tty_struct *tty; ++ struct device *tty_dev; ++ int may_wake = 0; ++ ++ /* Get the tty which could be NULL so don't assume it's valid */ ++ tty = tty_port_tty_get(&port->state->port); ++ if (tty) { ++ tty_dev = tty->dev; ++ may_wake = device_may_wakeup(tty_dev); ++ tty_kref_put(tty); ++ } ++ ++ /* ++ * Call the API provided in serial_core.c file which handles ++ * the suspend. ++ */ ++ uart_suspend_port(&xuartps_uart_driver, port); ++ if (console_suspend_enabled && !may_wake) { ++ struct xuartps *xuartps = port->private_data; ++ ++ clk_disable(xuartps->refclk); ++ clk_disable(xuartps->aperclk); ++ } else { ++ unsigned long flags = 0; ++ ++ spin_lock_irqsave(&port->lock, flags); ++ /* Empty the receive FIFO 1st before making changes */ ++ while (!(xuartps_readl(XUARTPS_SR_OFFSET) & XUARTPS_SR_RXEMPTY)) ++ xuartps_readl(XUARTPS_FIFO_OFFSET); ++ /* set RX trigger level to 1 */ ++ xuartps_writel(1, XUARTPS_RXWM_OFFSET); ++ /* disable RX timeout interrups */ ++ xuartps_writel(XUARTPS_IXR_TOUT, XUARTPS_IDR_OFFSET); ++ spin_unlock_irqrestore(&port->lock, flags); ++ } ++ ++ return 0; ++} ++ ++/** ++ * xuartps_resume - Resume after a previous suspend ++ * @device: Pointer to the device structure ++ * ++ * Returns 0 ++ */ ++static int xuartps_resume(struct device *device) ++{ ++ struct uart_port *port = dev_get_drvdata(device); ++ unsigned long flags = 0; ++ u32 ctrl_reg; ++ struct tty_struct *tty; ++ struct device *tty_dev; ++ int may_wake = 0; ++ ++ /* Get the tty which could be NULL so don't assume it's valid */ ++ tty = tty_port_tty_get(&port->state->port); ++ if (tty) { ++ tty_dev = tty->dev; ++ may_wake = device_may_wakeup(tty_dev); ++ tty_kref_put(tty); ++ } ++ ++ if (console_suspend_enabled && !may_wake) { ++ struct xuartps *xuartps = port->private_data; ++ ++ clk_enable(xuartps->aperclk); ++ clk_enable(xuartps->refclk); ++ ++ spin_lock_irqsave(&port->lock, flags); ++ ++ /* Set TX/RX Reset */ ++ xuartps_writel(xuartps_readl(XUARTPS_CR_OFFSET) | ++ (XUARTPS_CR_TXRST | XUARTPS_CR_RXRST), ++ XUARTPS_CR_OFFSET); ++ while (xuartps_readl(XUARTPS_CR_OFFSET) & ++ (XUARTPS_CR_TXRST | XUARTPS_CR_RXRST)) ++ cpu_relax(); ++ ++ /* restore rx timeout value */ ++ xuartps_writel(rx_timeout, XUARTPS_RXTOUT_OFFSET); ++ /* Enable Tx/Rx */ ++ ctrl_reg = xuartps_readl(XUARTPS_CR_OFFSET); ++ xuartps_writel( ++ (ctrl_reg & ~(XUARTPS_CR_TX_DIS | XUARTPS_CR_RX_DIS)) | ++ (XUARTPS_CR_TX_EN | XUARTPS_CR_RX_EN), ++ XUARTPS_CR_OFFSET); ++ ++ spin_unlock_irqrestore(&port->lock, flags); ++ } else { ++ spin_lock_irqsave(&port->lock, flags); ++ /* restore original rx trigger level */ ++ xuartps_writel(rx_trigger_level, XUARTPS_RXWM_OFFSET); ++ /* enable RX timeout interrupt */ ++ xuartps_writel(XUARTPS_IXR_TOUT, XUARTPS_IER_OFFSET); ++ spin_unlock_irqrestore(&port->lock, flags); ++ } ++ ++ return uart_resume_port(&xuartps_uart_driver, port); ++} ++#endif /* ! CONFIG_PM_SLEEP */ ++ ++static SIMPLE_DEV_PM_OPS(xuartps_dev_pm_ops, xuartps_suspend, xuartps_resume); ++ + /** Structure Definitions + */ + static struct uart_driver xuartps_uart_driver = { +@@ -1348,6 +1461,7 @@ static struct platform_driver xuartps_platform_driver = { + .owner = THIS_MODULE, + .name = XUARTPS_NAME, /* Driver name */ + .of_match_table = xuartps_of_match, ++ .pm = &xuartps_dev_pm_ops, + }, + }; + +-- +1.8.5.rc3 + diff --git a/patches.zynq/0025-tty-xuartps-Update-copyright-information.patch b/patches.zynq/0025-tty-xuartps-Update-copyright-information.patch new file mode 100644 index 00000000000000..aa89898ad97787 --- /dev/null +++ b/patches.zynq/0025-tty-xuartps-Update-copyright-information.patch @@ -0,0 +1,30 @@ +From 2f9b1698a6b1a02f3aa6bc80d843341260c97915 Mon Sep 17 00:00:00 2001 +From: Soren Brinkmann <soren.brinkmann@xilinx.com> +Date: Thu, 17 Oct 2013 14:08:13 -0700 +Subject: tty: xuartps: Update copyright information + +Signed-off-by: Soren Brinkmann <soren.brinkmann@xilinx.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +(cherry picked from commit 37cd940b2044ca0c481e70742da37278a2d736ae) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + drivers/tty/serial/xilinx_uartps.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c +index 9ecd8ea4f3ae..c7c96c2f149c 100644 +--- a/drivers/tty/serial/xilinx_uartps.c ++++ b/drivers/tty/serial/xilinx_uartps.c +@@ -1,7 +1,7 @@ + /* + * Xilinx PS UART driver + * +- * 2011 (c) Xilinx Inc. ++ * 2011 - 2013 (C) Xilinx Inc. + * + * This program is free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public +-- +1.8.5.rc3 + diff --git a/patches.zynq/0026-tty-xuartps-Fix-may-be-used-uninitialized-build-warn.patch b/patches.zynq/0026-tty-xuartps-Fix-may-be-used-uninitialized-build-warn.patch new file mode 100644 index 00000000000000..cc954710bf2aae --- /dev/null +++ b/patches.zynq/0026-tty-xuartps-Fix-may-be-used-uninitialized-build-warn.patch @@ -0,0 +1,34 @@ +From 4cc7cfa290341d350951af60eb237a0bc4b8bb99 Mon Sep 17 00:00:00 2001 +From: Soren Brinkmann <soren.brinkmann@xilinx.com> +Date: Mon, 21 Oct 2013 16:40:59 -0700 +Subject: tty: xuartps: Fix "may be used uninitialized" build warning + +Initialize varibles for which a 'may be used uninitalized' warning is +issued. + +Signed-off-by: Soren Brinkmann <soren.brinkmann@xilinx.com> +Reported-by: kbuild test robot <fengguang.wu@intel.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +(cherry picked from commit d54b181ea65682914cae0430f2a1efcbb6517dba) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + drivers/tty/serial/xilinx_uartps.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c +index c7c96c2f149c..5ac6c480df43 100644 +--- a/drivers/tty/serial/xilinx_uartps.c ++++ b/drivers/tty/serial/xilinx_uartps.c +@@ -389,7 +389,7 @@ static unsigned int xuartps_set_baud_rate(struct uart_port *port, + unsigned int baud) + { + unsigned int calc_baud; +- u32 cd, bdiv; ++ u32 cd = 0, bdiv = 0; + u32 mreg; + int div8; + struct xuartps *xuartps = port->private_data; +-- +1.8.5.rc3 + diff --git a/patches.zynq/0027-tty-xuartps-Fix-build-error-due-to-missing-forward-d.patch b/patches.zynq/0027-tty-xuartps-Fix-build-error-due-to-missing-forward-d.patch new file mode 100644 index 00000000000000..b2daae9fd99b85 --- /dev/null +++ b/patches.zynq/0027-tty-xuartps-Fix-build-error-due-to-missing-forward-d.patch @@ -0,0 +1,70 @@ +From 34f391544b7f23c038293fff1b51a93e0cf3d598 Mon Sep 17 00:00:00 2001 +From: Soren Brinkmann <soren.brinkmann@xilinx.com> +Date: Mon, 21 Oct 2013 16:41:00 -0700 +Subject: tty: xuartps: Fix build error due to missing forward declaration + +If CONFIG_PM_SLEEP is enabled and CONFIG_SERIAL_XILINX_PS_UART_CONSOLE +is not, a forward declaration of the uart_driver struct is not +included, leading to a build error due to an undeclared variable. +Fixing this by moving the definition of the struct uart_driver before +the definition of the suspend/resume callbacks. + +Signed-off-by: Soren Brinkmann <soren.brinkmann@xilinx.com> +Reported-by: kbuild test robot <fengguang.wu@intel.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +(cherry picked from commit d3641f64bc71765682754722fd42fae24366bb3a) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + drivers/tty/serial/xilinx_uartps.c | 28 ++++++++++++++-------------- + 1 file changed, 14 insertions(+), 14 deletions(-) + +diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c +index 5ac6c480df43..ca4a2f1fbca9 100644 +--- a/drivers/tty/serial/xilinx_uartps.c ++++ b/drivers/tty/serial/xilinx_uartps.c +@@ -1198,6 +1198,20 @@ console_initcall(xuartps_console_init); + + #endif /* CONFIG_SERIAL_XILINX_PS_UART_CONSOLE */ + ++/** Structure Definitions ++ */ ++static struct uart_driver xuartps_uart_driver = { ++ .owner = THIS_MODULE, /* Owner */ ++ .driver_name = XUARTPS_NAME, /* Driver name */ ++ .dev_name = XUARTPS_TTY_NAME, /* Node name */ ++ .major = XUARTPS_MAJOR, /* Major number */ ++ .minor = XUARTPS_MINOR, /* Minor number */ ++ .nr = XUARTPS_NR_PORTS, /* Number of UART ports */ ++#ifdef CONFIG_SERIAL_XILINX_PS_UART_CONSOLE ++ .cons = &xuartps_console, /* Console */ ++#endif ++}; ++ + #ifdef CONFIG_PM_SLEEP + /** + * xuartps_suspend - suspend event +@@ -1311,20 +1325,6 @@ static int xuartps_resume(struct device *device) + + static SIMPLE_DEV_PM_OPS(xuartps_dev_pm_ops, xuartps_suspend, xuartps_resume); + +-/** Structure Definitions +- */ +-static struct uart_driver xuartps_uart_driver = { +- .owner = THIS_MODULE, /* Owner */ +- .driver_name = XUARTPS_NAME, /* Driver name */ +- .dev_name = XUARTPS_TTY_NAME, /* Node name */ +- .major = XUARTPS_MAJOR, /* Major number */ +- .minor = XUARTPS_MINOR, /* Minor number */ +- .nr = XUARTPS_NR_PORTS, /* Number of UART ports */ +-#ifdef CONFIG_SERIAL_XILINX_PS_UART_CONSOLE +- .cons = &xuartps_console, /* Console */ +-#endif +-}; +- + /* --------------------------------------------------------------------- + * Platform bus binding + */ +-- +1.8.5.rc3 + diff --git a/patches.zynq/0028-tty-xuartps-Fix-build-error-when-COMMON_CLK-is-not-s.patch b/patches.zynq/0028-tty-xuartps-Fix-build-error-when-COMMON_CLK-is-not-s.patch new file mode 100644 index 00000000000000..6921786226d73f --- /dev/null +++ b/patches.zynq/0028-tty-xuartps-Fix-build-error-when-COMMON_CLK-is-not-s.patch @@ -0,0 +1,78 @@ +From 987416b050d5a2866459fae75ee599bb2bb5e903 Mon Sep 17 00:00:00 2001 +From: Soren Brinkmann <soren.brinkmann@xilinx.com> +Date: Mon, 21 Oct 2013 16:41:01 -0700 +Subject: tty: xuartps: Fix build error when COMMON_CLK is not set + +Clock notifiers are only available when CONFIG_COMMON_CLK is enabled. +Hence all notifier related code has to be protected by corresponsing +ifdefs. + +Signed-off-by: Soren Brinkmann <soren.brinkmann@xilinx.com> +Reported-by: kbuild test robot <fengguang.wu@intel.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +(cherry picked from commit 7ac57347c23de6b6fcaf8f0a1f91067cedea57bc) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + drivers/tty/serial/xilinx_uartps.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c +index ca4a2f1fbca9..e46e9f3f19b9 100644 +--- a/drivers/tty/serial/xilinx_uartps.c ++++ b/drivers/tty/serial/xilinx_uartps.c +@@ -411,6 +411,7 @@ static unsigned int xuartps_set_baud_rate(struct uart_port *port, + return calc_baud; + } + ++#ifdef CONFIG_COMMON_CLK + /** + * xuartps_clk_notitifer_cb - Clock notifier callback + * @nb: Notifier block +@@ -504,6 +505,7 @@ static int xuartps_clk_notifier_cb(struct notifier_block *nb, + return NOTIFY_DONE; + } + } ++#endif + + /*----------------------Uart Operations---------------------------*/ + +@@ -1380,11 +1382,13 @@ static int xuartps_probe(struct platform_device *pdev) + goto err_out_clk_disable; + } + ++#ifdef CONFIG_COMMON_CLK + xuartps_data->clk_rate_change_nb.notifier_call = + xuartps_clk_notifier_cb; + if (clk_notifier_register(xuartps_data->refclk, + &xuartps_data->clk_rate_change_nb)) + dev_warn(&pdev->dev, "Unable to register clock notifier.\n"); ++#endif + + /* Initialize the port structure */ + port = xuartps_get_port(); +@@ -1415,8 +1419,10 @@ static int xuartps_probe(struct platform_device *pdev) + } + + err_out_notif_unreg: ++#ifdef CONFIG_COMMON_CLK + clk_notifier_unregister(xuartps_data->refclk, + &xuartps_data->clk_rate_change_nb); ++#endif + err_out_clk_disable: + clk_disable_unprepare(xuartps_data->refclk); + err_out_clk_dis_aper: +@@ -1438,8 +1444,10 @@ static int xuartps_remove(struct platform_device *pdev) + int rc; + + /* Remove the xuartps port from the serial core */ ++#ifdef CONFIG_COMMON_CLK + clk_notifier_unregister(xuartps_data->refclk, + &xuartps_data->clk_rate_change_nb); ++#endif + rc = uart_remove_one_port(&xuartps_uart_driver, port); + port->mapbase = 0; + clk_disable_unprepare(xuartps_data->refclk); +-- +1.8.5.rc3 + diff --git a/patches.zynq/0029-GPIO-xilinx-Simplify-driver-probe-function.patch b/patches.zynq/0029-GPIO-xilinx-Simplify-driver-probe-function.patch new file mode 100644 index 00000000000000..94709b7134c2ee --- /dev/null +++ b/patches.zynq/0029-GPIO-xilinx-Simplify-driver-probe-function.patch @@ -0,0 +1,60 @@ +From 60a225735b974232b7b1e0dcce1f2812af26c09d Mon Sep 17 00:00:00 2001 +From: Michal Simek <michal.simek@xilinx.com> +Date: Mon, 3 Jun 2013 14:31:16 +0200 +Subject: GPIO: xilinx: Simplify driver probe function + +Simplification is done by using OF helper function +which increase readability of code and remove +(if (var) var = be32_to_cpup;) assignment. + +Signed-off-by: Michal Simek <michal.simek@xilinx.com> +Signed-off-by: Linus Walleij <linus.walleij@linaro.org> +(cherry picked from commit 6f8bf50031a68f533ae7eba3d3277c38ee7806f5) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + drivers/gpio/gpio-xilinx.c | 24 ++++++++++-------------- + 1 file changed, 10 insertions(+), 14 deletions(-) + +diff --git a/drivers/gpio/gpio-xilinx.c b/drivers/gpio/gpio-xilinx.c +index 9ae7aa8ca48a..2aad53497a63 100644 +--- a/drivers/gpio/gpio-xilinx.c ++++ b/drivers/gpio/gpio-xilinx.c +@@ -170,24 +170,20 @@ static int xgpio_of_probe(struct device_node *np) + return -ENOMEM; + + /* Update GPIO state shadow register with default value */ +- tree_info = of_get_property(np, "xlnx,dout-default", NULL); +- if (tree_info) +- chip->gpio_state = be32_to_cpup(tree_info); ++ of_property_read_u32(np, "xlnx,dout-default", &chip->gpio_state); ++ ++ /* By default, all pins are inputs */ ++ chip->gpio_dir = 0xFFFFFFFF; + + /* Update GPIO direction shadow register with default value */ +- chip->gpio_dir = 0xFFFFFFFF; /* By default, all pins are inputs */ +- tree_info = of_get_property(np, "xlnx,tri-default", NULL); +- if (tree_info) +- chip->gpio_dir = be32_to_cpup(tree_info); ++ of_property_read_u32(np, "xlnx,tri-default", &chip->gpio_dir); ++ ++ /* By default assume full GPIO controller */ ++ chip->mmchip.gc.ngpio = 32; + + /* Check device node and parent device node for device width */ +- chip->mmchip.gc.ngpio = 32; /* By default assume full GPIO controller */ +- tree_info = of_get_property(np, "xlnx,gpio-width", NULL); +- if (!tree_info) +- tree_info = of_get_property(np->parent, +- "xlnx,gpio-width", NULL); +- if (tree_info) +- chip->mmchip.gc.ngpio = be32_to_cpup(tree_info); ++ of_property_read_u32(np, "xlnx,gpio-width", ++ (u32 *)&chip->mmchip.gc.ngpio); + + spin_lock_init(&chip->gpio_lock); + +-- +1.8.5.rc3 + diff --git a/patches.zynq/0030-GPIO-xilinx-Add-support-for-dual-channel.patch b/patches.zynq/0030-GPIO-xilinx-Add-support-for-dual-channel.patch new file mode 100644 index 00000000000000..1dc40d12346a1a --- /dev/null +++ b/patches.zynq/0030-GPIO-xilinx-Add-support-for-dual-channel.patch @@ -0,0 +1,215 @@ +From 182740a085e83bd94a291554eee572946ada657e Mon Sep 17 00:00:00 2001 +From: Michal Simek <michal.simek@xilinx.com> +Date: Mon, 3 Jun 2013 14:31:17 +0200 +Subject: GPIO: xilinx: Add support for dual channel + +Supporting the second channel in the driver. +Offset is 0x8 and both channnels share the same +IRQ. + +Signed-off-by: Michal Simek <michal.simek@xilinx.com> +Signed-off-by: Linus Walleij <linus.walleij@linaro.org> +(cherry picked from commit 74600ee017557b2ebb669e45237f655e9e2fbac8) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + drivers/gpio/gpio-xilinx.c | 103 +++++++++++++++++++++++++++++++++++++++------ + 1 file changed, 91 insertions(+), 12 deletions(-) + +diff --git a/drivers/gpio/gpio-xilinx.c b/drivers/gpio/gpio-xilinx.c +index 2aad53497a63..626eaa876f09 100644 +--- a/drivers/gpio/gpio-xilinx.c ++++ b/drivers/gpio/gpio-xilinx.c +@@ -1,7 +1,7 @@ + /* +- * Xilinx gpio driver ++ * Xilinx gpio driver for xps/axi_gpio IP. + * +- * Copyright 2008 Xilinx, Inc. ++ * Copyright 2008 - 2013 Xilinx, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 +@@ -12,6 +12,7 @@ + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + ++#include <linux/bitops.h> + #include <linux/init.h> + #include <linux/errno.h> + #include <linux/module.h> +@@ -26,11 +27,26 @@ + #define XGPIO_DATA_OFFSET (0x0) /* Data register */ + #define XGPIO_TRI_OFFSET (0x4) /* I/O direction register */ + ++#define XGPIO_CHANNEL_OFFSET 0x8 ++ ++/* Read/Write access to the GPIO registers */ ++#define xgpio_readreg(offset) in_be32(offset) ++#define xgpio_writereg(offset, val) out_be32(offset, val) ++ ++/** ++ * struct xgpio_instance - Stores information about GPIO device ++ * struct of_mm_gpio_chip mmchip: OF GPIO chip for memory mapped banks ++ * gpio_state: GPIO state shadow register ++ * gpio_dir: GPIO direction shadow register ++ * offset: GPIO channel offset ++ * gpio_lock: Lock used for synchronization ++ */ + struct xgpio_instance { + struct of_mm_gpio_chip mmchip; +- u32 gpio_state; /* GPIO state shadow register */ +- u32 gpio_dir; /* GPIO direction shadow register */ +- spinlock_t gpio_lock; /* Lock used for synchronization */ ++ u32 gpio_state; ++ u32 gpio_dir; ++ u32 offset; ++ spinlock_t gpio_lock; + }; + + /** +@@ -44,8 +60,12 @@ struct xgpio_instance { + static int xgpio_get(struct gpio_chip *gc, unsigned int gpio) + { + struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); ++ struct xgpio_instance *chip = ++ container_of(mm_gc, struct xgpio_instance, mmchip); + +- return (in_be32(mm_gc->regs + XGPIO_DATA_OFFSET) >> gpio) & 1; ++ void __iomem *regs = mm_gc->regs + chip->offset; ++ ++ return !!(xgpio_readreg(regs + XGPIO_DATA_OFFSET) & BIT(gpio)); + } + + /** +@@ -63,6 +83,7 @@ static void xgpio_set(struct gpio_chip *gc, unsigned int gpio, int val) + struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); + struct xgpio_instance *chip = + container_of(mm_gc, struct xgpio_instance, mmchip); ++ void __iomem *regs = mm_gc->regs; + + spin_lock_irqsave(&chip->gpio_lock, flags); + +@@ -71,7 +92,9 @@ static void xgpio_set(struct gpio_chip *gc, unsigned int gpio, int val) + chip->gpio_state |= 1 << gpio; + else + chip->gpio_state &= ~(1 << gpio); +- out_be32(mm_gc->regs + XGPIO_DATA_OFFSET, chip->gpio_state); ++ ++ xgpio_writereg(regs + chip->offset + XGPIO_DATA_OFFSET, ++ chip->gpio_state); + + spin_unlock_irqrestore(&chip->gpio_lock, flags); + } +@@ -91,12 +114,13 @@ static int xgpio_dir_in(struct gpio_chip *gc, unsigned int gpio) + struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); + struct xgpio_instance *chip = + container_of(mm_gc, struct xgpio_instance, mmchip); ++ void __iomem *regs = mm_gc->regs; + + spin_lock_irqsave(&chip->gpio_lock, flags); + + /* Set the GPIO bit in shadow register and set direction as input */ + chip->gpio_dir |= (1 << gpio); +- out_be32(mm_gc->regs + XGPIO_TRI_OFFSET, chip->gpio_dir); ++ xgpio_writereg(regs + chip->offset + XGPIO_TRI_OFFSET, chip->gpio_dir); + + spin_unlock_irqrestore(&chip->gpio_lock, flags); + +@@ -119,6 +143,7 @@ static int xgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) + struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); + struct xgpio_instance *chip = + container_of(mm_gc, struct xgpio_instance, mmchip); ++ void __iomem *regs = mm_gc->regs; + + spin_lock_irqsave(&chip->gpio_lock, flags); + +@@ -127,11 +152,12 @@ static int xgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) + chip->gpio_state |= 1 << gpio; + else + chip->gpio_state &= ~(1 << gpio); +- out_be32(mm_gc->regs + XGPIO_DATA_OFFSET, chip->gpio_state); ++ xgpio_writereg(regs + chip->offset + XGPIO_DATA_OFFSET, ++ chip->gpio_state); + + /* Clear the GPIO bit in shadow register and set direction as output */ + chip->gpio_dir &= (~(1 << gpio)); +- out_be32(mm_gc->regs + XGPIO_TRI_OFFSET, chip->gpio_dir); ++ xgpio_writereg(regs + chip->offset + XGPIO_TRI_OFFSET, chip->gpio_dir); + + spin_unlock_irqrestore(&chip->gpio_lock, flags); + +@@ -147,8 +173,10 @@ static void xgpio_save_regs(struct of_mm_gpio_chip *mm_gc) + struct xgpio_instance *chip = + container_of(mm_gc, struct xgpio_instance, mmchip); + +- out_be32(mm_gc->regs + XGPIO_DATA_OFFSET, chip->gpio_state); +- out_be32(mm_gc->regs + XGPIO_TRI_OFFSET, chip->gpio_dir); ++ xgpio_writereg(mm_gc->regs + chip->offset + XGPIO_DATA_OFFSET, ++ chip->gpio_state); ++ xgpio_writereg(mm_gc->regs + chip->offset + XGPIO_TRI_OFFSET, ++ chip->gpio_dir); + } + + /** +@@ -202,6 +230,57 @@ static int xgpio_of_probe(struct device_node *np) + np->full_name, status); + return status; + } ++ ++ pr_info("XGpio: %s: registered, base is %d\n", np->full_name, ++ chip->mmchip.gc.base); ++ ++ tree_info = of_get_property(np, "xlnx,is-dual", NULL); ++ if (tree_info && be32_to_cpup(tree_info)) { ++ chip = kzalloc(sizeof(*chip), GFP_KERNEL); ++ if (!chip) ++ return -ENOMEM; ++ ++ /* Add dual channel offset */ ++ chip->offset = XGPIO_CHANNEL_OFFSET; ++ ++ /* Update GPIO state shadow register with default value */ ++ of_property_read_u32(np, "xlnx,dout-default-2", ++ &chip->gpio_state); ++ ++ /* By default, all pins are inputs */ ++ chip->gpio_dir = 0xFFFFFFFF; ++ ++ /* Update GPIO direction shadow register with default value */ ++ of_property_read_u32(np, "xlnx,tri-default-2", &chip->gpio_dir); ++ ++ /* By default assume full GPIO controller */ ++ chip->mmchip.gc.ngpio = 32; ++ ++ /* Check device node and parent device node for device width */ ++ of_property_read_u32(np, "xlnx,gpio2-width", ++ (u32 *)&chip->mmchip.gc.ngpio); ++ ++ spin_lock_init(&chip->gpio_lock); ++ ++ chip->mmchip.gc.direction_input = xgpio_dir_in; ++ chip->mmchip.gc.direction_output = xgpio_dir_out; ++ chip->mmchip.gc.get = xgpio_get; ++ chip->mmchip.gc.set = xgpio_set; ++ ++ chip->mmchip.save_regs = xgpio_save_regs; ++ ++ /* Call the OF gpio helper to setup and register the GPIO dev */ ++ status = of_mm_gpiochip_add(np, &chip->mmchip); ++ if (status) { ++ kfree(chip); ++ pr_err("%s: error in probe function with status %d\n", ++ np->full_name, status); ++ return status; ++ } ++ pr_info("XGpio: %s: dual channel registered, base is %d\n", ++ np->full_name, chip->mmchip.gc.base); ++ } ++ + return 0; + } + +-- +1.8.5.rc3 + diff --git a/patches.zynq/0031-GPIO-xilinx-Use-__raw_readl-__raw_writel-IO-function.patch b/patches.zynq/0031-GPIO-xilinx-Use-__raw_readl-__raw_writel-IO-function.patch new file mode 100644 index 00000000000000..767acc3524e388 --- /dev/null +++ b/patches.zynq/0031-GPIO-xilinx-Use-__raw_readl-__raw_writel-IO-function.patch @@ -0,0 +1,49 @@ +From bd45cfaebc9d2b27a8d6ba0395e91500129f9f78 Mon Sep 17 00:00:00 2001 +From: Michal Simek <michal.simek@xilinx.com> +Date: Mon, 3 Jun 2013 14:31:18 +0200 +Subject: GPIO: xilinx: Use __raw_readl/__raw_writel IO functions + +This driver can be used on Xilinx ARM Zynq platform +where in_be32/out_be32 functions are not implemented. +Use __raw_readl/__raw_writel functions which are +implemented on Microblaze and PowerPC. +For ARM readl/writel functions are used instead. + +The correct way how to implement this is to detect +endians directly on IP. But for the gpio case +without interrupt connected(it means without +interrupt logic) there are just 2 registers +data and tristate where auto detection can't be done. + +Signed-off-by: Michal Simek <michal.simek@xilinx.com> +Signed-off-by: Linus Walleij <linus.walleij@linaro.org> +(cherry picked from commit cc090d61d1a88f30f2fb75a91bce684ad1bd2e94) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + drivers/gpio/gpio-xilinx.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpio/gpio-xilinx.c b/drivers/gpio/gpio-xilinx.c +index 626eaa876f09..791ddaedbfb4 100644 +--- a/drivers/gpio/gpio-xilinx.c ++++ b/drivers/gpio/gpio-xilinx.c +@@ -30,8 +30,13 @@ + #define XGPIO_CHANNEL_OFFSET 0x8 + + /* Read/Write access to the GPIO registers */ +-#define xgpio_readreg(offset) in_be32(offset) +-#define xgpio_writereg(offset, val) out_be32(offset, val) ++#ifdef CONFIG_ARCH_ZYNQ ++# define xgpio_readreg(offset) readl(offset) ++# define xgpio_writereg(offset, val) writel(val, offset) ++#else ++# define xgpio_readreg(offset) __raw_readl(offset) ++# define xgpio_writereg(offset, val) __raw_writel(val, offset) ++#endif + + /** + * struct xgpio_instance - Stores information about GPIO device +-- +1.8.5.rc3 + diff --git a/patches.zynq/0032-GPIO-xilinx-Use-BIT-macro.patch b/patches.zynq/0032-GPIO-xilinx-Use-BIT-macro.patch new file mode 100644 index 00000000000000..672380f113761f --- /dev/null +++ b/patches.zynq/0032-GPIO-xilinx-Use-BIT-macro.patch @@ -0,0 +1,62 @@ +From 2fb27a6b5067c894c64152bc57d08def0ccfb530 Mon Sep 17 00:00:00 2001 +From: Michal Simek <michal.simek@xilinx.com> +Date: Mon, 3 Jun 2013 14:31:19 +0200 +Subject: GPIO: xilinx: Use BIT macro + +Use BIT macro from linux/bitops.h. + +Signed-off-by: Michal Simek <michal.simek@xilinx.com> +Signed-off-by: Linus Walleij <linus.walleij@linaro.org> +(cherry picked from commit 9f7f0b2bbcff719233e6724d756a8c93d3285ade) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + drivers/gpio/gpio-xilinx.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/drivers/gpio/gpio-xilinx.c b/drivers/gpio/gpio-xilinx.c +index 791ddaedbfb4..792a05ad4649 100644 +--- a/drivers/gpio/gpio-xilinx.c ++++ b/drivers/gpio/gpio-xilinx.c +@@ -94,9 +94,9 @@ static void xgpio_set(struct gpio_chip *gc, unsigned int gpio, int val) + + /* Write to GPIO signal and set its direction to output */ + if (val) +- chip->gpio_state |= 1 << gpio; ++ chip->gpio_state |= BIT(gpio); + else +- chip->gpio_state &= ~(1 << gpio); ++ chip->gpio_state &= ~BIT(gpio); + + xgpio_writereg(regs + chip->offset + XGPIO_DATA_OFFSET, + chip->gpio_state); +@@ -124,7 +124,7 @@ static int xgpio_dir_in(struct gpio_chip *gc, unsigned int gpio) + spin_lock_irqsave(&chip->gpio_lock, flags); + + /* Set the GPIO bit in shadow register and set direction as input */ +- chip->gpio_dir |= (1 << gpio); ++ chip->gpio_dir |= BIT(gpio); + xgpio_writereg(regs + chip->offset + XGPIO_TRI_OFFSET, chip->gpio_dir); + + spin_unlock_irqrestore(&chip->gpio_lock, flags); +@@ -154,14 +154,14 @@ static int xgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) + + /* Write state of GPIO signal */ + if (val) +- chip->gpio_state |= 1 << gpio; ++ chip->gpio_state |= BIT(gpio); + else +- chip->gpio_state &= ~(1 << gpio); ++ chip->gpio_state &= ~BIT(gpio); + xgpio_writereg(regs + chip->offset + XGPIO_DATA_OFFSET, + chip->gpio_state); + + /* Clear the GPIO bit in shadow register and set direction as output */ +- chip->gpio_dir &= (~(1 << gpio)); ++ chip->gpio_dir &= ~BIT(gpio); + xgpio_writereg(regs + chip->offset + XGPIO_TRI_OFFSET, chip->gpio_dir); + + spin_unlock_irqrestore(&chip->gpio_lock, flags); +-- +1.8.5.rc3 + diff --git a/patches.zynq/0033-arm-dt-zynq-Use-status-property-for-UART-nodes.patch b/patches.zynq/0033-arm-dt-zynq-Use-status-property-for-UART-nodes.patch new file mode 100644 index 00000000000000..67ce2a61dd6596 --- /dev/null +++ b/patches.zynq/0033-arm-dt-zynq-Use-status-property-for-UART-nodes.patch @@ -0,0 +1,59 @@ +From 10cc62facb9705eddcce5f684e89430deb641923 Mon Sep 17 00:00:00 2001 +From: Soren Brinkmann <soren.brinkmann@xilinx.com> +Date: Thu, 13 Jun 2013 09:37:16 -0700 +Subject: arm: dt: zynq: Use 'status' property for UART nodes + +Set the default status for UARTs to disabled in the zynq-7000.dtsi file +and let board dts files enable the UARTs on demand. + +Signed-off-by: Soren Brinkmann <soren.brinkmann@xilinx.com> +Reviewed-by: Steffen Trumtrar <s.trumtrar@pengutronix.de> +Signed-off-by: Michal Simek <michal.simek@xilinx.com> +(cherry picked from commit ec11ebcf2fab2d367e18c45712f7216aa6452243) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + arch/arm/boot/dts/zynq-7000.dtsi | 2 ++ + arch/arm/boot/dts/zynq-zc702.dts | 6 +++++- + 2 files changed, 7 insertions(+), 1 deletion(-) + +diff --git a/arch/arm/boot/dts/zynq-7000.dtsi b/arch/arm/boot/dts/zynq-7000.dtsi +index 952b61d39b0a..713ba2adc76c 100644 +--- a/arch/arm/boot/dts/zynq-7000.dtsi ++++ b/arch/arm/boot/dts/zynq-7000.dtsi +@@ -49,6 +49,7 @@ + + uart0: uart@e0000000 { + compatible = "xlnx,xuartps"; ++ status = "disabled"; + clocks = <&clkc 23>, <&clkc 40>; + clock-names = "ref_clk", "aper_clk"; + reg = <0xE0000000 0x1000>; +@@ -57,6 +58,7 @@ + + uart1: uart@e0001000 { + compatible = "xlnx,xuartps"; ++ status = "disabled"; + clocks = <&clkc 24>, <&clkc 41>; + clock-names = "ref_clk", "aper_clk"; + reg = <0xE0001000 0x1000>; +diff --git a/arch/arm/boot/dts/zynq-zc702.dts b/arch/arm/boot/dts/zynq-zc702.dts +index e25a307438ad..21aea99a067b 100644 +--- a/arch/arm/boot/dts/zynq-zc702.dts ++++ b/arch/arm/boot/dts/zynq-zc702.dts +@@ -24,7 +24,11 @@ + }; + + chosen { +- bootargs = "console=ttyPS1,115200 earlyprintk"; ++ bootargs = "console=ttyPS0,115200 earlyprintk"; + }; + + }; ++ ++&uart1 { ++ status = "okay"; ++}; +-- +1.8.5.rc3 + diff --git a/patches.zynq/0034-arm-zynq-dt-Set-correct-L2-ram-latencies.patch b/patches.zynq/0034-arm-zynq-dt-Set-correct-L2-ram-latencies.patch new file mode 100644 index 00000000000000..edec022422724a --- /dev/null +++ b/patches.zynq/0034-arm-zynq-dt-Set-correct-L2-ram-latencies.patch @@ -0,0 +1,32 @@ +From 29dc40ba4b009e2b3e5fa1feb9bfb148af3aa7f7 Mon Sep 17 00:00:00 2001 +From: Soren Brinkmann <soren.brinkmann@xilinx.com> +Date: Wed, 31 Jul 2013 16:24:59 -0700 +Subject: arm: zynq: dt: Set correct L2 ram latencies + +Signed-off-by: Soren Brinkmann <soren.brinkmann@xilinx.com> +Signed-off-by: Michal Simek <michal.simek@xilinx.com> +(cherry picked from commit 39c41df9c1950fba0ee6a4e7a63be281e89fe437) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + arch/arm/boot/dts/zynq-7000.dtsi | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/arch/arm/boot/dts/zynq-7000.dtsi b/arch/arm/boot/dts/zynq-7000.dtsi +index 713ba2adc76c..e7f73b2e4550 100644 +--- a/arch/arm/boot/dts/zynq-7000.dtsi ++++ b/arch/arm/boot/dts/zynq-7000.dtsi +@@ -41,8 +41,8 @@ + L2: cache-controller { + compatible = "arm,pl310-cache"; + reg = <0xF8F02000 0x1000>; +- arm,data-latency = <2 3 2>; +- arm,tag-latency = <2 3 2>; ++ arm,data-latency = <3 2 2>; ++ arm,tag-latency = <2 2 2>; + cache-unified; + cache-level = <2>; + }; +-- +1.8.5.rc3 + diff --git a/patches.zynq/0035-clk-zynq-Add-clock-controller-driver.patch b/patches.zynq/0035-clk-zynq-Add-clock-controller-driver.patch new file mode 100644 index 00000000000000..f4af10e600ac1e --- /dev/null +++ b/patches.zynq/0035-clk-zynq-Add-clock-controller-driver.patch @@ -0,0 +1,674 @@ +From 31b50f8cf40690de284a7694ba19676e96d8c1d8 Mon Sep 17 00:00:00 2001 +From: Soren Brinkmann <soren.brinkmann@xilinx.com> +Date: Mon, 13 May 2013 10:46:37 -0700 +Subject: clk: zynq: Add clock controller driver + +Add a clock controller driver and documentation. + +Signed-off-by: Soren Brinkmann <soren.brinkmann@xilinx.com> +Cc: Grant Likely <grant.likely@linaro.org> +Cc: Rob Herring <rob.herring@calxeda.com> +Cc: Rob Landley <rob@landley.net> +Cc: devicetree-discuss@lists.ozlabs.org +Cc: linux-doc@vger.kernel.org +Signed-off-by: Michal Simek <michal.simek@xilinx.com> +Acked-by: Mike Turquette <mturquette@linaro.org> +(cherry picked from commit 0ee52b157b8ed88550ddd6291e54bb4bfabde364) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + .../devicetree/bindings/clock/zynq-7000.txt | 97 ++++ + drivers/clk/zynq/clkc.c | 533 +++++++++++++++++++++ + 2 files changed, 630 insertions(+) + create mode 100644 drivers/clk/zynq/clkc.c + +diff --git a/Documentation/devicetree/bindings/clock/zynq-7000.txt b/Documentation/devicetree/bindings/clock/zynq-7000.txt +index 23ae1db1bc13..1049a313933c 100644 +--- a/Documentation/devicetree/bindings/clock/zynq-7000.txt ++++ b/Documentation/devicetree/bindings/clock/zynq-7000.txt +@@ -6,6 +6,103 @@ The purpose of this document is to document their usage. + See clock_bindings.txt for more information on the generic clock bindings. + See Chapter 25 of Zynq TRM for more information about Zynq clocks. + ++== Clock Controller == ++The clock controller is a logical abstraction of Zynq's clock tree. It reads ++required input clock frequencies from the devicetree and acts as clock provider ++for all clock consumers of PS clocks. ++ ++Required properties: ++ - #clock-cells : Must be 1 ++ - compatible : "xlnx,ps7-clkc" ++ - ps-clk-frequency : Frequency of the oscillator providing ps_clk in HZ ++ (usually 33 MHz oscillators are used for Zynq platforms) ++ - clock-output-names : List of strings used to name the clock outputs. Shall be ++ a list of the outputs given below. ++ ++Optional properties: ++ - clocks : as described in the clock bindings ++ - clock-names : as described in the clock bindings ++ ++Clock inputs: ++The following strings are optional parameters to the 'clock-names' property in ++order to provide an optional (E)MIO clock source. ++ - swdt_ext_clk ++ - gem0_emio_clk ++ - gem1_emio_clk ++ - mio_clk_XX # with XX = 00..53 ++... ++ ++Clock outputs: ++ 0: armpll ++ 1: ddrpll ++ 2: iopll ++ 3: cpu_6or4x ++ 4: cpu_3or2x ++ 5: cpu_2x ++ 6: cpu_1x ++ 7: ddr2x ++ 8: ddr3x ++ 9: dci ++ 10: lqspi ++ 11: smc ++ 12: pcap ++ 13: gem0 ++ 14: gem1 ++ 15: fclk0 ++ 16: fclk1 ++ 17: fclk2 ++ 18: fclk3 ++ 19: can0 ++ 20: can1 ++ 21: sdio0 ++ 22: sdio1 ++ 23: uart0 ++ 24: uart1 ++ 25: spi0 ++ 26: spi1 ++ 27: dma ++ 28: usb0_aper ++ 29: usb1_aper ++ 30: gem0_aper ++ 31: gem1_aper ++ 32: sdio0_aper ++ 33: sdio1_aper ++ 34: spi0_aper ++ 35: spi1_aper ++ 36: can0_aper ++ 37: can1_aper ++ 38: i2c0_aper ++ 39: i2c1_aper ++ 40: uart0_aper ++ 41: uart1_aper ++ 42: gpio_aper ++ 43: lqspi_aper ++ 44: smc_aper ++ 45: swdt ++ 46: dbg_trc ++ 47: dbg_apb ++ ++Example: ++ clkc: clkc { ++ #clock-cells = <1>; ++ compatible = "xlnx,ps7-clkc"; ++ ps-clk-frequency = <33333333>; ++ clock-output-names = "armpll", "ddrpll", "iopll", "cpu_6or4x", ++ "cpu_3or2x", "cpu_2x", "cpu_1x", "ddr2x", "ddr3x", ++ "dci", "lqspi", "smc", "pcap", "gem0", "gem1", ++ "fclk0", "fclk1", "fclk2", "fclk3", "can0", "can1", ++ "sdio0", "sdio1", "uart0", "uart1", "spi0", "spi1", ++ "dma", "usb0_aper", "usb1_aper", "gem0_aper", ++ "gem1_aper", "sdio0_aper", "sdio1_aper", ++ "spi0_aper", "spi1_aper", "can0_aper", "can1_aper", ++ "i2c0_aper", "i2c1_aper", "uart0_aper", "uart1_aper", ++ "gpio_aper", "lqspi_aper", "smc_aper", "swdt", ++ "dbg_trc", "dbg_apb"; ++ # optional props ++ clocks = <&clkc 16>, <&clk_foo>; ++ clock-names = "gem1_emio_clk", "can_mio_clk_23"; ++ }; ++ + == PLLs == + + Used to describe the ARM_PLL, DDR_PLL, and IO_PLL. +diff --git a/drivers/clk/zynq/clkc.c b/drivers/clk/zynq/clkc.c +new file mode 100644 +index 000000000000..5c205b60a82a +--- /dev/null ++++ b/drivers/clk/zynq/clkc.c +@@ -0,0 +1,533 @@ ++/* ++ * Zynq clock controller ++ * ++ * Copyright (C) 2012 - 2013 Xilinx ++ * ++ * Sören Brinkmann <soren.brinkmann@xilinx.com> ++ * ++ * This program is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License v2 as published by ++ * the Free Software Foundation. ++ * ++ * 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, see <http://www.gnu.org/licenses/>. ++ */ ++ ++#include <linux/clk/zynq.h> ++#include <linux/clk-provider.h> ++#include <linux/of.h> ++#include <linux/slab.h> ++#include <linux/string.h> ++#include <linux/io.h> ++ ++static void __iomem *zynq_slcr_base_priv; ++ ++#define SLCR_ARMPLL_CTRL (zynq_slcr_base_priv + 0x100) ++#define SLCR_DDRPLL_CTRL (zynq_slcr_base_priv + 0x104) ++#define SLCR_IOPLL_CTRL (zynq_slcr_base_priv + 0x108) ++#define SLCR_PLL_STATUS (zynq_slcr_base_priv + 0x10c) ++#define SLCR_ARM_CLK_CTRL (zynq_slcr_base_priv + 0x120) ++#define SLCR_DDR_CLK_CTRL (zynq_slcr_base_priv + 0x124) ++#define SLCR_DCI_CLK_CTRL (zynq_slcr_base_priv + 0x128) ++#define SLCR_APER_CLK_CTRL (zynq_slcr_base_priv + 0x12c) ++#define SLCR_GEM0_CLK_CTRL (zynq_slcr_base_priv + 0x140) ++#define SLCR_GEM1_CLK_CTRL (zynq_slcr_base_priv + 0x144) ++#define SLCR_SMC_CLK_CTRL (zynq_slcr_base_priv + 0x148) ++#define SLCR_LQSPI_CLK_CTRL (zynq_slcr_base_priv + 0x14c) ++#define SLCR_SDIO_CLK_CTRL (zynq_slcr_base_priv + 0x150) ++#define SLCR_UART_CLK_CTRL (zynq_slcr_base_priv + 0x154) ++#define SLCR_SPI_CLK_CTRL (zynq_slcr_base_priv + 0x158) ++#define SLCR_CAN_CLK_CTRL (zynq_slcr_base_priv + 0x15c) ++#define SLCR_CAN_MIOCLK_CTRL (zynq_slcr_base_priv + 0x160) ++#define SLCR_DBG_CLK_CTRL (zynq_slcr_base_priv + 0x164) ++#define SLCR_PCAP_CLK_CTRL (zynq_slcr_base_priv + 0x168) ++#define SLCR_FPGA0_CLK_CTRL (zynq_slcr_base_priv + 0x170) ++#define SLCR_621_TRUE (zynq_slcr_base_priv + 0x1c4) ++#define SLCR_SWDT_CLK_SEL (zynq_slcr_base_priv + 0x304) ++ ++#define NUM_MIO_PINS 54 ++ ++enum zynq_clk { ++ armpll, ddrpll, iopll, ++ cpu_6or4x, cpu_3or2x, cpu_2x, cpu_1x, ++ ddr2x, ddr3x, dci, ++ lqspi, smc, pcap, gem0, gem1, fclk0, fclk1, fclk2, fclk3, can0, can1, ++ sdio0, sdio1, uart0, uart1, spi0, spi1, dma, ++ usb0_aper, usb1_aper, gem0_aper, gem1_aper, ++ sdio0_aper, sdio1_aper, spi0_aper, spi1_aper, can0_aper, can1_aper, ++ i2c0_aper, i2c1_aper, uart0_aper, uart1_aper, gpio_aper, lqspi_aper, ++ smc_aper, swdt, dbg_trc, dbg_apb, clk_max}; ++ ++static struct clk *ps_clk; ++static struct clk *clks[clk_max]; ++static struct clk_onecell_data clk_data; ++ ++static DEFINE_SPINLOCK(armpll_lock); ++static DEFINE_SPINLOCK(ddrpll_lock); ++static DEFINE_SPINLOCK(iopll_lock); ++static DEFINE_SPINLOCK(armclk_lock); ++static DEFINE_SPINLOCK(ddrclk_lock); ++static DEFINE_SPINLOCK(dciclk_lock); ++static DEFINE_SPINLOCK(gem0clk_lock); ++static DEFINE_SPINLOCK(gem1clk_lock); ++static DEFINE_SPINLOCK(canclk_lock); ++static DEFINE_SPINLOCK(canmioclk_lock); ++static DEFINE_SPINLOCK(dbgclk_lock); ++static DEFINE_SPINLOCK(aperclk_lock); ++ ++static const char dummy_nm[] __initconst = "dummy_name"; ++ ++static const char *armpll_parents[] __initdata = {"armpll_int", "ps_clk"}; ++static const char *ddrpll_parents[] __initdata = {"ddrpll_int", "ps_clk"}; ++static const char *iopll_parents[] __initdata = {"iopll_int", "ps_clk"}; ++static const char *gem0_mux_parents[] __initdata = {"gem0_div1", dummy_nm}; ++static const char *gem1_mux_parents[] __initdata = {"gem1_div1", dummy_nm}; ++static const char *can0_mio_mux2_parents[] __initdata = {"can0_gate", ++ "can0_mio_mux"}; ++static const char *can1_mio_mux2_parents[] __initdata = {"can1_gate", ++ "can1_mio_mux"}; ++static const char *dbg_emio_mux_parents[] __initdata = {"dbg_div", ++ dummy_nm}; ++ ++static const char *dbgtrc_emio_input_names[] __initdata = {"trace_emio_clk"}; ++static const char *gem0_emio_input_names[] __initdata = {"gem0_emio_clk"}; ++static const char *gem1_emio_input_names[] __initdata = {"gem1_emio_clk"}; ++static const char *swdt_ext_clk_input_names[] __initdata = {"swdt_ext_clk"}; ++ ++static void __init zynq_clk_register_fclk(enum zynq_clk fclk, ++ const char *clk_name, void __iomem *fclk_ctrl_reg, ++ const char **parents) ++{ ++ struct clk *clk; ++ char *mux_name; ++ char *div0_name; ++ char *div1_name; ++ spinlock_t *fclk_lock; ++ spinlock_t *fclk_gate_lock; ++ void __iomem *fclk_gate_reg = fclk_ctrl_reg + 8; ++ ++ fclk_lock = kmalloc(sizeof(*fclk_lock), GFP_KERNEL); ++ if (!fclk_lock) ++ goto err; ++ fclk_gate_lock = kmalloc(sizeof(*fclk_gate_lock), GFP_KERNEL); ++ if (!fclk_gate_lock) ++ goto err; ++ spin_lock_init(fclk_lock); ++ spin_lock_init(fclk_gate_lock); ++ ++ mux_name = kasprintf(GFP_KERNEL, "%s_mux", clk_name); ++ div0_name = kasprintf(GFP_KERNEL, "%s_div0", clk_name); ++ div1_name = kasprintf(GFP_KERNEL, "%s_div1", clk_name); ++ ++ clk = clk_register_mux(NULL, mux_name, parents, 4, 0, ++ fclk_ctrl_reg, 4, 2, 0, fclk_lock); ++ ++ clk = clk_register_divider(NULL, div0_name, mux_name, ++ 0, fclk_ctrl_reg, 8, 6, CLK_DIVIDER_ONE_BASED | ++ CLK_DIVIDER_ALLOW_ZERO, fclk_lock); ++ ++ clk = clk_register_divider(NULL, div1_name, div0_name, ++ CLK_SET_RATE_PARENT, fclk_ctrl_reg, 20, 6, ++ CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO, ++ fclk_lock); ++ ++ clks[fclk] = clk_register_gate(NULL, clk_name, ++ div1_name, CLK_SET_RATE_PARENT, fclk_gate_reg, ++ 0, CLK_GATE_SET_TO_DISABLE, fclk_gate_lock); ++ kfree(mux_name); ++ kfree(div0_name); ++ kfree(div1_name); ++ ++ return; ++ ++err: ++ clks[fclk] = ERR_PTR(-ENOMEM); ++} ++ ++static void __init zynq_clk_register_periph_clk(enum zynq_clk clk0, ++ enum zynq_clk clk1, const char *clk_name0, ++ const char *clk_name1, void __iomem *clk_ctrl, ++ const char **parents, unsigned int two_gates) ++{ ++ struct clk *clk; ++ char *mux_name; ++ char *div_name; ++ spinlock_t *lock; ++ ++ lock = kmalloc(sizeof(*lock), GFP_KERNEL); ++ if (!lock) ++ goto err; ++ spin_lock_init(lock); ++ ++ mux_name = kasprintf(GFP_KERNEL, "%s_mux", clk_name0); ++ div_name = kasprintf(GFP_KERNEL, "%s_div", clk_name0); ++ ++ clk = clk_register_mux(NULL, mux_name, parents, 4, 0, ++ clk_ctrl, 4, 2, 0, lock); ++ ++ clk = clk_register_divider(NULL, div_name, mux_name, 0, clk_ctrl, 8, 6, ++ CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO, lock); ++ ++ clks[clk0] = clk_register_gate(NULL, clk_name0, div_name, ++ CLK_SET_RATE_PARENT, clk_ctrl, 0, 0, lock); ++ if (two_gates) ++ clks[clk1] = clk_register_gate(NULL, clk_name1, div_name, ++ CLK_SET_RATE_PARENT, clk_ctrl, 1, 0, lock); ++ ++ kfree(mux_name); ++ kfree(div_name); ++ ++ return; ++ ++err: ++ clks[clk0] = ERR_PTR(-ENOMEM); ++ if (two_gates) ++ clks[clk1] = ERR_PTR(-ENOMEM); ++} ++ ++static void __init zynq_clk_setup(struct device_node *np) ++{ ++ int i; ++ u32 tmp; ++ int ret; ++ struct clk *clk; ++ char *clk_name; ++ const char *clk_output_name[clk_max]; ++ const char *cpu_parents[4]; ++ const char *periph_parents[4]; ++ const char *swdt_ext_clk_mux_parents[2]; ++ const char *can_mio_mux_parents[NUM_MIO_PINS]; ++ ++ pr_info("Zynq clock init\n"); ++ ++ /* get clock output names from DT */ ++ for (i = 0; i < clk_max; i++) { ++ if (of_property_read_string_index(np, "clock-output-names", ++ i, &clk_output_name[i])) { ++ pr_err("%s: clock output name not in DT\n", __func__); ++ BUG(); ++ } ++ } ++ cpu_parents[0] = clk_output_name[armpll]; ++ cpu_parents[1] = clk_output_name[armpll]; ++ cpu_parents[2] = clk_output_name[ddrpll]; ++ cpu_parents[3] = clk_output_name[iopll]; ++ periph_parents[0] = clk_output_name[iopll]; ++ periph_parents[1] = clk_output_name[iopll]; ++ periph_parents[2] = clk_output_name[armpll]; ++ periph_parents[3] = clk_output_name[ddrpll]; ++ ++ /* ps_clk */ ++ ret = of_property_read_u32(np, "ps-clk-frequency", &tmp); ++ if (ret) { ++ pr_warn("ps_clk frequency not specified, using 33 MHz.\n"); ++ tmp = 33333333; ++ } ++ ps_clk = clk_register_fixed_rate(NULL, "ps_clk", NULL, CLK_IS_ROOT, ++ tmp); ++ ++ /* PLLs */ ++ clk = clk_register_zynq_pll("armpll_int", "ps_clk", SLCR_ARMPLL_CTRL, ++ SLCR_PLL_STATUS, 0, &armpll_lock); ++ clks[armpll] = clk_register_mux(NULL, clk_output_name[armpll], ++ armpll_parents, 2, 0, SLCR_ARMPLL_CTRL, 4, 1, 0, ++ &armpll_lock); ++ ++ clk = clk_register_zynq_pll("ddrpll_int", "ps_clk", SLCR_DDRPLL_CTRL, ++ SLCR_PLL_STATUS, 1, &ddrpll_lock); ++ clks[ddrpll] = clk_register_mux(NULL, clk_output_name[ddrpll], ++ ddrpll_parents, 2, 0, SLCR_DDRPLL_CTRL, 4, 1, 0, ++ &ddrpll_lock); ++ ++ clk = clk_register_zynq_pll("iopll_int", "ps_clk", SLCR_IOPLL_CTRL, ++ SLCR_PLL_STATUS, 2, &iopll_lock); ++ clks[iopll] = clk_register_mux(NULL, clk_output_name[iopll], ++ iopll_parents, 2, 0, SLCR_IOPLL_CTRL, 4, 1, 0, ++ &iopll_lock); ++ ++ /* CPU clocks */ ++ tmp = readl(SLCR_621_TRUE) & 1; ++ clk = clk_register_mux(NULL, "cpu_mux", cpu_parents, 4, 0, ++ SLCR_ARM_CLK_CTRL, 4, 2, 0, &armclk_lock); ++ clk = clk_register_divider(NULL, "cpu_div", "cpu_mux", 0, ++ SLCR_ARM_CLK_CTRL, 8, 6, CLK_DIVIDER_ONE_BASED | ++ CLK_DIVIDER_ALLOW_ZERO, &armclk_lock); ++ ++ clks[cpu_6or4x] = clk_register_gate(NULL, clk_output_name[cpu_6or4x], ++ "cpu_div", CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, ++ SLCR_ARM_CLK_CTRL, 24, 0, &armclk_lock); ++ ++ clk = clk_register_fixed_factor(NULL, "cpu_3or2x_div", "cpu_div", 0, ++ 1, 2); ++ clks[cpu_3or2x] = clk_register_gate(NULL, clk_output_name[cpu_3or2x], ++ "cpu_3or2x_div", CLK_IGNORE_UNUSED, ++ SLCR_ARM_CLK_CTRL, 25, 0, &armclk_lock); ++ ++ clk = clk_register_fixed_factor(NULL, "cpu_2x_div", "cpu_div", 0, 1, ++ 2 + tmp); ++ clks[cpu_2x] = clk_register_gate(NULL, clk_output_name[cpu_2x], ++ "cpu_2x_div", CLK_IGNORE_UNUSED, SLCR_ARM_CLK_CTRL, ++ 26, 0, &armclk_lock); ++ ++ clk = clk_register_fixed_factor(NULL, "cpu_1x_div", "cpu_div", 0, 1, ++ 4 + 2 * tmp); ++ clks[cpu_1x] = clk_register_gate(NULL, clk_output_name[cpu_1x], ++ "cpu_1x_div", CLK_IGNORE_UNUSED, SLCR_ARM_CLK_CTRL, 27, ++ 0, &armclk_lock); ++ ++ /* Timers */ ++ swdt_ext_clk_mux_parents[0] = clk_output_name[cpu_1x]; ++ for (i = 0; i < ARRAY_SIZE(swdt_ext_clk_input_names); i++) { ++ int idx = of_property_match_string(np, "clock-names", ++ swdt_ext_clk_input_names[i]); ++ if (idx >= 0) ++ swdt_ext_clk_mux_parents[i + 1] = ++ of_clk_get_parent_name(np, idx); ++ else ++ swdt_ext_clk_mux_parents[i + 1] = dummy_nm; ++ } ++ clks[swdt] = clk_register_mux(NULL, clk_output_name[swdt], ++ swdt_ext_clk_mux_parents, 2, CLK_SET_RATE_PARENT, ++ SLCR_SWDT_CLK_SEL, 0, 1, 0, &gem0clk_lock); ++ ++ /* DDR clocks */ ++ clk = clk_register_divider(NULL, "ddr2x_div", "ddrpll", 0, ++ SLCR_DDR_CLK_CTRL, 26, 6, CLK_DIVIDER_ONE_BASED | ++ CLK_DIVIDER_ALLOW_ZERO, &ddrclk_lock); ++ clks[ddr2x] = clk_register_gate(NULL, clk_output_name[ddr2x], ++ "ddr2x_div", 0, SLCR_DDR_CLK_CTRL, 1, 0, &ddrclk_lock); ++ clk_prepare_enable(clks[ddr2x]); ++ clk = clk_register_divider(NULL, "ddr3x_div", "ddrpll", 0, ++ SLCR_DDR_CLK_CTRL, 20, 6, CLK_DIVIDER_ONE_BASED | ++ CLK_DIVIDER_ALLOW_ZERO, &ddrclk_lock); ++ clks[ddr3x] = clk_register_gate(NULL, clk_output_name[ddr3x], ++ "ddr3x_div", 0, SLCR_DDR_CLK_CTRL, 0, 0, &ddrclk_lock); ++ clk_prepare_enable(clks[ddr3x]); ++ ++ clk = clk_register_divider(NULL, "dci_div0", "ddrpll", 0, ++ SLCR_DCI_CLK_CTRL, 8, 6, CLK_DIVIDER_ONE_BASED | ++ CLK_DIVIDER_ALLOW_ZERO, &dciclk_lock); ++ clk = clk_register_divider(NULL, "dci_div1", "dci_div0", ++ CLK_SET_RATE_PARENT, SLCR_DCI_CLK_CTRL, 20, 6, ++ CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO, ++ &dciclk_lock); ++ clks[dci] = clk_register_gate(NULL, clk_output_name[dci], "dci_div1", ++ CLK_SET_RATE_PARENT, SLCR_DCI_CLK_CTRL, 0, 0, ++ &dciclk_lock); ++ clk_prepare_enable(clks[dci]); ++ ++ /* Peripheral clocks */ ++ for (i = fclk0; i <= fclk3; i++) ++ zynq_clk_register_fclk(i, clk_output_name[i], ++ SLCR_FPGA0_CLK_CTRL + 0x10 * (i - fclk0), ++ periph_parents); ++ ++ zynq_clk_register_periph_clk(lqspi, 0, clk_output_name[lqspi], NULL, ++ SLCR_LQSPI_CLK_CTRL, periph_parents, 0); ++ ++ zynq_clk_register_periph_clk(smc, 0, clk_output_name[smc], NULL, ++ SLCR_SMC_CLK_CTRL, periph_parents, 0); ++ ++ zynq_clk_register_periph_clk(pcap, 0, clk_output_name[pcap], NULL, ++ SLCR_PCAP_CLK_CTRL, periph_parents, 0); ++ ++ zynq_clk_register_periph_clk(sdio0, sdio1, clk_output_name[sdio0], ++ clk_output_name[sdio1], SLCR_SDIO_CLK_CTRL, ++ periph_parents, 1); ++ ++ zynq_clk_register_periph_clk(uart0, uart1, clk_output_name[uart0], ++ clk_output_name[uart1], SLCR_UART_CLK_CTRL, ++ periph_parents, 1); ++ ++ zynq_clk_register_periph_clk(spi0, spi1, clk_output_name[spi0], ++ clk_output_name[spi1], SLCR_SPI_CLK_CTRL, ++ periph_parents, 1); ++ ++ for (i = 0; i < ARRAY_SIZE(gem0_emio_input_names); i++) { ++ int idx = of_property_match_string(np, "clock-names", ++ gem0_emio_input_names[i]); ++ if (idx >= 0) ++ gem0_mux_parents[i + 1] = of_clk_get_parent_name(np, ++ idx); ++ } ++ clk = clk_register_mux(NULL, "gem0_mux", periph_parents, 4, 0, ++ SLCR_GEM0_CLK_CTRL, 4, 2, 0, &gem0clk_lock); ++ clk = clk_register_divider(NULL, "gem0_div0", "gem0_mux", 0, ++ SLCR_GEM0_CLK_CTRL, 8, 6, CLK_DIVIDER_ONE_BASED | ++ CLK_DIVIDER_ALLOW_ZERO, &gem0clk_lock); ++ clk = clk_register_divider(NULL, "gem0_div1", "gem0_div0", ++ CLK_SET_RATE_PARENT, SLCR_GEM0_CLK_CTRL, 20, 6, ++ CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO, ++ &gem0clk_lock); ++ clk = clk_register_mux(NULL, "gem0_emio_mux", gem0_mux_parents, 2, 0, ++ SLCR_GEM0_CLK_CTRL, 6, 1, 0, &gem0clk_lock); ++ clks[gem0] = clk_register_gate(NULL, clk_output_name[gem0], ++ "gem0_emio_mux", CLK_SET_RATE_PARENT, ++ SLCR_GEM0_CLK_CTRL, 0, 0, &gem0clk_lock); ++ ++ for (i = 0; i < ARRAY_SIZE(gem1_emio_input_names); i++) { ++ int idx = of_property_match_string(np, "clock-names", ++ gem1_emio_input_names[i]); ++ if (idx >= 0) ++ gem1_mux_parents[i + 1] = of_clk_get_parent_name(np, ++ idx); ++ } ++ clk = clk_register_mux(NULL, "gem1_mux", periph_parents, 4, 0, ++ SLCR_GEM1_CLK_CTRL, 4, 2, 0, &gem1clk_lock); ++ clk = clk_register_divider(NULL, "gem1_div0", "gem1_mux", 0, ++ SLCR_GEM1_CLK_CTRL, 8, 6, CLK_DIVIDER_ONE_BASED | ++ CLK_DIVIDER_ALLOW_ZERO, &gem1clk_lock); ++ clk = clk_register_divider(NULL, "gem1_div1", "gem1_div0", ++ CLK_SET_RATE_PARENT, SLCR_GEM1_CLK_CTRL, 20, 6, ++ CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO, ++ &gem1clk_lock); ++ clk = clk_register_mux(NULL, "gem1_emio_mux", gem1_mux_parents, 2, 0, ++ SLCR_GEM1_CLK_CTRL, 6, 1, 0, &gem1clk_lock); ++ clks[gem1] = clk_register_gate(NULL, clk_output_name[gem1], ++ "gem1_emio_mux", CLK_SET_RATE_PARENT, ++ SLCR_GEM1_CLK_CTRL, 0, 0, &gem1clk_lock); ++ ++ tmp = strlen("mio_clk_00x"); ++ clk_name = kmalloc(tmp, GFP_KERNEL); ++ for (i = 0; i < NUM_MIO_PINS; i++) { ++ int idx; ++ ++ snprintf(clk_name, tmp, "mio_clk_%2.2d", i); ++ idx = of_property_match_string(np, "clock-names", clk_name); ++ if (idx >= 0) ++ can_mio_mux_parents[i] = of_clk_get_parent_name(np, ++ idx); ++ else ++ can_mio_mux_parents[i] = dummy_nm; ++ } ++ kfree(clk_name); ++ clk = clk_register_mux(NULL, "can_mux", periph_parents, 4, 0, ++ SLCR_CAN_CLK_CTRL, 4, 2, 0, &canclk_lock); ++ clk = clk_register_divider(NULL, "can_div0", "can_mux", 0, ++ SLCR_CAN_CLK_CTRL, 8, 6, CLK_DIVIDER_ONE_BASED | ++ CLK_DIVIDER_ALLOW_ZERO, &canclk_lock); ++ clk = clk_register_divider(NULL, "can_div1", "can_div0", ++ CLK_SET_RATE_PARENT, SLCR_CAN_CLK_CTRL, 20, 6, ++ CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO, ++ &canclk_lock); ++ clk = clk_register_gate(NULL, "can0_gate", "can_div1", ++ CLK_SET_RATE_PARENT, SLCR_CAN_CLK_CTRL, 0, 0, ++ &canclk_lock); ++ clk = clk_register_gate(NULL, "can1_gate", "can_div1", ++ CLK_SET_RATE_PARENT, SLCR_CAN_CLK_CTRL, 1, 0, ++ &canclk_lock); ++ clk = clk_register_mux(NULL, "can0_mio_mux", ++ can_mio_mux_parents, 54, CLK_SET_RATE_PARENT, ++ SLCR_CAN_MIOCLK_CTRL, 0, 6, 0, &canmioclk_lock); ++ clk = clk_register_mux(NULL, "can1_mio_mux", ++ can_mio_mux_parents, 54, CLK_SET_RATE_PARENT, ++ SLCR_CAN_MIOCLK_CTRL, 16, 6, 0, &canmioclk_lock); ++ clks[can0] = clk_register_mux(NULL, clk_output_name[can0], ++ can0_mio_mux2_parents, 2, CLK_SET_RATE_PARENT, ++ SLCR_CAN_MIOCLK_CTRL, 6, 1, 0, &canmioclk_lock); ++ clks[can1] = clk_register_mux(NULL, clk_output_name[can1], ++ can1_mio_mux2_parents, 2, CLK_SET_RATE_PARENT, ++ SLCR_CAN_MIOCLK_CTRL, 22, 1, 0, &canmioclk_lock); ++ ++ for (i = 0; i < ARRAY_SIZE(dbgtrc_emio_input_names); i++) { ++ int idx = of_property_match_string(np, "clock-names", ++ dbgtrc_emio_input_names[i]); ++ if (idx >= 0) ++ dbg_emio_mux_parents[i + 1] = of_clk_get_parent_name(np, ++ idx); ++ } ++ clk = clk_register_mux(NULL, "dbg_mux", periph_parents, 4, 0, ++ SLCR_DBG_CLK_CTRL, 4, 2, 0, &dbgclk_lock); ++ clk = clk_register_divider(NULL, "dbg_div", "dbg_mux", 0, ++ SLCR_DBG_CLK_CTRL, 8, 6, CLK_DIVIDER_ONE_BASED | ++ CLK_DIVIDER_ALLOW_ZERO, &dbgclk_lock); ++ clk = clk_register_mux(NULL, "dbg_emio_mux", dbg_emio_mux_parents, 2, 0, ++ SLCR_DBG_CLK_CTRL, 6, 1, 0, &dbgclk_lock); ++ clks[dbg_trc] = clk_register_gate(NULL, clk_output_name[dbg_trc], ++ "dbg_emio_mux", CLK_SET_RATE_PARENT, SLCR_DBG_CLK_CTRL, ++ 0, 0, &dbgclk_lock); ++ clks[dbg_apb] = clk_register_gate(NULL, clk_output_name[dbg_apb], ++ clk_output_name[cpu_1x], 0, SLCR_DBG_CLK_CTRL, 1, 0, ++ &dbgclk_lock); ++ ++ /* One gated clock for all APER clocks. */ ++ clks[dma] = clk_register_gate(NULL, clk_output_name[dma], ++ clk_output_name[cpu_2x], 0, SLCR_APER_CLK_CTRL, 0, 0, ++ &aperclk_lock); ++ clks[usb0_aper] = clk_register_gate(NULL, clk_output_name[usb0_aper], ++ clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 2, 0, ++ &aperclk_lock); ++ clks[usb1_aper] = clk_register_gate(NULL, clk_output_name[usb1_aper], ++ clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 3, 0, ++ &aperclk_lock); ++ clks[gem0_aper] = clk_register_gate(NULL, clk_output_name[gem0_aper], ++ clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 6, 0, ++ &aperclk_lock); ++ clks[gem1_aper] = clk_register_gate(NULL, clk_output_name[gem1_aper], ++ clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 7, 0, ++ &aperclk_lock); ++ clks[sdio0_aper] = clk_register_gate(NULL, clk_output_name[sdio0_aper], ++ clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 10, 0, ++ &aperclk_lock); ++ clks[sdio1_aper] = clk_register_gate(NULL, clk_output_name[sdio1_aper], ++ clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 11, 0, ++ &aperclk_lock); ++ clks[spi0_aper] = clk_register_gate(NULL, clk_output_name[spi0_aper], ++ clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 14, 0, ++ &aperclk_lock); ++ clks[spi1_aper] = clk_register_gate(NULL, clk_output_name[spi1_aper], ++ clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 15, 0, ++ &aperclk_lock); ++ clks[can0_aper] = clk_register_gate(NULL, clk_output_name[can0_aper], ++ clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 16, 0, ++ &aperclk_lock); ++ clks[can1_aper] = clk_register_gate(NULL, clk_output_name[can1_aper], ++ clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 17, 0, ++ &aperclk_lock); ++ clks[i2c0_aper] = clk_register_gate(NULL, clk_output_name[i2c0_aper], ++ clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 18, 0, ++ &aperclk_lock); ++ clks[i2c1_aper] = clk_register_gate(NULL, clk_output_name[i2c1_aper], ++ clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 19, 0, ++ &aperclk_lock); ++ clks[uart0_aper] = clk_register_gate(NULL, clk_output_name[uart0_aper], ++ clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 20, 0, ++ &aperclk_lock); ++ clks[uart1_aper] = clk_register_gate(NULL, clk_output_name[uart1_aper], ++ clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 21, 0, ++ &aperclk_lock); ++ clks[gpio_aper] = clk_register_gate(NULL, clk_output_name[gpio_aper], ++ clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 22, 0, ++ &aperclk_lock); ++ clks[lqspi_aper] = clk_register_gate(NULL, clk_output_name[lqspi_aper], ++ clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 23, 0, ++ &aperclk_lock); ++ clks[smc_aper] = clk_register_gate(NULL, clk_output_name[smc_aper], ++ clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 24, 0, ++ &aperclk_lock); ++ ++ for (i = 0; i < ARRAY_SIZE(clks); i++) { ++ if (IS_ERR(clks[i])) { ++ pr_err("Zynq clk %d: register failed with %ld\n", ++ i, PTR_ERR(clks[i])); ++ BUG(); ++ } ++ } ++ ++ clk_data.clks = clks; ++ clk_data.clk_num = ARRAY_SIZE(clks); ++ of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); ++} ++ ++CLK_OF_DECLARE(zynq_clkc, "xlnx,ps7-clkc", zynq_clk_setup); ++ ++void __init zynq_clock_init(void __iomem *slcr_base) ++{ ++ zynq_slcr_base_priv = slcr_base; ++ of_clk_init(NULL); ++} +-- +1.8.5.rc3 + diff --git a/patches.zynq/0036-clk-zynq-Remove-deprecated-clock-code.patch b/patches.zynq/0036-clk-zynq-Remove-deprecated-clock-code.patch new file mode 100644 index 00000000000000..5f78ff4790d0d1 --- /dev/null +++ b/patches.zynq/0036-clk-zynq-Remove-deprecated-clock-code.patch @@ -0,0 +1,465 @@ +From 271b78195ed174bef0601532aa9504c9f2ee9363 Mon Sep 17 00:00:00 2001 +From: Soren Brinkmann <soren.brinkmann@xilinx.com> +Date: Mon, 13 May 2013 10:46:39 -0700 +Subject: clk: zynq: Remove deprecated clock code + +Signed-off-by: Soren Brinkmann <soren.brinkmann@xilinx.com> +Cc: Grant Likely <grant.likely@linaro.org> +Cc: Rob Herring <rob.herring@calxeda.com> +Cc: Rob Landley <rob@landley.net> +Cc: devicetree-discuss@lists.ozlabs.org +Cc: linux-doc@vger.kernel.org +Signed-off-by: Michal Simek <michal.simek@xilinx.com> +Acked-by: Mike Turquette <mturquette@linaro.org> +(cherry picked from commit 97c4e87d45498fb4d18c995721bba72345a7d257) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + .../devicetree/bindings/clock/zynq-7000.txt | 48 --- + drivers/clk/clk-zynq.c | 378 --------------------- + 2 files changed, 426 deletions(-) + delete mode 100644 drivers/clk/clk-zynq.c + +diff --git a/Documentation/devicetree/bindings/clock/zynq-7000.txt b/Documentation/devicetree/bindings/clock/zynq-7000.txt +index 1049a313933c..d99af878f5d7 100644 +--- a/Documentation/devicetree/bindings/clock/zynq-7000.txt ++++ b/Documentation/devicetree/bindings/clock/zynq-7000.txt +@@ -102,51 +102,3 @@ Example: + clocks = <&clkc 16>, <&clk_foo>; + clock-names = "gem1_emio_clk", "can_mio_clk_23"; + }; +- +-== PLLs == +- +-Used to describe the ARM_PLL, DDR_PLL, and IO_PLL. +- +-Required properties: +-- #clock-cells : shall be 0 (only one clock is output from this node) +-- compatible : "xlnx,zynq-pll" +-- reg : pair of u32 values, which are the address offsets within the SLCR +- of the relevant PLL_CTRL register and PLL_CFG register respectively +-- clocks : phandle for parent clock. should be the phandle for ps_clk +- +-Optional properties: +-- clock-output-names : name of the output clock +- +-Example: +- armpll: armpll { +- #clock-cells = <0>; +- compatible = "xlnx,zynq-pll"; +- clocks = <&ps_clk>; +- reg = <0x100 0x110>; +- clock-output-names = "armpll"; +- }; +- +-== Peripheral clocks == +- +-Describes clock node for the SDIO, SMC, SPI, QSPI, and UART clocks. +- +-Required properties: +-- #clock-cells : shall be 1 +-- compatible : "xlnx,zynq-periph-clock" +-- reg : a single u32 value, describing the offset within the SLCR where +- the CLK_CTRL register is found for this peripheral +-- clocks : phandle for parent clocks. should hold phandles for +- the IO_PLL, ARM_PLL, and DDR_PLL in order +-- clock-output-names : names of the output clock(s). For peripherals that have +- two output clocks (for example, the UART), two clocks +- should be listed. +- +-Example: +- uart_clk: uart_clk { +- #clock-cells = <1>; +- compatible = "xlnx,zynq-periph-clock"; +- clocks = <&iopll &armpll &ddrpll>; +- reg = <0x154>; +- clock-output-names = "uart0_ref_clk", +- "uart1_ref_clk"; +- }; +diff --git a/drivers/clk/clk-zynq.c b/drivers/clk/clk-zynq.c +deleted file mode 100644 +index 32062977f453..000000000000 +--- a/drivers/clk/clk-zynq.c ++++ /dev/null +@@ -1,378 +0,0 @@ +-/* +- * Copyright (c) 2012 National Instruments +- * +- * Josh Cartwright <josh.cartwright@ni.com> +- * +- * This program is free software; you can redistribute it and/or modify it +- * under the terms and conditions of the GNU General Public License, +- * version 2, as published by the Free Software Foundation. +- * +- * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>. +- */ +-#include <linux/io.h> +-#include <linux/of.h> +-#include <linux/slab.h> +-#include <linux/kernel.h> +-#include <linux/clk-provider.h> +-#include <linux/clk/zynq.h> +- +-static void __iomem *slcr_base; +- +-struct zynq_pll_clk { +- struct clk_hw hw; +- void __iomem *pll_ctrl; +- void __iomem *pll_cfg; +-}; +- +-#define to_zynq_pll_clk(hw) container_of(hw, struct zynq_pll_clk, hw) +- +-#define CTRL_PLL_FDIV(x) ((x) >> 12) +- +-static unsigned long zynq_pll_recalc_rate(struct clk_hw *hw, +- unsigned long parent_rate) +-{ +- struct zynq_pll_clk *pll = to_zynq_pll_clk(hw); +- return parent_rate * CTRL_PLL_FDIV(ioread32(pll->pll_ctrl)); +-} +- +-static const struct clk_ops zynq_pll_clk_ops = { +- .recalc_rate = zynq_pll_recalc_rate, +-}; +- +-static void __init zynq_pll_clk_setup(struct device_node *np) +-{ +- struct clk_init_data init; +- struct zynq_pll_clk *pll; +- const char *parent_name; +- struct clk *clk; +- u32 regs[2]; +- int ret; +- +- ret = of_property_read_u32_array(np, "reg", regs, ARRAY_SIZE(regs)); +- if (WARN_ON(ret)) +- return; +- +- pll = kzalloc(sizeof(*pll), GFP_KERNEL); +- if (WARN_ON(!pll)) +- return; +- +- pll->pll_ctrl = slcr_base + regs[0]; +- pll->pll_cfg = slcr_base + regs[1]; +- +- of_property_read_string(np, "clock-output-names", &init.name); +- +- init.ops = &zynq_pll_clk_ops; +- parent_name = of_clk_get_parent_name(np, 0); +- init.parent_names = &parent_name; +- init.num_parents = 1; +- +- pll->hw.init = &init; +- +- clk = clk_register(NULL, &pll->hw); +- if (WARN_ON(IS_ERR(clk))) +- return; +- +- ret = of_clk_add_provider(np, of_clk_src_simple_get, clk); +- if (WARN_ON(ret)) +- return; +-} +-CLK_OF_DECLARE(zynq_pll, "xlnx,zynq-pll", zynq_pll_clk_setup); +- +-struct zynq_periph_clk { +- struct clk_hw hw; +- struct clk_onecell_data onecell_data; +- struct clk *gates[2]; +- void __iomem *clk_ctrl; +- spinlock_t clkact_lock; +-}; +- +-#define to_zynq_periph_clk(hw) container_of(hw, struct zynq_periph_clk, hw) +- +-static const u8 periph_clk_parent_map[] = { +- 0, 0, 1, 2 +-}; +-#define PERIPH_CLK_CTRL_SRC(x) (periph_clk_parent_map[((x) & 0x30) >> 4]) +-#define PERIPH_CLK_CTRL_DIV(x) (((x) & 0x3F00) >> 8) +- +-static unsigned long zynq_periph_recalc_rate(struct clk_hw *hw, +- unsigned long parent_rate) +-{ +- struct zynq_periph_clk *periph = to_zynq_periph_clk(hw); +- return parent_rate / PERIPH_CLK_CTRL_DIV(ioread32(periph->clk_ctrl)); +-} +- +-static u8 zynq_periph_get_parent(struct clk_hw *hw) +-{ +- struct zynq_periph_clk *periph = to_zynq_periph_clk(hw); +- return PERIPH_CLK_CTRL_SRC(ioread32(periph->clk_ctrl)); +-} +- +-static const struct clk_ops zynq_periph_clk_ops = { +- .recalc_rate = zynq_periph_recalc_rate, +- .get_parent = zynq_periph_get_parent, +-}; +- +-static void __init zynq_periph_clk_setup(struct device_node *np) +-{ +- struct zynq_periph_clk *periph; +- const char *parent_names[3]; +- struct clk_init_data init; +- int clk_num = 0, err; +- const char *name; +- struct clk *clk; +- u32 reg; +- int i; +- +- err = of_property_read_u32(np, "reg", ®); +- if (WARN_ON(err)) +- return; +- +- periph = kzalloc(sizeof(*periph), GFP_KERNEL); +- if (WARN_ON(!periph)) +- return; +- +- periph->clk_ctrl = slcr_base + reg; +- spin_lock_init(&periph->clkact_lock); +- +- init.name = np->name; +- init.ops = &zynq_periph_clk_ops; +- for (i = 0; i < ARRAY_SIZE(parent_names); i++) +- parent_names[i] = of_clk_get_parent_name(np, i); +- init.parent_names = parent_names; +- init.num_parents = ARRAY_SIZE(parent_names); +- +- periph->hw.init = &init; +- +- clk = clk_register(NULL, &periph->hw); +- if (WARN_ON(IS_ERR(clk))) +- return; +- +- err = of_clk_add_provider(np, of_clk_src_simple_get, clk); +- if (WARN_ON(err)) +- return; +- +- err = of_property_read_string_index(np, "clock-output-names", 0, +- &name); +- if (WARN_ON(err)) +- return; +- +- periph->gates[0] = clk_register_gate(NULL, name, np->name, 0, +- periph->clk_ctrl, 0, 0, +- &periph->clkact_lock); +- if (WARN_ON(IS_ERR(periph->gates[0]))) +- return; +- clk_num++; +- +- /* some periph clks have 2 downstream gates */ +- err = of_property_read_string_index(np, "clock-output-names", 1, +- &name); +- if (err != -ENODATA) { +- periph->gates[1] = clk_register_gate(NULL, name, np->name, 0, +- periph->clk_ctrl, 1, 0, +- &periph->clkact_lock); +- if (WARN_ON(IS_ERR(periph->gates[1]))) +- return; +- clk_num++; +- } +- +- periph->onecell_data.clks = periph->gates; +- periph->onecell_data.clk_num = clk_num; +- +- err = of_clk_add_provider(np, of_clk_src_onecell_get, +- &periph->onecell_data); +- if (WARN_ON(err)) +- return; +-} +-CLK_OF_DECLARE(zynq_periph, "xlnx,zynq-periph-clock", zynq_periph_clk_setup); +- +-/* CPU Clock domain is modelled as a mux with 4 children subclks, whose +- * derivative rates depend on CLK_621_TRUE +- */ +- +-struct zynq_cpu_clk { +- struct clk_hw hw; +- struct clk_onecell_data onecell_data; +- struct clk *subclks[4]; +- void __iomem *clk_ctrl; +- spinlock_t clkact_lock; +-}; +- +-#define to_zynq_cpu_clk(hw) container_of(hw, struct zynq_cpu_clk, hw) +- +-static const u8 zynq_cpu_clk_parent_map[] = { +- 1, 1, 2, 0 +-}; +-#define CPU_CLK_SRCSEL(x) (zynq_cpu_clk_parent_map[(((x) & 0x30) >> 4)]) +-#define CPU_CLK_CTRL_DIV(x) (((x) & 0x3F00) >> 8) +- +-static u8 zynq_cpu_clk_get_parent(struct clk_hw *hw) +-{ +- struct zynq_cpu_clk *cpuclk = to_zynq_cpu_clk(hw); +- return CPU_CLK_SRCSEL(ioread32(cpuclk->clk_ctrl)); +-} +- +-static unsigned long zynq_cpu_clk_recalc_rate(struct clk_hw *hw, +- unsigned long parent_rate) +-{ +- struct zynq_cpu_clk *cpuclk = to_zynq_cpu_clk(hw); +- return parent_rate / CPU_CLK_CTRL_DIV(ioread32(cpuclk->clk_ctrl)); +-} +- +-static const struct clk_ops zynq_cpu_clk_ops = { +- .get_parent = zynq_cpu_clk_get_parent, +- .recalc_rate = zynq_cpu_clk_recalc_rate, +-}; +- +-struct zynq_cpu_subclk { +- struct clk_hw hw; +- void __iomem *clk_621; +- enum { +- CPU_SUBCLK_6X4X, +- CPU_SUBCLK_3X2X, +- CPU_SUBCLK_2X, +- CPU_SUBCLK_1X, +- } which; +-}; +- +-#define CLK_621_TRUE(x) ((x) & 1) +- +-#define to_zynq_cpu_subclk(hw) container_of(hw, struct zynq_cpu_subclk, hw); +- +-static unsigned long zynq_cpu_subclk_recalc_rate(struct clk_hw *hw, +- unsigned long parent_rate) +-{ +- unsigned long uninitialized_var(rate); +- struct zynq_cpu_subclk *subclk; +- bool is_621; +- +- subclk = to_zynq_cpu_subclk(hw) +- is_621 = CLK_621_TRUE(ioread32(subclk->clk_621)); +- +- switch (subclk->which) { +- case CPU_SUBCLK_6X4X: +- rate = parent_rate; +- break; +- case CPU_SUBCLK_3X2X: +- rate = parent_rate / 2; +- break; +- case CPU_SUBCLK_2X: +- rate = parent_rate / (is_621 ? 3 : 2); +- break; +- case CPU_SUBCLK_1X: +- rate = parent_rate / (is_621 ? 6 : 4); +- break; +- }; +- +- return rate; +-} +- +-static const struct clk_ops zynq_cpu_subclk_ops = { +- .recalc_rate = zynq_cpu_subclk_recalc_rate, +-}; +- +-static struct clk *zynq_cpu_subclk_setup(struct device_node *np, u8 which, +- void __iomem *clk_621) +-{ +- struct zynq_cpu_subclk *subclk; +- struct clk_init_data init; +- struct clk *clk; +- int err; +- +- err = of_property_read_string_index(np, "clock-output-names", +- which, &init.name); +- if (WARN_ON(err)) +- goto err_read_output_name; +- +- subclk = kzalloc(sizeof(*subclk), GFP_KERNEL); +- if (!subclk) +- goto err_subclk_alloc; +- +- subclk->clk_621 = clk_621; +- subclk->which = which; +- +- init.ops = &zynq_cpu_subclk_ops; +- init.parent_names = &np->name; +- init.num_parents = 1; +- +- subclk->hw.init = &init; +- +- clk = clk_register(NULL, &subclk->hw); +- if (WARN_ON(IS_ERR(clk))) +- goto err_clk_register; +- +- return clk; +- +-err_clk_register: +- kfree(subclk); +-err_subclk_alloc: +-err_read_output_name: +- return ERR_PTR(-EINVAL); +-} +- +-static void __init zynq_cpu_clk_setup(struct device_node *np) +-{ +- struct zynq_cpu_clk *cpuclk; +- const char *parent_names[3]; +- struct clk_init_data init; +- void __iomem *clk_621; +- struct clk *clk; +- u32 reg[2]; +- int err; +- int i; +- +- err = of_property_read_u32_array(np, "reg", reg, ARRAY_SIZE(reg)); +- if (WARN_ON(err)) +- return; +- +- cpuclk = kzalloc(sizeof(*cpuclk), GFP_KERNEL); +- if (WARN_ON(!cpuclk)) +- return; +- +- cpuclk->clk_ctrl = slcr_base + reg[0]; +- clk_621 = slcr_base + reg[1]; +- spin_lock_init(&cpuclk->clkact_lock); +- +- init.name = np->name; +- init.ops = &zynq_cpu_clk_ops; +- for (i = 0; i < ARRAY_SIZE(parent_names); i++) +- parent_names[i] = of_clk_get_parent_name(np, i); +- init.parent_names = parent_names; +- init.num_parents = ARRAY_SIZE(parent_names); +- +- cpuclk->hw.init = &init; +- +- clk = clk_register(NULL, &cpuclk->hw); +- if (WARN_ON(IS_ERR(clk))) +- return; +- +- err = of_clk_add_provider(np, of_clk_src_simple_get, clk); +- if (WARN_ON(err)) +- return; +- +- for (i = 0; i < 4; i++) { +- cpuclk->subclks[i] = zynq_cpu_subclk_setup(np, i, clk_621); +- if (WARN_ON(IS_ERR(cpuclk->subclks[i]))) +- return; +- } +- +- cpuclk->onecell_data.clks = cpuclk->subclks; +- cpuclk->onecell_data.clk_num = i; +- +- err = of_clk_add_provider(np, of_clk_src_onecell_get, +- &cpuclk->onecell_data); +- if (WARN_ON(err)) +- return; +-} +-CLK_OF_DECLARE(zynq_cpu, "xlnx,zynq-cpu-clock", zynq_cpu_clk_setup); +- +-void __init xilinx_zynq_clocks_init(void __iomem *slcr) +-{ +- slcr_base = slcr; +- of_clk_init(NULL); +-} +-- +1.8.5.rc3 + diff --git a/patches.zynq/0037-clk-zynq-clkc-Add-dedicated-spinlock-for-the-SWDT.patch b/patches.zynq/0037-clk-zynq-clkc-Add-dedicated-spinlock-for-the-SWDT.patch new file mode 100644 index 00000000000000..cc38cb3671d06a --- /dev/null +++ b/patches.zynq/0037-clk-zynq-clkc-Add-dedicated-spinlock-for-the-SWDT.patch @@ -0,0 +1,49 @@ +From 8f1f273065be3102c89727c356355ebbe6d9c022 Mon Sep 17 00:00:00 2001 +From: Soren Brinkmann <soren.brinkmann@xilinx.com> +Date: Mon, 17 Jun 2013 15:03:46 -0700 +Subject: clk/zynq/clkc: Add dedicated spinlock for the SWDT + +The clk_mux for the system watchdog timer reused the register lock +dedicated to the Ethernet module - for no apparent reason. +Add a lock dedicated to the SWDT's clock register to remove this +wrong dependency. + +This does not fix a specific regression but the clock driver was merged +for 3.11-rc1, so best to fix the known bugs before the release. + +Signed-off-by: Soren Brinkmann <soren.brinkmann@xilinx.com> +Signed-off-by: Michal Simek <michal.simek@xilinx.com> +Signed-off-by: Mike Turquette <mturquette@linaro.org> +[mturquette@linaro.org: added to changelog] + +(cherry picked from commit 252957cc3a2d59179df1a2d44d219e07dc5c3f06) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + drivers/clk/zynq/clkc.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/clk/zynq/clkc.c b/drivers/clk/zynq/clkc.c +index 5c205b60a82a..515a5732d391 100644 +--- a/drivers/clk/zynq/clkc.c ++++ b/drivers/clk/zynq/clkc.c +@@ -71,6 +71,7 @@ static DEFINE_SPINLOCK(armpll_lock); + static DEFINE_SPINLOCK(ddrpll_lock); + static DEFINE_SPINLOCK(iopll_lock); + static DEFINE_SPINLOCK(armclk_lock); ++static DEFINE_SPINLOCK(swdtclk_lock); + static DEFINE_SPINLOCK(ddrclk_lock); + static DEFINE_SPINLOCK(dciclk_lock); + static DEFINE_SPINLOCK(gem0clk_lock); +@@ -293,7 +294,7 @@ static void __init zynq_clk_setup(struct device_node *np) + } + clks[swdt] = clk_register_mux(NULL, clk_output_name[swdt], + swdt_ext_clk_mux_parents, 2, CLK_SET_RATE_PARENT, +- SLCR_SWDT_CLK_SEL, 0, 1, 0, &gem0clk_lock); ++ SLCR_SWDT_CLK_SEL, 0, 1, 0, &swdtclk_lock); + + /* DDR clocks */ + clk = clk_register_divider(NULL, "ddr2x_div", "ddrpll", 0, +-- +1.8.5.rc3 + diff --git a/patches.zynq/0038-clk-zynq-clkc-Add-CLK_SET_RATE_PARENT-flag-to-ethern.patch b/patches.zynq/0038-clk-zynq-clkc-Add-CLK_SET_RATE_PARENT-flag-to-ethern.patch new file mode 100644 index 00000000000000..05e8cf7e66970a --- /dev/null +++ b/patches.zynq/0038-clk-zynq-clkc-Add-CLK_SET_RATE_PARENT-flag-to-ethern.patch @@ -0,0 +1,57 @@ +From 96733aac27bad6e23fb1bfb25c14c59369bb371d Mon Sep 17 00:00:00 2001 +From: Soren Brinkmann <soren.brinkmann@xilinx.com> +Date: Mon, 17 Jun 2013 15:47:40 -0700 +Subject: clk/zynq/clkc: Add CLK_SET_RATE_PARENT flag to ethernet muxes + +Zynq's Ethernet clocks are created by the following hierarchy: + mux0 ---> div0 ---> div1 ---> mux1 ---> gate +Rate change requests on the gate have to propagate all the way up to +div0 to properly leverage all dividers. Mux1 was missing the +CLK_SET_RATE_PARENT flag, which is required to achieve this. + +This does not fix a specific regression but the clock driver was merged +for 3.11-rc1, so best to fix the known bugs before the release. + +Signed-off-by: Soren Brinkmann <soren.brinkmann@xilinx.com> +Signed-off-by: Michal Simek <michal.simek@xilinx.com> +Signed-off-by: Mike Turquette <mturquette@linaro.org> +[mturquette@linaro.org: added to changelog] + +(cherry picked from commit 765b7d4c4cb376465f81d0dd44b50861514dbcba) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + drivers/clk/zynq/clkc.c | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +diff --git a/drivers/clk/zynq/clkc.c b/drivers/clk/zynq/clkc.c +index 515a5732d391..089d3e30e221 100644 +--- a/drivers/clk/zynq/clkc.c ++++ b/drivers/clk/zynq/clkc.c +@@ -365,8 +365,9 @@ static void __init zynq_clk_setup(struct device_node *np) + CLK_SET_RATE_PARENT, SLCR_GEM0_CLK_CTRL, 20, 6, + CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO, + &gem0clk_lock); +- clk = clk_register_mux(NULL, "gem0_emio_mux", gem0_mux_parents, 2, 0, +- SLCR_GEM0_CLK_CTRL, 6, 1, 0, &gem0clk_lock); ++ clk = clk_register_mux(NULL, "gem0_emio_mux", gem0_mux_parents, 2, ++ CLK_SET_RATE_PARENT, SLCR_GEM0_CLK_CTRL, 6, 1, 0, ++ &gem0clk_lock); + clks[gem0] = clk_register_gate(NULL, clk_output_name[gem0], + "gem0_emio_mux", CLK_SET_RATE_PARENT, + SLCR_GEM0_CLK_CTRL, 0, 0, &gem0clk_lock); +@@ -387,8 +388,9 @@ static void __init zynq_clk_setup(struct device_node *np) + CLK_SET_RATE_PARENT, SLCR_GEM1_CLK_CTRL, 20, 6, + CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO, + &gem1clk_lock); +- clk = clk_register_mux(NULL, "gem1_emio_mux", gem1_mux_parents, 2, 0, +- SLCR_GEM1_CLK_CTRL, 6, 1, 0, &gem1clk_lock); ++ clk = clk_register_mux(NULL, "gem1_emio_mux", gem1_mux_parents, 2, ++ CLK_SET_RATE_PARENT, SLCR_GEM1_CLK_CTRL, 6, 1, 0, ++ &gem1clk_lock); + clks[gem1] = clk_register_gate(NULL, clk_output_name[gem1], + "gem1_emio_mux", CLK_SET_RATE_PARENT, + SLCR_GEM1_CLK_CTRL, 0, 0, &gem1clk_lock); +-- +1.8.5.rc3 + diff --git a/patches.zynq/0039-clk-add-CLK_SET_RATE_NO_REPARENT-flag.patch b/patches.zynq/0039-clk-add-CLK_SET_RATE_NO_REPARENT-flag.patch new file mode 100644 index 00000000000000..27ab31585a048a --- /dev/null +++ b/patches.zynq/0039-clk-add-CLK_SET_RATE_NO_REPARENT-flag.patch @@ -0,0 +1,251 @@ +From 1ce16914cbed078b39c1c752888825e02ce86b1c Mon Sep 17 00:00:00 2001 +From: James Hogan <james.hogan@imgtec.com> +Date: Mon, 29 Jul 2013 12:25:01 +0100 +Subject: clk: add CLK_SET_RATE_NO_REPARENT flag +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Add a CLK_SET_RATE_NO_REPARENT clock flag, which will prevent muxes +being reparented during clk_set_rate. + +To avoid breaking existing platforms, all callers of clk_register_mux() +are adjusted to pass the new flag. Platform maintainers are encouraged +to remove the flag if they wish to allow mux reparenting on set_rate. + +Signed-off-by: James Hogan <james.hogan@imgtec.com> +Reviewed-by: Stephen Boyd <sboyd@codeaurora.org> +Cc: Mike Turquette <mturquette@linaro.org> +Cc: Russell King <linux@arm.linux.org.uk> +Cc: Sascha Hauer <kernel@pengutronix.de> +Cc: Stephen Warren <swarren@wwwdotorg.org> +Cc: Viresh Kumar <viresh.linux@gmail.com> +Cc: Kukjin Kim <kgene.kim@samsung.com> +Cc: Haojian Zhuang <haojian.zhuang@linaro.org> +Cc: Chao Xie <xiechao.mail@gmail.com> +Cc: Arnd Bergmann <arnd@arndb.de> +Cc: "Emilio López" <emilio@elopez.com.ar> +Cc: Gregory CLEMENT <gregory.clement@free-electrons.com> +Cc: Maxime Ripard <maxime.ripard@free-electrons.com> +Cc: Prashant Gaikwad <pgaikwad@nvidia.com> +Cc: Thierry Reding <thierry.reding@gmail.com> +Cc: Peter De Schrijver <pdeschrijver@nvidia.com> +Cc: Pawel Moll <pawel.moll@arm.com> +Cc: Catalin Marinas <catalin.marinas@arm.com> +Cc: Andrew Chew <achew@nvidia.com> +Cc: Doug Anderson <dianders@chromium.org> +Cc: Heiko Stuebner <heiko@sntech.de> +Cc: Paul Walmsley <pwalmsley@nvidia.com> +Cc: Sylwester Nawrocki <s.nawrocki@samsung.com> +Cc: Thomas Abraham <thomas.abraham@linaro.org> +Cc: Tomasz Figa <t.figa@samsung.com> +Cc: linux-arm-kernel@lists.infradead.org +Cc: linux-samsung-soc@vger.kernel.org +Cc: spear-devel@list.st.com +Cc: linux-tegra@vger.kernel.org +Tested-by: Haojian Zhuang <haojian.zhuang@gmail.com> +Acked-by: Stephen Warren <swarren@nvidia.com> [tegra] +Acked-by: Maxime Ripard <maxime.ripard@free-electrons.com> [sunxi] +Acked-by: Sören Brinkmann <soren.brinkmann@xilinx.com> [Zynq] +Signed-off-by: Mike Turquette <mturquette@linaro.org> +(cherry picked from commit 819c1de344c5b8350bffd35be9a0fa74541292d3) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + drivers/clk/zynq/clkc.c | 80 +++++++++++++++++++++++++------------------- + include/linux/clk-provider.h | 1 + + 2 files changed, 47 insertions(+), 34 deletions(-) + +diff --git a/drivers/clk/zynq/clkc.c b/drivers/clk/zynq/clkc.c +index 089d3e30e221..6169d56fb6f1 100644 +--- a/drivers/clk/zynq/clkc.c ++++ b/drivers/clk/zynq/clkc.c +@@ -125,8 +125,9 @@ static void __init zynq_clk_register_fclk(enum zynq_clk fclk, + div0_name = kasprintf(GFP_KERNEL, "%s_div0", clk_name); + div1_name = kasprintf(GFP_KERNEL, "%s_div1", clk_name); + +- clk = clk_register_mux(NULL, mux_name, parents, 4, 0, +- fclk_ctrl_reg, 4, 2, 0, fclk_lock); ++ clk = clk_register_mux(NULL, mux_name, parents, 4, ++ CLK_SET_RATE_NO_REPARENT, fclk_ctrl_reg, 4, 2, 0, ++ fclk_lock); + + clk = clk_register_divider(NULL, div0_name, mux_name, + 0, fclk_ctrl_reg, 8, 6, CLK_DIVIDER_ONE_BASED | +@@ -168,8 +169,8 @@ static void __init zynq_clk_register_periph_clk(enum zynq_clk clk0, + mux_name = kasprintf(GFP_KERNEL, "%s_mux", clk_name0); + div_name = kasprintf(GFP_KERNEL, "%s_div", clk_name0); + +- clk = clk_register_mux(NULL, mux_name, parents, 4, 0, +- clk_ctrl, 4, 2, 0, lock); ++ clk = clk_register_mux(NULL, mux_name, parents, 4, ++ CLK_SET_RATE_NO_REPARENT, clk_ctrl, 4, 2, 0, lock); + + clk = clk_register_divider(NULL, div_name, mux_name, 0, clk_ctrl, 8, 6, + CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO, lock); +@@ -236,25 +237,26 @@ static void __init zynq_clk_setup(struct device_node *np) + clk = clk_register_zynq_pll("armpll_int", "ps_clk", SLCR_ARMPLL_CTRL, + SLCR_PLL_STATUS, 0, &armpll_lock); + clks[armpll] = clk_register_mux(NULL, clk_output_name[armpll], +- armpll_parents, 2, 0, SLCR_ARMPLL_CTRL, 4, 1, 0, +- &armpll_lock); ++ armpll_parents, 2, CLK_SET_RATE_NO_REPARENT, ++ SLCR_ARMPLL_CTRL, 4, 1, 0, &armpll_lock); + + clk = clk_register_zynq_pll("ddrpll_int", "ps_clk", SLCR_DDRPLL_CTRL, + SLCR_PLL_STATUS, 1, &ddrpll_lock); + clks[ddrpll] = clk_register_mux(NULL, clk_output_name[ddrpll], +- ddrpll_parents, 2, 0, SLCR_DDRPLL_CTRL, 4, 1, 0, +- &ddrpll_lock); ++ ddrpll_parents, 2, CLK_SET_RATE_NO_REPARENT, ++ SLCR_DDRPLL_CTRL, 4, 1, 0, &ddrpll_lock); + + clk = clk_register_zynq_pll("iopll_int", "ps_clk", SLCR_IOPLL_CTRL, + SLCR_PLL_STATUS, 2, &iopll_lock); + clks[iopll] = clk_register_mux(NULL, clk_output_name[iopll], +- iopll_parents, 2, 0, SLCR_IOPLL_CTRL, 4, 1, 0, +- &iopll_lock); ++ iopll_parents, 2, CLK_SET_RATE_NO_REPARENT, ++ SLCR_IOPLL_CTRL, 4, 1, 0, &iopll_lock); + + /* CPU clocks */ + tmp = readl(SLCR_621_TRUE) & 1; +- clk = clk_register_mux(NULL, "cpu_mux", cpu_parents, 4, 0, +- SLCR_ARM_CLK_CTRL, 4, 2, 0, &armclk_lock); ++ clk = clk_register_mux(NULL, "cpu_mux", cpu_parents, 4, ++ CLK_SET_RATE_NO_REPARENT, SLCR_ARM_CLK_CTRL, 4, 2, 0, ++ &armclk_lock); + clk = clk_register_divider(NULL, "cpu_div", "cpu_mux", 0, + SLCR_ARM_CLK_CTRL, 8, 6, CLK_DIVIDER_ONE_BASED | + CLK_DIVIDER_ALLOW_ZERO, &armclk_lock); +@@ -293,8 +295,9 @@ static void __init zynq_clk_setup(struct device_node *np) + swdt_ext_clk_mux_parents[i + 1] = dummy_nm; + } + clks[swdt] = clk_register_mux(NULL, clk_output_name[swdt], +- swdt_ext_clk_mux_parents, 2, CLK_SET_RATE_PARENT, +- SLCR_SWDT_CLK_SEL, 0, 1, 0, &swdtclk_lock); ++ swdt_ext_clk_mux_parents, 2, CLK_SET_RATE_PARENT | ++ CLK_SET_RATE_NO_REPARENT, SLCR_SWDT_CLK_SEL, 0, 1, 0, ++ &gem0clk_lock); + + /* DDR clocks */ + clk = clk_register_divider(NULL, "ddr2x_div", "ddrpll", 0, +@@ -356,8 +359,9 @@ static void __init zynq_clk_setup(struct device_node *np) + gem0_mux_parents[i + 1] = of_clk_get_parent_name(np, + idx); + } +- clk = clk_register_mux(NULL, "gem0_mux", periph_parents, 4, 0, +- SLCR_GEM0_CLK_CTRL, 4, 2, 0, &gem0clk_lock); ++ clk = clk_register_mux(NULL, "gem0_mux", periph_parents, 4, ++ CLK_SET_RATE_NO_REPARENT, SLCR_GEM0_CLK_CTRL, 4, 2, 0, ++ &gem0clk_lock); + clk = clk_register_divider(NULL, "gem0_div0", "gem0_mux", 0, + SLCR_GEM0_CLK_CTRL, 8, 6, CLK_DIVIDER_ONE_BASED | + CLK_DIVIDER_ALLOW_ZERO, &gem0clk_lock); +@@ -366,7 +370,7 @@ static void __init zynq_clk_setup(struct device_node *np) + CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO, + &gem0clk_lock); + clk = clk_register_mux(NULL, "gem0_emio_mux", gem0_mux_parents, 2, +- CLK_SET_RATE_PARENT, SLCR_GEM0_CLK_CTRL, 6, 1, 0, ++ CLK_SET_RATE_NO_REPARENT, SLCR_GEM0_CLK_CTRL, 6, 1, 0, + &gem0clk_lock); + clks[gem0] = clk_register_gate(NULL, clk_output_name[gem0], + "gem0_emio_mux", CLK_SET_RATE_PARENT, +@@ -379,8 +383,9 @@ static void __init zynq_clk_setup(struct device_node *np) + gem1_mux_parents[i + 1] = of_clk_get_parent_name(np, + idx); + } +- clk = clk_register_mux(NULL, "gem1_mux", periph_parents, 4, 0, +- SLCR_GEM1_CLK_CTRL, 4, 2, 0, &gem1clk_lock); ++ clk = clk_register_mux(NULL, "gem1_mux", periph_parents, 4, ++ CLK_SET_RATE_NO_REPARENT, SLCR_GEM1_CLK_CTRL, 4, 2, 0, ++ &gem1clk_lock); + clk = clk_register_divider(NULL, "gem1_div0", "gem1_mux", 0, + SLCR_GEM1_CLK_CTRL, 8, 6, CLK_DIVIDER_ONE_BASED | + CLK_DIVIDER_ALLOW_ZERO, &gem1clk_lock); +@@ -389,7 +394,7 @@ static void __init zynq_clk_setup(struct device_node *np) + CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO, + &gem1clk_lock); + clk = clk_register_mux(NULL, "gem1_emio_mux", gem1_mux_parents, 2, +- CLK_SET_RATE_PARENT, SLCR_GEM1_CLK_CTRL, 6, 1, 0, ++ CLK_SET_RATE_NO_REPARENT, SLCR_GEM1_CLK_CTRL, 6, 1, 0, + &gem1clk_lock); + clks[gem1] = clk_register_gate(NULL, clk_output_name[gem1], + "gem1_emio_mux", CLK_SET_RATE_PARENT, +@@ -409,8 +414,9 @@ static void __init zynq_clk_setup(struct device_node *np) + can_mio_mux_parents[i] = dummy_nm; + } + kfree(clk_name); +- clk = clk_register_mux(NULL, "can_mux", periph_parents, 4, 0, +- SLCR_CAN_CLK_CTRL, 4, 2, 0, &canclk_lock); ++ clk = clk_register_mux(NULL, "can_mux", periph_parents, 4, ++ CLK_SET_RATE_NO_REPARENT, SLCR_CAN_CLK_CTRL, 4, 2, 0, ++ &canclk_lock); + clk = clk_register_divider(NULL, "can_div0", "can_mux", 0, + SLCR_CAN_CLK_CTRL, 8, 6, CLK_DIVIDER_ONE_BASED | + CLK_DIVIDER_ALLOW_ZERO, &canclk_lock); +@@ -425,17 +431,21 @@ static void __init zynq_clk_setup(struct device_node *np) + CLK_SET_RATE_PARENT, SLCR_CAN_CLK_CTRL, 1, 0, + &canclk_lock); + clk = clk_register_mux(NULL, "can0_mio_mux", +- can_mio_mux_parents, 54, CLK_SET_RATE_PARENT, +- SLCR_CAN_MIOCLK_CTRL, 0, 6, 0, &canmioclk_lock); ++ can_mio_mux_parents, 54, CLK_SET_RATE_PARENT | ++ CLK_SET_RATE_NO_REPARENT, SLCR_CAN_MIOCLK_CTRL, 0, 6, 0, ++ &canmioclk_lock); + clk = clk_register_mux(NULL, "can1_mio_mux", +- can_mio_mux_parents, 54, CLK_SET_RATE_PARENT, +- SLCR_CAN_MIOCLK_CTRL, 16, 6, 0, &canmioclk_lock); ++ can_mio_mux_parents, 54, CLK_SET_RATE_PARENT | ++ CLK_SET_RATE_NO_REPARENT, SLCR_CAN_MIOCLK_CTRL, 16, 6, ++ 0, &canmioclk_lock); + clks[can0] = clk_register_mux(NULL, clk_output_name[can0], +- can0_mio_mux2_parents, 2, CLK_SET_RATE_PARENT, +- SLCR_CAN_MIOCLK_CTRL, 6, 1, 0, &canmioclk_lock); ++ can0_mio_mux2_parents, 2, CLK_SET_RATE_PARENT | ++ CLK_SET_RATE_NO_REPARENT, SLCR_CAN_MIOCLK_CTRL, 6, 1, 0, ++ &canmioclk_lock); + clks[can1] = clk_register_mux(NULL, clk_output_name[can1], +- can1_mio_mux2_parents, 2, CLK_SET_RATE_PARENT, +- SLCR_CAN_MIOCLK_CTRL, 22, 1, 0, &canmioclk_lock); ++ can1_mio_mux2_parents, 2, CLK_SET_RATE_PARENT | ++ CLK_SET_RATE_NO_REPARENT, SLCR_CAN_MIOCLK_CTRL, 22, 1, ++ 0, &canmioclk_lock); + + for (i = 0; i < ARRAY_SIZE(dbgtrc_emio_input_names); i++) { + int idx = of_property_match_string(np, "clock-names", +@@ -444,13 +454,15 @@ static void __init zynq_clk_setup(struct device_node *np) + dbg_emio_mux_parents[i + 1] = of_clk_get_parent_name(np, + idx); + } +- clk = clk_register_mux(NULL, "dbg_mux", periph_parents, 4, 0, +- SLCR_DBG_CLK_CTRL, 4, 2, 0, &dbgclk_lock); ++ clk = clk_register_mux(NULL, "dbg_mux", periph_parents, 4, ++ CLK_SET_RATE_NO_REPARENT, SLCR_DBG_CLK_CTRL, 4, 2, 0, ++ &dbgclk_lock); + clk = clk_register_divider(NULL, "dbg_div", "dbg_mux", 0, + SLCR_DBG_CLK_CTRL, 8, 6, CLK_DIVIDER_ONE_BASED | + CLK_DIVIDER_ALLOW_ZERO, &dbgclk_lock); +- clk = clk_register_mux(NULL, "dbg_emio_mux", dbg_emio_mux_parents, 2, 0, +- SLCR_DBG_CLK_CTRL, 6, 1, 0, &dbgclk_lock); ++ clk = clk_register_mux(NULL, "dbg_emio_mux", dbg_emio_mux_parents, 2, ++ CLK_SET_RATE_NO_REPARENT, SLCR_DBG_CLK_CTRL, 6, 1, 0, ++ &dbgclk_lock); + clks[dbg_trc] = clk_register_gate(NULL, clk_output_name[dbg_trc], + "dbg_emio_mux", CLK_SET_RATE_PARENT, SLCR_DBG_CLK_CTRL, + 0, 0, &dbgclk_lock); +diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h +index 11860985fecb..de4c2fc08c35 100644 +--- a/include/linux/clk-provider.h ++++ b/include/linux/clk-provider.h +@@ -27,6 +27,7 @@ + #define CLK_IS_ROOT BIT(4) /* root clk, has no parent */ + #define CLK_IS_BASIC BIT(5) /* Basic clk, can't do a to_clk_foo() */ + #define CLK_GET_RATE_NOCACHE BIT(6) /* do not use the cached clk rate */ ++#define CLK_SET_RATE_NO_REPARENT BIT(7) /* don't re-parent on rate change */ + + struct clk_hw; + +-- +1.8.5.rc3 + diff --git a/patches.zynq/0040-Merge-tag-clk-for-linus-3.12-of-git-git.linaro.org-p.patch b/patches.zynq/0040-Merge-tag-clk-for-linus-3.12-of-git-git.linaro.org-p.patch new file mode 100644 index 00000000000000..c0486dbfa0fabc --- /dev/null +++ b/patches.zynq/0040-Merge-tag-clk-for-linus-3.12-of-git-git.linaro.org-p.patch @@ -0,0 +1,78 @@ +From aac5b796df5c5322b8646f83804db6d83aca46c3 Mon Sep 17 00:00:00 2001 +From: Linus Torvalds <torvalds@linux-foundation.org> +Date: Mon, 2 Dec 2013 10:39:23 +0900 +Subject: Merge tag 'clk-for-linus-3.12' of + git://git.linaro.org/people/mturquette/linux + +Pull clock framework changes from Michael Turquette: +"The common clk framework changes for 3.12 are dominated by clock +driver patches, both new drivers and fixes to existing. A high +percentage of these are for Samsung platforms like Exynos. Core +framework fixes and some new features like automagical clock +re-parenting round out the patches" + +* tag 'clk-for-linus-3.12' of git://git.linaro.org/people/mturquette/linux: (102 commits) +clk: only call get_parent if there is one +clk: samsung: exynos5250: Simplify registration of PLL rate tables +clk: samsung: exynos4: Register PLL rate tables for Exynos4x12 +clk: samsung: exynos4: Register PLL rate tables for Exynos4210 +clk: samsung: exynos4: Reorder registration of mout_vpllsrc +clk: samsung: pll: Add support for rate configuration of PLL46xx +clk: samsung: pll: Use new registration method for PLL46xx +clk: samsung: pll: Add support for rate configuration of PLL45xx +clk: samsung: pll: Use new registration method for PLL45xx +clk: samsung: exynos4: Rename exynos4_plls to exynos4x12_plls +clk: samsung: exynos4: Remove checks for DT node +clk: samsung: exynos4: Remove unused static clkdev aliases +clk: samsung: Modify _get_rate() helper to use __clk_lookup() +clk: samsung: exynos4: Use separate aliases for cpufreq related clocks +clocksource: samsung_pwm_timer: Get clock from device tree +ARM: dts: exynos4: Specify PWM clocks in PWM node +pwm: samsung: Update DT bindings documentation to cover clocks +clk: Move symbol export to proper location +clk: fix new_parent dereference before null check +clk: wm831x: Initialise wm831x pointer on init + +(cherry picked from commit bef4a0ab984662d4ccd68d431a7c4ef3daebcb43) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + drivers/clk/zynq/clkc.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +diff --git a/drivers/clk/zynq/clkc.c b/drivers/clk/zynq/clkc.c +index 6169d56fb6f1..cc40fe64f2dc 100644 +--- a/drivers/clk/zynq/clkc.c ++++ b/drivers/clk/zynq/clkc.c +@@ -297,7 +297,7 @@ static void __init zynq_clk_setup(struct device_node *np) + clks[swdt] = clk_register_mux(NULL, clk_output_name[swdt], + swdt_ext_clk_mux_parents, 2, CLK_SET_RATE_PARENT | + CLK_SET_RATE_NO_REPARENT, SLCR_SWDT_CLK_SEL, 0, 1, 0, +- &gem0clk_lock); ++ &swdtclk_lock); + + /* DDR clocks */ + clk = clk_register_divider(NULL, "ddr2x_div", "ddrpll", 0, +@@ -370,7 +370,8 @@ static void __init zynq_clk_setup(struct device_node *np) + CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO, + &gem0clk_lock); + clk = clk_register_mux(NULL, "gem0_emio_mux", gem0_mux_parents, 2, +- CLK_SET_RATE_NO_REPARENT, SLCR_GEM0_CLK_CTRL, 6, 1, 0, ++ CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT, ++ SLCR_GEM0_CLK_CTRL, 6, 1, 0, + &gem0clk_lock); + clks[gem0] = clk_register_gate(NULL, clk_output_name[gem0], + "gem0_emio_mux", CLK_SET_RATE_PARENT, +@@ -394,7 +395,8 @@ static void __init zynq_clk_setup(struct device_node *np) + CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO, + &gem1clk_lock); + clk = clk_register_mux(NULL, "gem1_emio_mux", gem1_mux_parents, 2, +- CLK_SET_RATE_NO_REPARENT, SLCR_GEM1_CLK_CTRL, 6, 1, 0, ++ CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT, ++ SLCR_GEM1_CLK_CTRL, 6, 1, 0, + &gem1clk_lock); + clks[gem1] = clk_register_gate(NULL, clk_output_name[gem1], + "gem1_emio_mux", CLK_SET_RATE_PARENT, +-- +1.8.5.rc3 + diff --git a/patches.zynq/0041-clk-zynq-Fix-possible-memory-leak.patch b/patches.zynq/0041-clk-zynq-Fix-possible-memory-leak.patch new file mode 100644 index 00000000000000..4fd314016a44b9 --- /dev/null +++ b/patches.zynq/0041-clk-zynq-Fix-possible-memory-leak.patch @@ -0,0 +1,64 @@ +From 39b5005431c5abedee2ee97e6083bea8e5c1cf98 Mon Sep 17 00:00:00 2001 +From: Felipe Pena <felipensp@gmail.com> +Date: Mon, 7 Oct 2013 23:25:44 -0300 +Subject: clk/zynq: Fix possible memory leak +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The zynq_clk_register_fclk function can leak memory (fclk_lock) when unable +to alloc memory for fclk_gate_lock + +Signed-off-by: Felipe Pena <felipensp@gmail.com> +Acked-by: Sören Brinkmann <soren.brinkmann@xilinx.com> +Signed-off-by: Mike Turquette <mturquette@linaro.org> +(cherry picked from commit f8fe36f6083a70270a7305f7740b124ff1e8aea7) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + drivers/clk/zynq/clkc.c | 16 +++++++++++++++- + 1 file changed, 15 insertions(+), 1 deletion(-) + +diff --git a/drivers/clk/zynq/clkc.c b/drivers/clk/zynq/clkc.c +index cc40fe64f2dc..10772aa72e4e 100644 +--- a/drivers/clk/zynq/clkc.c ++++ b/drivers/clk/zynq/clkc.c +@@ -117,13 +117,19 @@ static void __init zynq_clk_register_fclk(enum zynq_clk fclk, + goto err; + fclk_gate_lock = kmalloc(sizeof(*fclk_gate_lock), GFP_KERNEL); + if (!fclk_gate_lock) +- goto err; ++ goto err_fclk_gate_lock; + spin_lock_init(fclk_lock); + spin_lock_init(fclk_gate_lock); + + mux_name = kasprintf(GFP_KERNEL, "%s_mux", clk_name); ++ if (!mux_name) ++ goto err_mux_name; + div0_name = kasprintf(GFP_KERNEL, "%s_div0", clk_name); ++ if (!div0_name) ++ goto err_div0_name; + div1_name = kasprintf(GFP_KERNEL, "%s_div1", clk_name); ++ if (!div1_name) ++ goto err_div1_name; + + clk = clk_register_mux(NULL, mux_name, parents, 4, + CLK_SET_RATE_NO_REPARENT, fclk_ctrl_reg, 4, 2, 0, +@@ -147,6 +153,14 @@ static void __init zynq_clk_register_fclk(enum zynq_clk fclk, + + return; + ++err_div1_name: ++ kfree(div0_name); ++err_div0_name: ++ kfree(mux_name); ++err_mux_name: ++ kfree(fclk_gate_lock); ++err_fclk_gate_lock: ++ kfree(fclk_lock); + err: + clks[fclk] = ERR_PTR(-ENOMEM); + } +-- +1.8.5.rc3 + diff --git a/patches.zynq/0042-clk-zynq-Factor-out-PLL-driver.patch b/patches.zynq/0042-clk-zynq-Factor-out-PLL-driver.patch new file mode 100644 index 00000000000000..f660dfc0ed6078 --- /dev/null +++ b/patches.zynq/0042-clk-zynq-Factor-out-PLL-driver.patch @@ -0,0 +1,262 @@ +From c941bcb6045b8a2a89fe393c4a71452996055bf7 Mon Sep 17 00:00:00 2001 +From: Soren Brinkmann <soren.brinkmann@xilinx.com> +Date: Mon, 13 May 2013 10:46:36 -0700 +Subject: clk: zynq: Factor out PLL driver + +Refactor the PLL driver so it works with the clock controller driver. + +Signed-off-by: Soren Brinkmann <soren.brinkmann@xilinx.com> +Signed-off-by: Michal Simek <michal.simek@xilinx.com> +Acked-by: Mike Turquette <mturquette@linaro.org> +(cherry picked from commit 3682af46d55f2c97898b9cc1c8c80afad81f62be) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + drivers/clk/zynq/pll.c | 235 +++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 235 insertions(+) + create mode 100644 drivers/clk/zynq/pll.c + +diff --git a/drivers/clk/zynq/pll.c b/drivers/clk/zynq/pll.c +new file mode 100644 +index 000000000000..47e307c25a7b +--- /dev/null ++++ b/drivers/clk/zynq/pll.c +@@ -0,0 +1,235 @@ ++/* ++ * Zynq PLL driver ++ * ++ * Copyright (C) 2013 Xilinx ++ * ++ * Sören Brinkmann <soren.brinkmann@xilinx.com> ++ * ++ * This program is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License v2 as published by ++ * the Free Software Foundation. ++ * ++ * 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, see <http://www.gnu.org/licenses/>. ++ * ++ */ ++#include <linux/clk/zynq.h> ++#include <linux/clk-provider.h> ++#include <linux/slab.h> ++#include <linux/io.h> ++ ++/** ++ * struct zynq_pll ++ * @hw: Handle between common and hardware-specific interfaces ++ * @pll_ctrl: PLL control register ++ * @pll_status: PLL status register ++ * @lock: Register lock ++ * @lockbit: Indicates the associated PLL_LOCKED bit in the PLL status ++ * register. ++ */ ++struct zynq_pll { ++ struct clk_hw hw; ++ void __iomem *pll_ctrl; ++ void __iomem *pll_status; ++ spinlock_t *lock; ++ u8 lockbit; ++}; ++#define to_zynq_pll(_hw) container_of(_hw, struct zynq_pll, hw) ++ ++/* Register bitfield defines */ ++#define PLLCTRL_FBDIV_MASK 0x7f000 ++#define PLLCTRL_FBDIV_SHIFT 12 ++#define PLLCTRL_BPQUAL_MASK (1 << 3) ++#define PLLCTRL_PWRDWN_MASK 2 ++#define PLLCTRL_PWRDWN_SHIFT 1 ++#define PLLCTRL_RESET_MASK 1 ++#define PLLCTRL_RESET_SHIFT 0 ++ ++/** ++ * zynq_pll_round_rate() - Round a clock frequency ++ * @hw: Handle between common and hardware-specific interfaces ++ * @rate: Desired clock frequency ++ * @prate: Clock frequency of parent clock ++ * Returns frequency closest to @rate the hardware can generate. ++ */ ++static long zynq_pll_round_rate(struct clk_hw *hw, unsigned long rate, ++ unsigned long *prate) ++{ ++ u32 fbdiv; ++ ++ fbdiv = DIV_ROUND_CLOSEST(rate, *prate); ++ if (fbdiv < 13) ++ fbdiv = 13; ++ else if (fbdiv > 66) ++ fbdiv = 66; ++ ++ return *prate * fbdiv; ++} ++ ++/** ++ * zynq_pll_recalc_rate() - Recalculate clock frequency ++ * @hw: Handle between common and hardware-specific interfaces ++ * @parent_rate: Clock frequency of parent clock ++ * Returns current clock frequency. ++ */ ++static unsigned long zynq_pll_recalc_rate(struct clk_hw *hw, ++ unsigned long parent_rate) ++{ ++ struct zynq_pll *clk = to_zynq_pll(hw); ++ u32 fbdiv; ++ ++ /* ++ * makes probably sense to redundantly save fbdiv in the struct ++ * zynq_pll to save the IO access. ++ */ ++ fbdiv = (readl(clk->pll_ctrl) & PLLCTRL_FBDIV_MASK) >> ++ PLLCTRL_FBDIV_SHIFT; ++ ++ return parent_rate * fbdiv; ++} ++ ++/** ++ * zynq_pll_is_enabled - Check if a clock is enabled ++ * @hw: Handle between common and hardware-specific interfaces ++ * Returns 1 if the clock is enabled, 0 otherwise. ++ * ++ * Not sure this is a good idea, but since disabled means bypassed for ++ * this clock implementation we say we are always enabled. ++ */ ++static int zynq_pll_is_enabled(struct clk_hw *hw) ++{ ++ unsigned long flags = 0; ++ u32 reg; ++ struct zynq_pll *clk = to_zynq_pll(hw); ++ ++ spin_lock_irqsave(clk->lock, flags); ++ ++ reg = readl(clk->pll_ctrl); ++ ++ spin_unlock_irqrestore(clk->lock, flags); ++ ++ return !(reg & (PLLCTRL_RESET_MASK | PLLCTRL_PWRDWN_MASK)); ++} ++ ++/** ++ * zynq_pll_enable - Enable clock ++ * @hw: Handle between common and hardware-specific interfaces ++ * Returns 0 on success ++ */ ++static int zynq_pll_enable(struct clk_hw *hw) ++{ ++ unsigned long flags = 0; ++ u32 reg; ++ struct zynq_pll *clk = to_zynq_pll(hw); ++ ++ if (zynq_pll_is_enabled(hw)) ++ return 0; ++ ++ pr_info("PLL: enable\n"); ++ ++ /* Power up PLL and wait for lock */ ++ spin_lock_irqsave(clk->lock, flags); ++ ++ reg = readl(clk->pll_ctrl); ++ reg &= ~(PLLCTRL_RESET_MASK | PLLCTRL_PWRDWN_MASK); ++ writel(reg, clk->pll_ctrl); ++ while (!(readl(clk->pll_status) & (1 << clk->lockbit))) ++ ; ++ ++ spin_unlock_irqrestore(clk->lock, flags); ++ ++ return 0; ++} ++ ++/** ++ * zynq_pll_disable - Disable clock ++ * @hw: Handle between common and hardware-specific interfaces ++ * Returns 0 on success ++ */ ++static void zynq_pll_disable(struct clk_hw *hw) ++{ ++ unsigned long flags = 0; ++ u32 reg; ++ struct zynq_pll *clk = to_zynq_pll(hw); ++ ++ if (!zynq_pll_is_enabled(hw)) ++ return; ++ ++ pr_info("PLL: shutdown\n"); ++ ++ /* shut down PLL */ ++ spin_lock_irqsave(clk->lock, flags); ++ ++ reg = readl(clk->pll_ctrl); ++ reg |= PLLCTRL_RESET_MASK | PLLCTRL_PWRDWN_MASK; ++ writel(reg, clk->pll_ctrl); ++ ++ spin_unlock_irqrestore(clk->lock, flags); ++} ++ ++static const struct clk_ops zynq_pll_ops = { ++ .enable = zynq_pll_enable, ++ .disable = zynq_pll_disable, ++ .is_enabled = zynq_pll_is_enabled, ++ .round_rate = zynq_pll_round_rate, ++ .recalc_rate = zynq_pll_recalc_rate ++}; ++ ++/** ++ * clk_register_zynq_pll() - Register PLL with the clock framework ++ * @np Pointer to the DT device node ++ */ ++struct clk *clk_register_zynq_pll(const char *name, const char *parent, ++ void __iomem *pll_ctrl, void __iomem *pll_status, u8 lock_index, ++ spinlock_t *lock) ++{ ++ struct zynq_pll *pll; ++ struct clk *clk; ++ u32 reg; ++ const char *parent_arr[1] = {parent}; ++ unsigned long flags = 0; ++ struct clk_init_data initd = { ++ .name = name, ++ .parent_names = parent_arr, ++ .ops = &zynq_pll_ops, ++ .num_parents = 1, ++ .flags = 0 ++ }; ++ ++ pll = kmalloc(sizeof(*pll), GFP_KERNEL); ++ if (!pll) { ++ pr_err("%s: Could not allocate Zynq PLL clk.\n", __func__); ++ return ERR_PTR(-ENOMEM); ++ } ++ ++ /* Populate the struct */ ++ pll->hw.init = &initd; ++ pll->pll_ctrl = pll_ctrl; ++ pll->pll_status = pll_status; ++ pll->lockbit = lock_index; ++ pll->lock = lock; ++ ++ spin_lock_irqsave(pll->lock, flags); ++ ++ reg = readl(pll->pll_ctrl); ++ reg &= ~PLLCTRL_BPQUAL_MASK; ++ writel(reg, pll->pll_ctrl); ++ ++ spin_unlock_irqrestore(pll->lock, flags); ++ ++ clk = clk_register(NULL, &pll->hw); ++ if (WARN_ON(IS_ERR(clk))) ++ goto free_pll; ++ ++ return clk; ++ ++free_pll: ++ kfree(pll); ++ ++ return clk; ++} +-- +1.8.5.rc3 + diff --git a/patches.zynq/0043-clk-zynq-pll-Fix-documentation-for-PLL-register-func.patch b/patches.zynq/0043-clk-zynq-pll-Fix-documentation-for-PLL-register-func.patch new file mode 100644 index 00000000000000..0e297c4e31774c --- /dev/null +++ b/patches.zynq/0043-clk-zynq-pll-Fix-documentation-for-PLL-register-func.patch @@ -0,0 +1,36 @@ +From bb636310249b365d2bb98cdc56ac4b31643016fa Mon Sep 17 00:00:00 2001 +From: Soren Brinkmann <soren.brinkmann@xilinx.com> +Date: Fri, 19 Jul 2013 10:16:44 -0700 +Subject: clk/zynq/pll: Fix documentation for PLL register function + +Signed-off-by: Soren Brinkmann <soren.brinkmann@xilinx.com> +Signed-off-by: Michal Simek <michal.simek@xilinx.com> +(cherry picked from commit 14924ba288921c536a72e71baeb14322ece44b39) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + drivers/clk/zynq/pll.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/drivers/clk/zynq/pll.c b/drivers/clk/zynq/pll.c +index 47e307c25a7b..6daa7b6702ed 100644 +--- a/drivers/clk/zynq/pll.c ++++ b/drivers/clk/zynq/pll.c +@@ -182,7 +182,13 @@ static const struct clk_ops zynq_pll_ops = { + + /** + * clk_register_zynq_pll() - Register PLL with the clock framework +- * @np Pointer to the DT device node ++ * @name PLL name ++ * @parent Parent clock name ++ * @pll_ctrl Pointer to PLL control register ++ * @pll_status Pointer to PLL status register ++ * @lock_index Bit index to this PLL's lock status bit in @pll_status ++ * @lock Register lock ++ * Returns handle to the registered clock. + */ + struct clk *clk_register_zynq_pll(const char *name, const char *parent, + void __iomem *pll_ctrl, void __iomem *pll_status, u8 lock_index, +-- +1.8.5.rc3 + diff --git a/patches.zynq/0044-clk-zynq-pll-Use-defines-for-fbdiv-min-max-values.patch b/patches.zynq/0044-clk-zynq-pll-Use-defines-for-fbdiv-min-max-values.patch new file mode 100644 index 00000000000000..9803e32de10b3c --- /dev/null +++ b/patches.zynq/0044-clk-zynq-pll-Use-defines-for-fbdiv-min-max-values.patch @@ -0,0 +1,49 @@ +From c9ae039aa0af3eac0f187339fcffb1b0e71c0a96 Mon Sep 17 00:00:00 2001 +From: Soren Brinkmann <soren.brinkmann@xilinx.com> +Date: Fri, 19 Jul 2013 10:16:45 -0700 +Subject: clk/zynq/pll: Use #defines for fbdiv min/max values + +Use more descriptive #defines for the minimum and maximum PLL +feedback divider. + +Signed-off-by: Soren Brinkmann <soren.brinkmann@xilinx.com> +Signed-off-by: Michal Simek <michal.simek@xilinx.com> +(cherry picked from commit 353dc6c47d67c83f7cc20334f8deb251674e6864) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + drivers/clk/zynq/pll.c | 11 +++++++---- + 1 file changed, 7 insertions(+), 4 deletions(-) + +diff --git a/drivers/clk/zynq/pll.c b/drivers/clk/zynq/pll.c +index 6daa7b6702ed..3226f54fa595 100644 +--- a/drivers/clk/zynq/pll.c ++++ b/drivers/clk/zynq/pll.c +@@ -50,6 +50,9 @@ struct zynq_pll { + #define PLLCTRL_RESET_MASK 1 + #define PLLCTRL_RESET_SHIFT 0 + ++#define PLL_FBDIV_MIN 13 ++#define PLL_FBDIV_MAX 66 ++ + /** + * zynq_pll_round_rate() - Round a clock frequency + * @hw: Handle between common and hardware-specific interfaces +@@ -63,10 +66,10 @@ static long zynq_pll_round_rate(struct clk_hw *hw, unsigned long rate, + u32 fbdiv; + + fbdiv = DIV_ROUND_CLOSEST(rate, *prate); +- if (fbdiv < 13) +- fbdiv = 13; +- else if (fbdiv > 66) +- fbdiv = 66; ++ if (fbdiv < PLL_FBDIV_MIN) ++ fbdiv = PLL_FBDIV_MIN; ++ else if (fbdiv > PLL_FBDIV_MAX) ++ fbdiv = PLL_FBDIV_MAX; + + return *prate * fbdiv; + } +-- +1.8.5.rc3 + diff --git a/patches.zynq/0045-spi-spi-xilinx-Add-run-run-time-endian-detection.patch b/patches.zynq/0045-spi-spi-xilinx-Add-run-run-time-endian-detection.patch new file mode 100644 index 00000000000000..fc0c067e8b990f --- /dev/null +++ b/patches.zynq/0045-spi-spi-xilinx-Add-run-run-time-endian-detection.patch @@ -0,0 +1,127 @@ +From 779734a79029a3703ddb2eda774fb6cbb3dfeb62 Mon Sep 17 00:00:00 2001 +From: Michal Simek <michal.simek@xilinx.com> +Date: Tue, 4 Jun 2013 16:02:36 +0200 +Subject: spi: spi-xilinx: Add run run-time endian detection + +Do not load endian value from platform data +and rather autodetect it. + +Signed-off-by: Michal Simek <michal.simek@xilinx.com> +Signed-off-by: Mark Brown <broonie@linaro.org> +(cherry picked from commit 082339bc63cccf8ea49b1f3cf4ee39ce00742849) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + drivers/mfd/timberdale.c | 1 - + drivers/spi/spi-xilinx.c | 29 +++++++++++++++++++++-------- + include/linux/spi/xilinx_spi.h | 1 - + 3 files changed, 21 insertions(+), 10 deletions(-) + +diff --git a/drivers/mfd/timberdale.c b/drivers/mfd/timberdale.c +index 59e0ee247e86..0c1fcbc23d04 100644 +--- a/drivers/mfd/timberdale.c ++++ b/drivers/mfd/timberdale.c +@@ -145,7 +145,6 @@ static struct spi_board_info timberdale_spi_8bit_board_info[] = { + + static struct xspi_platform_data timberdale_xspi_platform_data = { + .num_chipselect = 3, +- .little_endian = true, + /* bits per word and devices will be filled in runtime depending + * on the HW config + */ +diff --git a/drivers/spi/spi-xilinx.c b/drivers/spi/spi-xilinx.c +index 34d18dcfa0db..882f2cf3edbd 100644 +--- a/drivers/spi/spi-xilinx.c ++++ b/drivers/spi/spi-xilinx.c +@@ -30,6 +30,7 @@ + */ + #define XSPI_CR_OFFSET 0x60 /* Control Register */ + ++#define XSPI_CR_LOOP 0x01 + #define XSPI_CR_ENABLE 0x02 + #define XSPI_CR_MASTER_MODE 0x04 + #define XSPI_CR_CPOL 0x08 +@@ -355,11 +356,12 @@ static const struct of_device_id xilinx_spi_of_match[] = { + MODULE_DEVICE_TABLE(of, xilinx_spi_of_match); + + struct spi_master *xilinx_spi_init(struct device *dev, struct resource *mem, +- u32 irq, s16 bus_num, int num_cs, int little_endian, int bits_per_word) ++ u32 irq, s16 bus_num, int num_cs, int bits_per_word) + { + struct spi_master *master; + struct xilinx_spi *xspi; + int ret; ++ u32 tmp; + + master = spi_alloc_master(dev, sizeof(struct xilinx_spi)); + if (!master) +@@ -392,13 +394,25 @@ struct spi_master *xilinx_spi_init(struct device *dev, struct resource *mem, + + xspi->mem = *mem; + xspi->irq = irq; +- if (little_endian) { +- xspi->read_fn = xspi_read32; +- xspi->write_fn = xspi_write32; +- } else { ++ ++ /* ++ * Detect endianess on the IP via loop bit in CR. Detection ++ * must be done before reset is sent because incorrect reset ++ * value generates error interrupt. ++ * Setup little endian helper functions first and try to use them ++ * and check if bit was correctly setup or not. ++ */ ++ xspi->read_fn = xspi_read32; ++ xspi->write_fn = xspi_write32; ++ ++ xspi->write_fn(XSPI_CR_LOOP, xspi->regs + XSPI_CR_OFFSET); ++ tmp = xspi->read_fn(xspi->regs + XSPI_CR_OFFSET); ++ tmp &= XSPI_CR_LOOP; ++ if (tmp != XSPI_CR_LOOP) { + xspi->read_fn = xspi_read32_be; + xspi->write_fn = xspi_write32_be; + } ++ + xspi->bits_per_word = bits_per_word; + if (xspi->bits_per_word == 8) { + xspi->tx_fn = xspi_tx8; +@@ -462,14 +476,13 @@ static int xilinx_spi_probe(struct platform_device *dev) + { + struct xspi_platform_data *pdata; + struct resource *r; +- int irq, num_cs = 0, little_endian = 0, bits_per_word = 8; ++ int irq, num_cs = 0, bits_per_word = 8; + struct spi_master *master; + u8 i; + + pdata = dev->dev.platform_data; + if (pdata) { + num_cs = pdata->num_chipselect; +- little_endian = pdata->little_endian; + bits_per_word = pdata->bits_per_word; + } + +@@ -501,7 +514,7 @@ static int xilinx_spi_probe(struct platform_device *dev) + return -ENXIO; + + master = xilinx_spi_init(&dev->dev, r, irq, dev->id, num_cs, +- little_endian, bits_per_word); ++ bits_per_word); + if (!master) + return -ENODEV; + +diff --git a/include/linux/spi/xilinx_spi.h b/include/linux/spi/xilinx_spi.h +index 6f17278810b0..333ecdfee0d9 100644 +--- a/include/linux/spi/xilinx_spi.h ++++ b/include/linux/spi/xilinx_spi.h +@@ -11,7 +11,6 @@ + */ + struct xspi_platform_data { + u16 num_chipselect; +- bool little_endian; + u8 bits_per_word; + struct spi_board_info *devices; + u8 num_devices; +-- +1.8.5.rc3 + diff --git a/patches.zynq/0046-spi-spi-xilinx-Remove-redundant-platform_set_drvdata.patch b/patches.zynq/0046-spi-spi-xilinx-Remove-redundant-platform_set_drvdata.patch new file mode 100644 index 00000000000000..b6df6eae459873 --- /dev/null +++ b/patches.zynq/0046-spi-spi-xilinx-Remove-redundant-platform_set_drvdata.patch @@ -0,0 +1,33 @@ +From 3bee85fa29ad04923a703f5c3dccda442f35a15d Mon Sep 17 00:00:00 2001 +From: Sachin Kamat <sachin.kamat@linaro.org> +Date: Fri, 31 May 2013 17:17:49 +0530 +Subject: spi: spi-xilinx: Remove redundant platform_set_drvdata() + +Setting platform data to NULL is not necessary. +Also fixes the following sparse warning: +drivers/spi/spi-xilinx.c:508:35: warning: Using plain integer as NULL pointer + +Signed-off-by: Sachin Kamat <sachin.kamat@linaro.org> +Signed-off-by: Mark Brown <broonie@linaro.org> +(cherry picked from commit 913b19660e166e718d419cccd753c3990881f17c) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + drivers/spi/spi-xilinx.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/drivers/spi/spi-xilinx.c b/drivers/spi/spi-xilinx.c +index 882f2cf3edbd..a6c475b43dcc 100644 +--- a/drivers/spi/spi-xilinx.c ++++ b/drivers/spi/spi-xilinx.c +@@ -530,7 +530,6 @@ static int xilinx_spi_probe(struct platform_device *dev) + static int xilinx_spi_remove(struct platform_device *dev) + { + xilinx_spi_deinit(platform_get_drvdata(dev)); +- platform_set_drvdata(dev, 0); + + return 0; + } +-- +1.8.5.rc3 + diff --git a/patches.zynq/0047-spi-spi-xilinx-cleanup-a-check-in-xilinx_spi_txrx_bu.patch b/patches.zynq/0047-spi-spi-xilinx-cleanup-a-check-in-xilinx_spi_txrx_bu.patch new file mode 100644 index 00000000000000..fbfdfa242e5193 --- /dev/null +++ b/patches.zynq/0047-spi-spi-xilinx-cleanup-a-check-in-xilinx_spi_txrx_bu.patch @@ -0,0 +1,39 @@ +From cbe328377241c633b4b543cc0df99ff7483f2ec4 Mon Sep 17 00:00:00 2001 +From: "dan.carpenter@oracle.com" <dan.carpenter@oracle.com> +Date: Sun, 9 Jun 2013 16:07:28 +0300 +Subject: spi: spi-xilinx: cleanup a check in xilinx_spi_txrx_bufs() + +'!' has higher precedence than comparisons so the original condition +is equivalent to "if (xspi->remaining_bytes == 0)". This makes the +static checkers complain. + +xspi->remaining_bytes is signed and from looking at the code +briefly, I think it might be able to go negative. I suspect that +going negative may cause a bug, but I don't have the hardware and +can't test. + +Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com> +Signed-off-by: Mark Brown <broonie@linaro.org> +(cherry picked from commit e33d085d11e54bc9fb07b2555cd104d8e7b3089b) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + drivers/spi/spi-xilinx.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/spi/spi-xilinx.c b/drivers/spi/spi-xilinx.c +index a6c475b43dcc..09a942852593 100644 +--- a/drivers/spi/spi-xilinx.c ++++ b/drivers/spi/spi-xilinx.c +@@ -316,7 +316,7 @@ static int xilinx_spi_txrx_bufs(struct spi_device *spi, struct spi_transfer *t) + } + + /* See if there is more data to send */ +- if (!xspi->remaining_bytes > 0) ++ if (xspi->remaining_bytes <= 0) + break; + } + +-- +1.8.5.rc3 + diff --git a/patches.zynq/0048-spi-xilinx-Convert-to-devm_ioremap_resource.patch b/patches.zynq/0048-spi-xilinx-Convert-to-devm_ioremap_resource.patch new file mode 100644 index 00000000000000..6886527ebdfbec --- /dev/null +++ b/patches.zynq/0048-spi-xilinx-Convert-to-devm_ioremap_resource.patch @@ -0,0 +1,79 @@ +From db08d8a5dba3caf55f6e9bd8c799046a80bbecc4 Mon Sep 17 00:00:00 2001 +From: Mark Brown <broonie@linaro.org> +Date: Mon, 1 Jul 2013 20:33:01 +0100 +Subject: spi/xilinx: Convert to devm_ioremap_resource() + +Saves code and reduces the possibility of error. + +Signed-off-by: Mark Brown <broonie@linaro.org> +(cherry picked from commit c40537d008ab1b4fe2f12641cca1462de10a95f7) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + drivers/spi/spi-xilinx.c | 20 +++++--------------- + 1 file changed, 5 insertions(+), 15 deletions(-) + +diff --git a/drivers/spi/spi-xilinx.c b/drivers/spi/spi-xilinx.c +index 09a942852593..6dd660818f05 100644 +--- a/drivers/spi/spi-xilinx.c ++++ b/drivers/spi/spi-xilinx.c +@@ -378,14 +378,10 @@ struct spi_master *xilinx_spi_init(struct device *dev, struct resource *mem, + xspi->bitbang.master->setup = xilinx_spi_setup; + init_completion(&xspi->done); + +- if (!request_mem_region(mem->start, resource_size(mem), +- XILINX_SPI_NAME)) ++ xspi->regs = devm_ioremap_resource(dev, mem); ++ if (IS_ERR(xspi->regs)) { ++ ret = PTR_ERR(xspi->regs); + goto put_master; +- +- xspi->regs = ioremap(mem->start, resource_size(mem)); +- if (xspi->regs == NULL) { +- dev_warn(dev, "ioremap failure\n"); +- goto map_failed; + } + + master->bus_num = bus_num; +@@ -424,7 +420,7 @@ struct spi_master *xilinx_spi_init(struct device *dev, struct resource *mem, + xspi->tx_fn = xspi_tx32; + xspi->rx_fn = xspi_rx32; + } else +- goto unmap_io; ++ goto put_master; + + + /* SPI controller initializations */ +@@ -433,7 +429,7 @@ struct spi_master *xilinx_spi_init(struct device *dev, struct resource *mem, + /* Register for SPI Interrupt */ + ret = request_irq(xspi->irq, xilinx_spi_irq, 0, XILINX_SPI_NAME, xspi); + if (ret) +- goto unmap_io; ++ goto put_master; + + ret = spi_bitbang_start(&xspi->bitbang); + if (ret) { +@@ -447,10 +443,6 @@ struct spi_master *xilinx_spi_init(struct device *dev, struct resource *mem, + + free_irq: + free_irq(xspi->irq, xspi); +-unmap_io: +- iounmap(xspi->regs); +-map_failed: +- release_mem_region(mem->start, resource_size(mem)); + put_master: + spi_master_put(master); + return NULL; +@@ -465,9 +457,7 @@ void xilinx_spi_deinit(struct spi_master *master) + + spi_bitbang_stop(&xspi->bitbang); + free_irq(xspi->irq, xspi); +- iounmap(xspi->regs); + +- release_mem_region(xspi->mem.start, resource_size(&xspi->mem)); + spi_master_put(xspi->bitbang.master); + } + EXPORT_SYMBOL(xilinx_spi_deinit); +-- +1.8.5.rc3 + diff --git a/patches.zynq/0049-spi-xilinx-Remove-remains-of-of_platform-device-regi.patch b/patches.zynq/0049-spi-xilinx-Remove-remains-of-of_platform-device-regi.patch new file mode 100644 index 00000000000000..58894b00c9c651 --- /dev/null +++ b/patches.zynq/0049-spi-xilinx-Remove-remains-of-of_platform-device-regi.patch @@ -0,0 +1,228 @@ +From 0dd0b5d53c655f5181e2bca2c29a1301007a0ca3 Mon Sep 17 00:00:00 2001 +From: Mark Brown <broonie@linaro.org> +Date: Wed, 3 Jul 2013 12:05:42 +0100 +Subject: spi/xilinx: Remove remains of of_platform device registration + +In the past there used to be a separate platform device type for device +tree systems so the probe and removal functions were split into generic +and bus sections. Since this is no longer the case simplify the code (and +remove some unprototyped exports) by factoring everything into the bus +probe() and remove(). + +Signed-off-by: Mark Brown <broonie@linaro.org> +(cherry picked from commit d81c0bbbf84086568b559bee59e4a93aba4a6e0f) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + drivers/spi/spi-xilinx.c | 145 ++++++++++++++++++++--------------------------- + 1 file changed, 63 insertions(+), 82 deletions(-) + +diff --git a/drivers/spi/spi-xilinx.c b/drivers/spi/spi-xilinx.c +index 6dd660818f05..dc9df0cf086d 100644 +--- a/drivers/spi/spi-xilinx.c ++++ b/drivers/spi/spi-xilinx.c +@@ -355,17 +355,51 @@ static const struct of_device_id xilinx_spi_of_match[] = { + }; + MODULE_DEVICE_TABLE(of, xilinx_spi_of_match); + +-struct spi_master *xilinx_spi_init(struct device *dev, struct resource *mem, +- u32 irq, s16 bus_num, int num_cs, int bits_per_word) ++static int xilinx_spi_probe(struct platform_device *dev) + { +- struct spi_master *master; + struct xilinx_spi *xspi; +- int ret; ++ struct xspi_platform_data *pdata; ++ struct resource *r; ++ int ret, irq, num_cs = 0, bits_per_word = 8; ++ struct spi_master *master; + u32 tmp; ++ u8 i; ++ ++ pdata = dev->dev.platform_data; ++ if (pdata) { ++ num_cs = pdata->num_chipselect; ++ bits_per_word = pdata->bits_per_word; ++ } ++ ++#ifdef CONFIG_OF ++ if (dev->dev.of_node) { ++ const __be32 *prop; ++ int len; ++ ++ /* number of slave select bits is required */ ++ prop = of_get_property(dev->dev.of_node, "xlnx,num-ss-bits", ++ &len); ++ if (prop && len >= sizeof(*prop)) ++ num_cs = __be32_to_cpup(prop); ++ } ++#endif + +- master = spi_alloc_master(dev, sizeof(struct xilinx_spi)); ++ if (!num_cs) { ++ dev_err(&dev->dev, "Missing slave select configuration data\n"); ++ return -EINVAL; ++ } ++ ++ r = platform_get_resource(dev, IORESOURCE_MEM, 0); ++ if (!r) ++ return -ENODEV; ++ ++ irq = platform_get_irq(dev, 0); ++ if (irq < 0) ++ return -ENXIO; ++ ++ master = spi_alloc_master(&dev->dev, sizeof(struct xilinx_spi)); + if (!master) +- return NULL; ++ return -ENODEV; + + /* the spi->mode bits understood by this driver: */ + master->mode_bits = SPI_CPOL | SPI_CPHA; +@@ -378,17 +412,17 @@ struct spi_master *xilinx_spi_init(struct device *dev, struct resource *mem, + xspi->bitbang.master->setup = xilinx_spi_setup; + init_completion(&xspi->done); + +- xspi->regs = devm_ioremap_resource(dev, mem); ++ xspi->regs = devm_ioremap_resource(&dev->dev, r); + if (IS_ERR(xspi->regs)) { + ret = PTR_ERR(xspi->regs); + goto put_master; + } + +- master->bus_num = bus_num; ++ master->bus_num = dev->dev.id; + master->num_chipselect = num_cs; +- master->dev.of_node = dev->of_node; ++ master->dev.of_node = dev->dev.of_node; + +- xspi->mem = *mem; ++ xspi->mem = *r; + xspi->irq = irq; + + /* +@@ -419,8 +453,10 @@ struct spi_master *xilinx_spi_init(struct device *dev, struct resource *mem, + } else if (xspi->bits_per_word == 32) { + xspi->tx_fn = xspi_tx32; + xspi->rx_fn = xspi_rx32; +- } else ++ } else { ++ ret = -EINVAL; + goto put_master; ++ } + + + /* SPI controller initializations */ +@@ -433,93 +469,38 @@ struct spi_master *xilinx_spi_init(struct device *dev, struct resource *mem, + + ret = spi_bitbang_start(&xspi->bitbang); + if (ret) { +- dev_err(dev, "spi_bitbang_start FAILED\n"); ++ dev_err(&dev->dev, "spi_bitbang_start FAILED\n"); + goto free_irq; + } + +- dev_info(dev, "at 0x%08llX mapped to 0x%p, irq=%d\n", +- (unsigned long long)mem->start, xspi->regs, xspi->irq); +- return master; ++ dev_info(&dev->dev, "at 0x%08llX mapped to 0x%p, irq=%d\n", ++ (unsigned long long)r->start, xspi->regs, xspi->irq); ++ ++ if (pdata) { ++ for (i = 0; i < pdata->num_devices; i++) ++ spi_new_device(master, pdata->devices + i); ++ } ++ ++ platform_set_drvdata(dev, master); ++ return 0; + + free_irq: + free_irq(xspi->irq, xspi); + put_master: + spi_master_put(master); +- return NULL; ++ ++ return ret; + } +-EXPORT_SYMBOL(xilinx_spi_init); + +-void xilinx_spi_deinit(struct spi_master *master) ++static int xilinx_spi_remove(struct platform_device *dev) + { +- struct xilinx_spi *xspi; +- +- xspi = spi_master_get_devdata(master); ++ struct spi_master *master = platform_get_drvdata(dev); ++ struct xilinx_spi *xspi = spi_master_get_devdata(master); + + spi_bitbang_stop(&xspi->bitbang); + free_irq(xspi->irq, xspi); + + spi_master_put(xspi->bitbang.master); +-} +-EXPORT_SYMBOL(xilinx_spi_deinit); +- +-static int xilinx_spi_probe(struct platform_device *dev) +-{ +- struct xspi_platform_data *pdata; +- struct resource *r; +- int irq, num_cs = 0, bits_per_word = 8; +- struct spi_master *master; +- u8 i; +- +- pdata = dev->dev.platform_data; +- if (pdata) { +- num_cs = pdata->num_chipselect; +- bits_per_word = pdata->bits_per_word; +- } +- +-#ifdef CONFIG_OF +- if (dev->dev.of_node) { +- const __be32 *prop; +- int len; +- +- /* number of slave select bits is required */ +- prop = of_get_property(dev->dev.of_node, "xlnx,num-ss-bits", +- &len); +- if (prop && len >= sizeof(*prop)) +- num_cs = __be32_to_cpup(prop); +- } +-#endif +- +- if (!num_cs) { +- dev_err(&dev->dev, "Missing slave select configuration data\n"); +- return -EINVAL; +- } +- +- +- r = platform_get_resource(dev, IORESOURCE_MEM, 0); +- if (!r) +- return -ENODEV; +- +- irq = platform_get_irq(dev, 0); +- if (irq < 0) +- return -ENXIO; +- +- master = xilinx_spi_init(&dev->dev, r, irq, dev->id, num_cs, +- bits_per_word); +- if (!master) +- return -ENODEV; +- +- if (pdata) { +- for (i = 0; i < pdata->num_devices; i++) +- spi_new_device(master, pdata->devices + i); +- } +- +- platform_set_drvdata(dev, master); +- return 0; +-} +- +-static int xilinx_spi_remove(struct platform_device *dev) +-{ +- xilinx_spi_deinit(platform_get_drvdata(dev)); + + return 0; + } +-- +1.8.5.rc3 + diff --git a/patches.zynq/0050-spi-xilinx-Refer-to-platform-device-as-pdev-in-probe.patch b/patches.zynq/0050-spi-xilinx-Refer-to-platform-device-as-pdev-in-probe.patch new file mode 100644 index 00000000000000..301cbbcb451bb0 --- /dev/null +++ b/patches.zynq/0050-spi-xilinx-Refer-to-platform-device-as-pdev-in-probe.patch @@ -0,0 +1,135 @@ +From 0fd5137aabbcf9212b33c07566bab6732c90b1f1 Mon Sep 17 00:00:00 2001 +From: Mark Brown <broonie@linaro.org> +Date: Fri, 5 Jul 2013 11:24:26 +0100 +Subject: spi/xilinx: Refer to platform device as pdev in probe() and remove() + +This is a more traditional name and makes things a bit clearer when +referring to actual struct devices as we do frequently during probe(). + +Signed-off-by: Mark Brown <broonie@linaro.org> +Acked-by: Michal Simek <michal.simek@xilinx.com> +(cherry picked from commit 7cb2abd05fe1f9aea70b8ee38004b60bc882ffb5) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + drivers/spi/spi-xilinx.c | 33 +++++++++++++++++---------------- + 1 file changed, 17 insertions(+), 16 deletions(-) + +diff --git a/drivers/spi/spi-xilinx.c b/drivers/spi/spi-xilinx.c +index dc9df0cf086d..faae198ba7ea 100644 +--- a/drivers/spi/spi-xilinx.c ++++ b/drivers/spi/spi-xilinx.c +@@ -355,7 +355,7 @@ static const struct of_device_id xilinx_spi_of_match[] = { + }; + MODULE_DEVICE_TABLE(of, xilinx_spi_of_match); + +-static int xilinx_spi_probe(struct platform_device *dev) ++static int xilinx_spi_probe(struct platform_device *pdev) + { + struct xilinx_spi *xspi; + struct xspi_platform_data *pdata; +@@ -365,19 +365,19 @@ static int xilinx_spi_probe(struct platform_device *dev) + u32 tmp; + u8 i; + +- pdata = dev->dev.platform_data; ++ pdata = pdev->dev.platform_data; + if (pdata) { + num_cs = pdata->num_chipselect; + bits_per_word = pdata->bits_per_word; + } + + #ifdef CONFIG_OF +- if (dev->dev.of_node) { ++ if (pdev->dev.of_node) { + const __be32 *prop; + int len; + + /* number of slave select bits is required */ +- prop = of_get_property(dev->dev.of_node, "xlnx,num-ss-bits", ++ prop = of_get_property(pdev->dev.of_node, "xlnx,num-ss-bits", + &len); + if (prop && len >= sizeof(*prop)) + num_cs = __be32_to_cpup(prop); +@@ -385,19 +385,20 @@ static int xilinx_spi_probe(struct platform_device *dev) + #endif + + if (!num_cs) { +- dev_err(&dev->dev, "Missing slave select configuration data\n"); ++ dev_err(&pdev->dev, ++ "Missing slave select configuration data\n"); + return -EINVAL; + } + +- r = platform_get_resource(dev, IORESOURCE_MEM, 0); ++ r = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!r) + return -ENODEV; + +- irq = platform_get_irq(dev, 0); ++ irq = platform_get_irq(pdev, 0); + if (irq < 0) + return -ENXIO; + +- master = spi_alloc_master(&dev->dev, sizeof(struct xilinx_spi)); ++ master = spi_alloc_master(&pdev->dev, sizeof(struct xilinx_spi)); + if (!master) + return -ENODEV; + +@@ -412,15 +413,15 @@ static int xilinx_spi_probe(struct platform_device *dev) + xspi->bitbang.master->setup = xilinx_spi_setup; + init_completion(&xspi->done); + +- xspi->regs = devm_ioremap_resource(&dev->dev, r); ++ xspi->regs = devm_ioremap_resource(&pdev->dev, r); + if (IS_ERR(xspi->regs)) { + ret = PTR_ERR(xspi->regs); + goto put_master; + } + +- master->bus_num = dev->dev.id; ++ master->bus_num = pdev->dev.id; + master->num_chipselect = num_cs; +- master->dev.of_node = dev->dev.of_node; ++ master->dev.of_node = pdev->dev.of_node; + + xspi->mem = *r; + xspi->irq = irq; +@@ -469,11 +470,11 @@ static int xilinx_spi_probe(struct platform_device *dev) + + ret = spi_bitbang_start(&xspi->bitbang); + if (ret) { +- dev_err(&dev->dev, "spi_bitbang_start FAILED\n"); ++ dev_err(&pdev->dev, "spi_bitbang_start FAILED\n"); + goto free_irq; + } + +- dev_info(&dev->dev, "at 0x%08llX mapped to 0x%p, irq=%d\n", ++ dev_info(&pdev->dev, "at 0x%08llX mapped to 0x%p, irq=%d\n", + (unsigned long long)r->start, xspi->regs, xspi->irq); + + if (pdata) { +@@ -481,7 +482,7 @@ static int xilinx_spi_probe(struct platform_device *dev) + spi_new_device(master, pdata->devices + i); + } + +- platform_set_drvdata(dev, master); ++ platform_set_drvdata(pdev, master); + return 0; + + free_irq: +@@ -492,9 +493,9 @@ put_master: + return ret; + } + +-static int xilinx_spi_remove(struct platform_device *dev) ++static int xilinx_spi_remove(struct platform_device *pdev) + { +- struct spi_master *master = platform_get_drvdata(dev); ++ struct spi_master *master = platform_get_drvdata(pdev); + struct xilinx_spi *xspi = spi_master_get_devdata(master); + + spi_bitbang_stop(&xspi->bitbang); +-- +1.8.5.rc3 + diff --git a/patches.zynq/0051-spi-xilinx-Remove-CONFIG_OF-from-the-driver.patch b/patches.zynq/0051-spi-xilinx-Remove-CONFIG_OF-from-the-driver.patch new file mode 100644 index 00000000000000..8a4d99c37ec634 --- /dev/null +++ b/patches.zynq/0051-spi-xilinx-Remove-CONFIG_OF-from-the-driver.patch @@ -0,0 +1,39 @@ +From 8e3fa31d013096a9c7451a6db8674955e31decde Mon Sep 17 00:00:00 2001 +From: Michal Simek <michal.simek@xilinx.com> +Date: Mon, 8 Jul 2013 15:29:14 +0200 +Subject: spi/xilinx: Remove CONFIG_OF from the driver + +dev.of_node is in struct device all the time. + +Signed-off-by: Michal Simek <michal.simek@xilinx.com> +Signed-off-by: Mark Brown <broonie@linaro.org> +(cherry picked from commit 5586c09e19b0dea5c1b4fd9838ca73575def223f) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + drivers/spi/spi-xilinx.c | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/drivers/spi/spi-xilinx.c b/drivers/spi/spi-xilinx.c +index faae198ba7ea..5c98859f3cd6 100644 +--- a/drivers/spi/spi-xilinx.c ++++ b/drivers/spi/spi-xilinx.c +@@ -371,7 +371,6 @@ static int xilinx_spi_probe(struct platform_device *pdev) + bits_per_word = pdata->bits_per_word; + } + +-#ifdef CONFIG_OF + if (pdev->dev.of_node) { + const __be32 *prop; + int len; +@@ -382,7 +381,6 @@ static int xilinx_spi_probe(struct platform_device *pdev) + if (prop && len >= sizeof(*prop)) + num_cs = __be32_to_cpup(prop); + } +-#endif + + if (!num_cs) { + dev_err(&pdev->dev, +-- +1.8.5.rc3 + diff --git a/patches.zynq/0052-spi-xilinx-Clean-ioremap-calling.patch b/patches.zynq/0052-spi-xilinx-Clean-ioremap-calling.patch new file mode 100644 index 00000000000000..f8b304413aac25 --- /dev/null +++ b/patches.zynq/0052-spi-xilinx-Clean-ioremap-calling.patch @@ -0,0 +1,82 @@ +From abf247b64fcc5e48ad84b8f7f93a004bd39d3605 Mon Sep 17 00:00:00 2001 +From: Michal Simek <michal.simek@xilinx.com> +Date: Mon, 8 Jul 2013 15:29:15 +0200 +Subject: spi/xilinx: Clean ioremap calling + +devm_ioremap_resource() automatically checks that +struct resource is initialized. +Also group platform_get_resource() and devm_ioremap_resource() +together. +And remove mem resource from struct xilinx_spi. + +Signed-off-by: Michal Simek <michal.simek@xilinx.com> +Signed-off-by: Mark Brown <broonie@linaro.org> +(cherry picked from commit ad3fdbcaf98dc1258f7ee1503703e7fcbc0d8d8e) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + drivers/spi/spi-xilinx.c | 13 ++++--------- + 1 file changed, 4 insertions(+), 9 deletions(-) + +diff --git a/drivers/spi/spi-xilinx.c b/drivers/spi/spi-xilinx.c +index 5c98859f3cd6..c3ea6cad568f 100644 +--- a/drivers/spi/spi-xilinx.c ++++ b/drivers/spi/spi-xilinx.c +@@ -80,7 +80,6 @@ struct xilinx_spi { + /* bitbang has to be first */ + struct spi_bitbang bitbang; + struct completion done; +- struct resource mem; /* phys mem */ + void __iomem *regs; /* virt. address of the control registers */ + + u32 irq; +@@ -359,7 +358,7 @@ static int xilinx_spi_probe(struct platform_device *pdev) + { + struct xilinx_spi *xspi; + struct xspi_platform_data *pdata; +- struct resource *r; ++ struct resource *res; + int ret, irq, num_cs = 0, bits_per_word = 8; + struct spi_master *master; + u32 tmp; +@@ -388,10 +387,6 @@ static int xilinx_spi_probe(struct platform_device *pdev) + return -EINVAL; + } + +- r = platform_get_resource(pdev, IORESOURCE_MEM, 0); +- if (!r) +- return -ENODEV; +- + irq = platform_get_irq(pdev, 0); + if (irq < 0) + return -ENXIO; +@@ -411,7 +406,8 @@ static int xilinx_spi_probe(struct platform_device *pdev) + xspi->bitbang.master->setup = xilinx_spi_setup; + init_completion(&xspi->done); + +- xspi->regs = devm_ioremap_resource(&pdev->dev, r); ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ xspi->regs = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(xspi->regs)) { + ret = PTR_ERR(xspi->regs); + goto put_master; +@@ -421,7 +417,6 @@ static int xilinx_spi_probe(struct platform_device *pdev) + master->num_chipselect = num_cs; + master->dev.of_node = pdev->dev.of_node; + +- xspi->mem = *r; + xspi->irq = irq; + + /* +@@ -473,7 +468,7 @@ static int xilinx_spi_probe(struct platform_device *pdev) + } + + dev_info(&pdev->dev, "at 0x%08llX mapped to 0x%p, irq=%d\n", +- (unsigned long long)r->start, xspi->regs, xspi->irq); ++ (unsigned long long)res->start, xspi->regs, xspi->irq); + + if (pdata) { + for (i = 0; i < pdata->num_devices; i++) +-- +1.8.5.rc3 + diff --git a/patches.zynq/0053-spi-xilinx-Use-of_property_read_u32-for-reading-valu.patch b/patches.zynq/0053-spi-xilinx-Use-of_property_read_u32-for-reading-valu.patch new file mode 100644 index 00000000000000..75151f1cb8beaa --- /dev/null +++ b/patches.zynq/0053-spi-xilinx-Use-of_property_read_u32-for-reading-valu.patch @@ -0,0 +1,44 @@ +From 3b0944d8f563cdb3a7f7766d112f3cd7ab0aa2f1 Mon Sep 17 00:00:00 2001 +From: Michal Simek <michal.simek@xilinx.com> +Date: Mon, 8 Jul 2013 15:29:17 +0200 +Subject: spi/xilinx: Use of_property_read_u32 for reading value from node + +It simplifies driver probing. + +Signed-off-by: Michal Simek <michal.simek@xilinx.com> +Signed-off-by: Mark Brown <broonie@linaro.org> +(cherry picked from commit be3acdff943f46c32e9b2f453f0033bbae01a804) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + drivers/spi/spi-xilinx.c | 14 +++----------- + 1 file changed, 3 insertions(+), 11 deletions(-) + +diff --git a/drivers/spi/spi-xilinx.c b/drivers/spi/spi-xilinx.c +index c3ea6cad568f..1c3372084bc8 100644 +--- a/drivers/spi/spi-xilinx.c ++++ b/drivers/spi/spi-xilinx.c +@@ -368,17 +368,9 @@ static int xilinx_spi_probe(struct platform_device *pdev) + if (pdata) { + num_cs = pdata->num_chipselect; + bits_per_word = pdata->bits_per_word; +- } +- +- if (pdev->dev.of_node) { +- const __be32 *prop; +- int len; +- +- /* number of slave select bits is required */ +- prop = of_get_property(pdev->dev.of_node, "xlnx,num-ss-bits", +- &len); +- if (prop && len >= sizeof(*prop)) +- num_cs = __be32_to_cpup(prop); ++ } else { ++ of_property_read_u32(pdev->dev.of_node, "xlnx,num-ss-bits", ++ &num_cs); + } + + if (!num_cs) { +-- +1.8.5.rc3 + diff --git a/patches.zynq/0054-spi-xilinx-Simplify-irq-allocation.patch b/patches.zynq/0054-spi-xilinx-Simplify-irq-allocation.patch new file mode 100644 index 00000000000000..ea490044ae0879 --- /dev/null +++ b/patches.zynq/0054-spi-xilinx-Simplify-irq-allocation.patch @@ -0,0 +1,107 @@ +From 323e7ddbed538321ad3ed02299d4f305a18db001 Mon Sep 17 00:00:00 2001 +From: Michal Simek <michal.simek@xilinx.com> +Date: Tue, 9 Jul 2013 18:05:16 +0200 +Subject: spi/xilinx: Simplify irq allocation + +Use devm_request_irq() for irq allocation which +simplify driver code. + +Signed-off-by: Michal Simek <michal.simek@xilinx.com> +Signed-off-by: Mark Brown <broonie@linaro.org> +(cherry picked from commit 7b3b7432ae7848a269671921393148ff1aae3881) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + drivers/spi/spi-xilinx.c | 29 ++++++++++++++++------------- + 1 file changed, 16 insertions(+), 13 deletions(-) + +diff --git a/drivers/spi/spi-xilinx.c b/drivers/spi/spi-xilinx.c +index 1c3372084bc8..fea815c2bc95 100644 +--- a/drivers/spi/spi-xilinx.c ++++ b/drivers/spi/spi-xilinx.c +@@ -359,7 +359,7 @@ static int xilinx_spi_probe(struct platform_device *pdev) + struct xilinx_spi *xspi; + struct xspi_platform_data *pdata; + struct resource *res; +- int ret, irq, num_cs = 0, bits_per_word = 8; ++ int ret, num_cs = 0, bits_per_word = 8; + struct spi_master *master; + u32 tmp; + u8 i; +@@ -379,10 +379,6 @@ static int xilinx_spi_probe(struct platform_device *pdev) + return -EINVAL; + } + +- irq = platform_get_irq(pdev, 0); +- if (irq < 0) +- return -ENXIO; +- + master = spi_alloc_master(&pdev->dev, sizeof(struct xilinx_spi)); + if (!master) + return -ENODEV; +@@ -409,8 +405,6 @@ static int xilinx_spi_probe(struct platform_device *pdev) + master->num_chipselect = num_cs; + master->dev.of_node = pdev->dev.of_node; + +- xspi->irq = irq; +- + /* + * Detect endianess on the IP via loop bit in CR. Detection + * must be done before reset is sent because incorrect reset +@@ -444,19 +438,25 @@ static int xilinx_spi_probe(struct platform_device *pdev) + goto put_master; + } + +- + /* SPI controller initializations */ + xspi_init_hw(xspi); + ++ xspi->irq = platform_get_irq(pdev, 0); ++ if (xspi->irq < 0) { ++ ret = xspi->irq; ++ goto put_master; ++ } ++ + /* Register for SPI Interrupt */ +- ret = request_irq(xspi->irq, xilinx_spi_irq, 0, XILINX_SPI_NAME, xspi); ++ ret = devm_request_irq(&pdev->dev, xspi->irq, xilinx_spi_irq, 0, ++ dev_name(&pdev->dev), xspi); + if (ret) + goto put_master; + + ret = spi_bitbang_start(&xspi->bitbang); + if (ret) { + dev_err(&pdev->dev, "spi_bitbang_start FAILED\n"); +- goto free_irq; ++ goto put_master; + } + + dev_info(&pdev->dev, "at 0x%08llX mapped to 0x%p, irq=%d\n", +@@ -470,8 +470,6 @@ static int xilinx_spi_probe(struct platform_device *pdev) + platform_set_drvdata(pdev, master); + return 0; + +-free_irq: +- free_irq(xspi->irq, xspi); + put_master: + spi_master_put(master); + +@@ -482,9 +480,14 @@ static int xilinx_spi_remove(struct platform_device *pdev) + { + struct spi_master *master = platform_get_drvdata(pdev); + struct xilinx_spi *xspi = spi_master_get_devdata(master); ++ void __iomem *regs_base = xspi->regs; + + spi_bitbang_stop(&xspi->bitbang); +- free_irq(xspi->irq, xspi); ++ ++ /* Disable all the interrupts just in case */ ++ xspi->write_fn(0, regs_base + XIPIF_V123B_IIER_OFFSET); ++ /* Disable the global IPIF interrupt */ ++ xspi->write_fn(0, regs_base + XIPIF_V123B_DGIER_OFFSET); + + spi_master_put(xspi->bitbang.master); + +-- +1.8.5.rc3 + diff --git a/patches.zynq/0055-spi-xilinx-signedness-issue-checking-platform_get_ir.patch b/patches.zynq/0055-spi-xilinx-signedness-issue-checking-platform_get_ir.patch new file mode 100644 index 00000000000000..6e4c6aff5295ba --- /dev/null +++ b/patches.zynq/0055-spi-xilinx-signedness-issue-checking-platform_get_ir.patch @@ -0,0 +1,34 @@ +From 5dc3d5b675ac2e9b1399d7fc1fbd753ae4a0fa8a Mon Sep 17 00:00:00 2001 +From: Dan Carpenter <dan.carpenter@oracle.com> +Date: Wed, 17 Jul 2013 18:34:48 +0300 +Subject: spi/xilinx: signedness issue checking platform_get_irq() + +In xilinx_spi_probe() we use xspi->irq to store negative error codes so +it has to be signed. We weren't going to use the upper bit any way so +this is fine. + +Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com> +Signed-off-by: Mark Brown <broonie@linaro.org> +(cherry picked from commit 9ca1273bb9d35c81bfb73215556bf794a73a2d83) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + drivers/spi/spi-xilinx.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/spi/spi-xilinx.c b/drivers/spi/spi-xilinx.c +index fea815c2bc95..0f4a093ca8d5 100644 +--- a/drivers/spi/spi-xilinx.c ++++ b/drivers/spi/spi-xilinx.c +@@ -82,7 +82,7 @@ struct xilinx_spi { + struct completion done; + void __iomem *regs; /* virt. address of the control registers */ + +- u32 irq; ++ int irq; + + u8 *rx_ptr; /* pointer in the Tx buffer */ + const u8 *tx_ptr; /* pointer in the Rx buffer */ +-- +1.8.5.rc3 + diff --git a/patches.zynq/0056-spi-bitbang-Drop-empty-setup-functions.patch b/patches.zynq/0056-spi-bitbang-Drop-empty-setup-functions.patch new file mode 100644 index 00000000000000..014a379ecbc6ca --- /dev/null +++ b/patches.zynq/0056-spi-bitbang-Drop-empty-setup-functions.patch @@ -0,0 +1,54 @@ +From debd2e0bd920027d3bb19d25d41d9df04c2377da Mon Sep 17 00:00:00 2001 +From: Mark Brown <broonie@linaro.org> +Date: Fri, 9 Aug 2013 17:26:37 +0100 +Subject: spi/bitbang: Drop empty setup() functions + +Now that the bitbang core does not require a setup() function we can +drop the check in the altera, nuc900 and xilinx drivers. + +Signed-off-by: Mark Brown <broonie@linaro.org> +(cherry picked from commit 30af9b558a56200bda5febd140d5b826581d1f15 +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp>) + +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + drivers/spi/spi-xilinx.c | 16 ---------------- + 1 file changed, 16 deletions(-) + +diff --git a/drivers/spi/spi-xilinx.c b/drivers/spi/spi-xilinx.c +index 0f4a093ca8d5..dec7e71a833c 100644 +--- a/drivers/spi/spi-xilinx.c ++++ b/drivers/spi/spi-xilinx.c +@@ -232,21 +232,6 @@ static int xilinx_spi_setup_transfer(struct spi_device *spi, + return 0; + } + +-static int xilinx_spi_setup(struct spi_device *spi) +-{ +- /* always return 0, we can not check the number of bits. +- * There are cases when SPI setup is called before any driver is +- * there, in that case the SPI core defaults to 8 bits, which we +- * do not support in some cases. But if we return an error, the +- * SPI device would not be registered and no driver can get hold of it +- * When the driver is there, it will call SPI setup again with the +- * correct number of bits per transfer. +- * If a driver setups with the wrong bit number, it will fail when +- * it tries to do a transfer +- */ +- return 0; +-} +- + static void xilinx_spi_fill_tx_fifo(struct xilinx_spi *xspi) + { + u8 sr; +@@ -391,7 +376,6 @@ static int xilinx_spi_probe(struct platform_device *pdev) + xspi->bitbang.chipselect = xilinx_spi_chipselect; + xspi->bitbang.setup_transfer = xilinx_spi_setup_transfer; + xspi->bitbang.txrx_bufs = xilinx_spi_txrx_bufs; +- xspi->bitbang.master->setup = xilinx_spi_setup; + init_completion(&xspi->done); + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); +-- +1.8.5.rc3 + diff --git a/patches.zynq/0057-spi-use-dev_get_platdata.patch b/patches.zynq/0057-spi-use-dev_get_platdata.patch new file mode 100644 index 00000000000000..01530137119ded --- /dev/null +++ b/patches.zynq/0057-spi-use-dev_get_platdata.patch @@ -0,0 +1,34 @@ +From 7369d65d3586d733226f05af08cc7899ef2d9c2f Mon Sep 17 00:00:00 2001 +From: Jingoo Han <jg1.han@samsung.com> +Date: Tue, 30 Jul 2013 16:58:59 +0900 +Subject: spi: use dev_get_platdata() + +Use the wrapper function for retrieving the platform data instead of +accessing dev->platform_data directly. + +Signed-off-by: Jingoo Han <jg1.han@samsung.com> +Signed-off-by: Mark Brown <broonie@linaro.org> +(cherry picked from commit 8074cf063e410a2c0cf1704c3b31002e21f5df7c +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp>) + +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + drivers/spi/spi-xilinx.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/spi/spi-xilinx.c b/drivers/spi/spi-xilinx.c +index dec7e71a833c..0bf1b2c457a1 100644 +--- a/drivers/spi/spi-xilinx.c ++++ b/drivers/spi/spi-xilinx.c +@@ -349,7 +349,7 @@ static int xilinx_spi_probe(struct platform_device *pdev) + u32 tmp; + u8 i; + +- pdata = pdev->dev.platform_data; ++ pdata = dev_get_platdata(&pdev->dev); + if (pdata) { + num_cs = pdata->num_chipselect; + bits_per_word = pdata->bits_per_word; +-- +1.8.5.rc3 + diff --git a/patches.zynq/0058-spi-bitbang-Let-spi_bitbang_start-take-a-reference-t.patch b/patches.zynq/0058-spi-bitbang-Let-spi_bitbang_start-take-a-reference-t.patch new file mode 100644 index 00000000000000..79e949d48b56b3 --- /dev/null +++ b/patches.zynq/0058-spi-bitbang-Let-spi_bitbang_start-take-a-reference-t.patch @@ -0,0 +1,53 @@ +From 81a4e56c65f5df67e124ad02e2a4e93940bf2ed2 Mon Sep 17 00:00:00 2001 +From: Axel Lin <axel.lin@ingics.com> +Date: Tue, 10 Sep 2013 15:43:41 +0800 +Subject: spi: bitbang: Let spi_bitbang_start() take a reference to master + +Many drivers that use bitbang library have a leak on probe error paths. +This is because once a spi_master_get() call succeeds, we need an additional +spi_master_put() call to free the memory. + +Fix this issue by moving the code taking a reference to master to +spi_bitbang_start(), so spi_bitbang_start() will take a reference to master on +success. With this change, the caller is responsible for calling +spi_bitbang_stop() to decrement the reference and spi_master_put() as +counterpart of spi_alloc_master() to prevent a memory leak. + +So now we have below patten for drivers using bitbang library: + +probe: +spi_alloc_master -> Init reference count to 1 +spi_bitbang_start -> Increment reference count +remove: +spi_bitbang_stop -> Decrement reference count +spi_master_put -> Decrement reference count (reference count reaches 0) + +Fixup all users accordingly. + +Signed-off-by: Axel Lin <axel.lin@ingics.com> +Suggested-by: Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de> +Acked-by: Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de> +Signed-off-by: Mark Brown <broonie@linaro.org> +(cherry picked from commit 94c69f765f1b4a658d96905ec59928e3e3e07e6a) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + drivers/spi/spi-xilinx.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/spi/spi-xilinx.c b/drivers/spi/spi-xilinx.c +index 0bf1b2c457a1..ec3a83f52ea2 100644 +--- a/drivers/spi/spi-xilinx.c ++++ b/drivers/spi/spi-xilinx.c +@@ -372,7 +372,7 @@ static int xilinx_spi_probe(struct platform_device *pdev) + master->mode_bits = SPI_CPOL | SPI_CPHA; + + xspi = spi_master_get_devdata(master); +- xspi->bitbang.master = spi_master_get(master); ++ xspi->bitbang.master = master; + xspi->bitbang.chipselect = xilinx_spi_chipselect; + xspi->bitbang.setup_transfer = xilinx_spi_setup_transfer; + xspi->bitbang.txrx_bufs = xilinx_spi_txrx_bufs; +-- +1.8.5.rc3 + diff --git a/patches.zynq/0059-Input-xilinx_ps2-remove-redundant-platform_set_drvda.patch b/patches.zynq/0059-Input-xilinx_ps2-remove-redundant-platform_set_drvda.patch new file mode 100644 index 00000000000000..7bf5e7ca568f14 --- /dev/null +++ b/patches.zynq/0059-Input-xilinx_ps2-remove-redundant-platform_set_drvda.patch @@ -0,0 +1,34 @@ +From cda8b02933c2e3d6798b785f06905e27264ee01d Mon Sep 17 00:00:00 2001 +From: Sachin Kamat <sachin.kamat@linaro.org> +Date: Mon, 27 May 2013 23:40:33 -0700 +Subject: Input: xilinx_ps2 - remove redundant platform_set_drvdata() + +Commit 0998d06310 (device-core: Ensure drvdata = NULL when no +driver is bound) removes the need to set driver data field to +NULL. + +Signed-off-by: Sachin Kamat <sachin.kamat@linaro.org> +Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com> +(cherry picked from commit f6e63f8032571bb58d054071edfd35d88f9dd07a) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + drivers/input/serio/xilinx_ps2.c | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/drivers/input/serio/xilinx_ps2.c b/drivers/input/serio/xilinx_ps2.c +index 17be85948ffd..4b7662a17ae9 100644 +--- a/drivers/input/serio/xilinx_ps2.c ++++ b/drivers/input/serio/xilinx_ps2.c +@@ -349,8 +349,6 @@ static int xps2_of_remove(struct platform_device *of_dev) + + kfree(drvdata); + +- platform_set_drvdata(of_dev, NULL); +- + return 0; + } + +-- +1.8.5.rc3 + diff --git a/patches.zynq/0060-drivers-clean-up-prom.h-implicit-includes.patch b/patches.zynq/0060-drivers-clean-up-prom.h-implicit-includes.patch new file mode 100644 index 00000000000000..43c52543ee7305 --- /dev/null +++ b/patches.zynq/0060-drivers-clean-up-prom.h-implicit-includes.patch @@ -0,0 +1,32 @@ +From 189f21efa238c81683514631d6d8845f1b863d48 Mon Sep 17 00:00:00 2001 +From: Rob Herring <rob.herring@calxeda.com> +Date: Tue, 17 Sep 2013 14:28:33 -0500 +Subject: drivers: clean-up prom.h implicit includes + +Powerpc is a mess of implicit includes by prom.h. Add the necessary +explicit includes to drivers in preparation of prom.h cleanup. + +Signed-off-by: Rob Herring <rob.herring@calxeda.com> +Acked-by: Grant Likely <grant.likely@linaro.org> +(cherry picked from commit 5af5073004071cedd0343eee51d77955037ec6f3) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + drivers/input/serio/xilinx_ps2.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/input/serio/xilinx_ps2.c b/drivers/input/serio/xilinx_ps2.c +index 4b7662a17ae9..b90eb4fb2b5b 100644 +--- a/drivers/input/serio/xilinx_ps2.c ++++ b/drivers/input/serio/xilinx_ps2.c +@@ -25,6 +25,7 @@ + #include <linux/io.h> + #include <linux/of_address.h> + #include <linux/of_device.h> ++#include <linux/of_irq.h> + #include <linux/of_platform.h> + + #define DRIVER_NAME "xilinx_ps2" +-- +1.8.5.rc3 + diff --git a/patches.zynq/0061-of-irq-Use-irq_of_parse_and_map.patch b/patches.zynq/0061-of-irq-Use-irq_of_parse_and_map.patch new file mode 100644 index 00000000000000..cfa1a98da55123 --- /dev/null +++ b/patches.zynq/0061-of-irq-Use-irq_of_parse_and_map.patch @@ -0,0 +1,60 @@ +From 73b01d8722b34add7077b92b98a69b2123f749aa Mon Sep 17 00:00:00 2001 +From: Thierry Reding <thierry.reding@gmail.com> +Date: Wed, 18 Sep 2013 15:24:44 +0200 +Subject: of/irq: Use irq_of_parse_and_map() + +Replace some instances of of_irq_map_one()/irq_create_of_mapping() and +of_irq_to_resource() by the simpler equivalent irq_of_parse_and_map(). + +Signed-off-by: Thierry Reding <treding@nvidia.com> +Acked-by: Rob Herring <rob.herring@calxeda.com> +[grant.likely: resolved conflicts with core code renames] +Signed-off-by: Grant Likely <grant.likely@linaro.org> +(cherry picked from commit f7578496a671a96e501f16a5104893275e32c33a) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> + +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + drivers/input/serio/xilinx_ps2.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/drivers/input/serio/xilinx_ps2.c b/drivers/input/serio/xilinx_ps2.c +index b90eb4fb2b5b..dfbcd872f95e 100644 +--- a/drivers/input/serio/xilinx_ps2.c ++++ b/drivers/input/serio/xilinx_ps2.c +@@ -236,12 +236,12 @@ static void sxps2_close(struct serio *pserio) + */ + static int xps2_of_probe(struct platform_device *ofdev) + { +- struct resource r_irq; /* Interrupt resources */ + struct resource r_mem; /* IO mem resources */ + struct xps2data *drvdata; + struct serio *serio; + struct device *dev = &ofdev->dev; + resource_size_t remap_size, phys_addr; ++ unsigned int irq; + int error; + + dev_info(dev, "Device Tree Probing \'%s\'\n", +@@ -255,7 +255,8 @@ static int xps2_of_probe(struct platform_device *ofdev) + } + + /* Get IRQ for the device */ +- if (!of_irq_to_resource(ofdev->dev.of_node, 0, &r_irq)) { ++ irq = irq_of_parse_and_map(ofdev->dev.of_node, 0); ++ if (!irq) { + dev_err(dev, "no IRQ found\n"); + return -ENODEV; + } +@@ -268,7 +269,7 @@ static int xps2_of_probe(struct platform_device *ofdev) + } + + spin_lock_init(&drvdata->lock); +- drvdata->irq = r_irq.start; ++ drvdata->irq = irq; + drvdata->serio = serio; + drvdata->dev = dev; + +-- +1.8.5.rc3 + diff --git a/patches.zynq/0062-char-xilinx_hwicap-Remove-casting-the-return-value-w.patch b/patches.zynq/0062-char-xilinx_hwicap-Remove-casting-the-return-value-w.patch new file mode 100644 index 00000000000000..31e857e996f17a --- /dev/null +++ b/patches.zynq/0062-char-xilinx_hwicap-Remove-casting-the-return-value-w.patch @@ -0,0 +1,35 @@ +From 4275a801013a2f960af28ac9ffc95f656744cf88 Mon Sep 17 00:00:00 2001 +From: Jingoo Han <jg1.han@samsung.com> +Date: Mon, 9 Sep 2013 14:14:50 +0900 +Subject: char: xilinx_hwicap: Remove casting the return value which is a void + pointer + +Casting the return value which is a void pointer is redundant. +The conversion from void pointer to any other pointer type is +guaranteed by the C programming language. + +Signed-off-by: Jingoo Han <jg1.han@samsung.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +(cherry picked from commit 20055477566958e751a20290aa45ae21bd4b5e11) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + drivers/char/xilinx_hwicap/xilinx_hwicap.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/char/xilinx_hwicap/xilinx_hwicap.c b/drivers/char/xilinx_hwicap/xilinx_hwicap.c +index 5224da5202d3..a7f65c2b2cb5 100644 +--- a/drivers/char/xilinx_hwicap/xilinx_hwicap.c ++++ b/drivers/char/xilinx_hwicap/xilinx_hwicap.c +@@ -721,7 +721,7 @@ static int hwicap_remove(struct device *dev) + { + struct hwicap_drvdata *drvdata; + +- drvdata = (struct hwicap_drvdata *)dev_get_drvdata(dev); ++ drvdata = dev_get_drvdata(dev); + + if (!drvdata) + return 0; +-- +1.8.5.rc3 + diff --git a/patches.zynq/0063-char-hwicap-Remove-unnecessary-dev_set_drvdata.patch b/patches.zynq/0063-char-hwicap-Remove-unnecessary-dev_set_drvdata.patch new file mode 100644 index 00000000000000..de4367093b9afc --- /dev/null +++ b/patches.zynq/0063-char-hwicap-Remove-unnecessary-dev_set_drvdata.patch @@ -0,0 +1,32 @@ +From 38a2ec46d4dc7b60d9b919ebeee5ad7458a1eb63 Mon Sep 17 00:00:00 2001 +From: Michal Simek <michal.simek@xilinx.com> +Date: Mon, 30 Sep 2013 09:28:36 +0200 +Subject: char: hwicap: Remove unnecessary dev_set_drvdata() + +Driver core clears the driver data to NULL after device_release +or on probe failure, so just remove it from here. + +Signed-off-by: Michal Simek <michal.simek@xilinx.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +(cherry picked from commit 12b3af3096cdfb0613da374021167868c6abc9ce) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + drivers/char/xilinx_hwicap/xilinx_hwicap.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/drivers/char/xilinx_hwicap/xilinx_hwicap.c b/drivers/char/xilinx_hwicap/xilinx_hwicap.c +index a7f65c2b2cb5..f6345f932e46 100644 +--- a/drivers/char/xilinx_hwicap/xilinx_hwicap.c ++++ b/drivers/char/xilinx_hwicap/xilinx_hwicap.c +@@ -731,7 +731,6 @@ static int hwicap_remove(struct device *dev) + iounmap(drvdata->base_address); + release_mem_region(drvdata->mem_start, drvdata->mem_size); + kfree(drvdata); +- dev_set_drvdata(dev, NULL); + + mutex_lock(&icap_sem); + probed_devices[MINOR(dev->devt)-XHWICAP_MINOR] = 0; +-- +1.8.5.rc3 + diff --git a/patches.zynq/0064-char-xilinx_hwicap-Checkpatch.pl-cleanup.patch b/patches.zynq/0064-char-xilinx_hwicap-Checkpatch.pl-cleanup.patch new file mode 100644 index 00000000000000..340aecff2e3898 --- /dev/null +++ b/patches.zynq/0064-char-xilinx_hwicap-Checkpatch.pl-cleanup.patch @@ -0,0 +1,33 @@ +From 52e527233de5b99f0b08bd5d926cfc5c2c924c1a Mon Sep 17 00:00:00 2001 +From: Michal Simek <michal.simek@xilinx.com> +Date: Thu, 23 May 2013 14:52:33 +0200 +Subject: char: xilinx_hwicap: Checkpatch.pl cleanup + +Remove checkpatch warning: +WARNING: Use #include <linux/io.h> instead of <asm/io.h> + +Signed-off-by: Michal Simek <michal.simek@xilinx.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +(cherry picked from commit 1dd24daef9c5a4b51f4981a9c65a36a32b2ea98a) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + drivers/char/xilinx_hwicap/xilinx_hwicap.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/char/xilinx_hwicap/xilinx_hwicap.h b/drivers/char/xilinx_hwicap/xilinx_hwicap.h +index d31ee23c9f13..96677fc7ea4d 100644 +--- a/drivers/char/xilinx_hwicap/xilinx_hwicap.h ++++ b/drivers/char/xilinx_hwicap/xilinx_hwicap.h +@@ -37,7 +37,7 @@ + #include <linux/cdev.h> + #include <linux/platform_device.h> + +-#include <asm/io.h> ++#include <linux/io.h> + + struct hwicap_drvdata { + u32 write_buffer_in_use; /* Always in [0,3] */ +-- +1.8.5.rc3 + diff --git a/patches.zynq/0065-char-xilinx_hwicap-Fix-typo-in-comment-and-extend-it.patch b/patches.zynq/0065-char-xilinx_hwicap-Fix-typo-in-comment-and-extend-it.patch new file mode 100644 index 00000000000000..fb09fc55b46ba6 --- /dev/null +++ b/patches.zynq/0065-char-xilinx_hwicap-Fix-typo-in-comment-and-extend-it.patch @@ -0,0 +1,42 @@ +From d412e999fddebea19b40024ae935489fb0ed870b Mon Sep 17 00:00:00 2001 +From: Michal Simek <monstr@monstr.eu> +Date: Thu, 23 May 2013 14:52:34 +0200 +Subject: char: xilinx_hwicap: Fix typo in comment and extend it + +s/regsiter/register/ + +Use origin comment from the first driver version +which also explain the usage of XHI_MAX_RETRIES better. + +Signed-off-by: Michal Simek <monstr@monstr.eu> +Signed-off-by: Michal Simek <michal.simek@xilinx.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +(cherry picked from commit 84524cf43d693746896782628466205ccc193e0d) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + drivers/char/xilinx_hwicap/xilinx_hwicap.h | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/drivers/char/xilinx_hwicap/xilinx_hwicap.h b/drivers/char/xilinx_hwicap/xilinx_hwicap.h +index 96677fc7ea4d..38b145eaf24d 100644 +--- a/drivers/char/xilinx_hwicap/xilinx_hwicap.h ++++ b/drivers/char/xilinx_hwicap/xilinx_hwicap.h +@@ -85,7 +85,13 @@ struct hwicap_driver_config { + void (*reset)(struct hwicap_drvdata *drvdata); + }; + +-/* Number of times to poll the done regsiter */ ++/* Number of times to poll the done register. This has to be large ++ * enough to allow an entire configuration to complete. If an entire ++ * page (4kb) is configured at once, that could take up to 4k cycles ++ * with a byte-wide icap interface. In most cases, this driver is ++ * used with a much smaller fifo, but this should be sufficient in the ++ * worst case. ++ */ + #define XHI_MAX_RETRIES 5000 + + /************ Constant Definitions *************/ +-- +1.8.5.rc3 + diff --git a/patches.zynq/0066-watchdog-xilinx-Fix-driver-header.patch b/patches.zynq/0066-watchdog-xilinx-Fix-driver-header.patch new file mode 100644 index 00000000000000..ef2ec994de8199 --- /dev/null +++ b/patches.zynq/0066-watchdog-xilinx-Fix-driver-header.patch @@ -0,0 +1,67 @@ +From f87fd16bb0d675fadda290df5969a7d1f394b0a1 Mon Sep 17 00:00:00 2001 +From: Michal Simek <michal.simek@xilinx.com> +Date: Fri, 31 May 2013 07:56:33 +0200 +Subject: watchdog: xilinx: Fix driver header + +- Remove reference for IP version +- Fix header coding style +- Remove notes which are visible from the code +- Fix driver license according to header + +Signed-off-by: Michal Simek <michal.simek@xilinx.com> +Reviewed-by: Guenter Roeck <linux@roeck-us.net> +Signed-off-by: Wim Van Sebroeck <wim@iguana.be> +(cherry picked from commit 9419c07ccebf6080159b4440dab9b3e484c96d7a) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + drivers/watchdog/of_xilinx_wdt.c | 30 ++++++++++-------------------- + 1 file changed, 10 insertions(+), 20 deletions(-) + +diff --git a/drivers/watchdog/of_xilinx_wdt.c b/drivers/watchdog/of_xilinx_wdt.c +index 2761ddb08501..d4a35ab89e01 100644 +--- a/drivers/watchdog/of_xilinx_wdt.c ++++ b/drivers/watchdog/of_xilinx_wdt.c +@@ -1,23 +1,13 @@ + /* +-* of_xilinx_wdt.c 1.01 A Watchdog Device Driver for Xilinx xps_timebase_wdt +-* +-* (C) Copyright 2011 (Alejandro Cabrera <aldaya@gmail.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 the Free Software Foundation; either version +-* 2 of the License, or (at your option) any later version. +-* +-* ----------------------- +-* 30-May-2011 Alejandro Cabrera <aldaya@gmail.com> +-* - If "xlnx,wdt-enable-once" wasn't found on device tree the +-* module will use CONFIG_WATCHDOG_NOWAYOUT +-* - If the device tree parameters ("clock-frequency" and +-* "xlnx,wdt-interval") wasn't found the driver won't +-* know the wdt reset interval +-*/ ++ * Watchdog Device Driver for Xilinx axi/xps_timebase_wdt ++ * ++ * (C) Copyright 2011 (Alejandro Cabrera <aldaya@gmail.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 the Free Software Foundation; either version ++ * 2 of the License, or (at your option) any later version. ++ */ + + #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +@@ -413,5 +403,5 @@ module_platform_driver(xwdt_driver); + + MODULE_AUTHOR("Alejandro Cabrera <aldaya@gmail.com>"); + MODULE_DESCRIPTION("Xilinx Watchdog driver"); +-MODULE_LICENSE("GPL"); ++MODULE_LICENSE("GPL v2"); + MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); +-- +1.8.5.rc3 + diff --git a/patches.zynq/0067-watchdog-xilinx-Setup-the-origin-compatible-string.patch b/patches.zynq/0067-watchdog-xilinx-Setup-the-origin-compatible-string.patch new file mode 100644 index 00000000000000..f7858cd0c28adf --- /dev/null +++ b/patches.zynq/0067-watchdog-xilinx-Setup-the-origin-compatible-string.patch @@ -0,0 +1,33 @@ +From 8ed5d9d9e4d3af298977fc4488cbb712b5d82576 Mon Sep 17 00:00:00 2001 +From: Michal Simek <michal.simek@xilinx.com> +Date: Fri, 31 May 2013 07:56:34 +0200 +Subject: watchdog: xilinx: Setup the origin compatible string + +Watchdog 1.01.a is also compatible with 1.00.a. +Add the origin version to compatible list. + +Signed-off-by: Michal Simek <michal.simek@xilinx.com> +Reviewed-by: Guenter Roeck <linux@roeck-us.net> +Signed-off-by: Wim Van Sebroeck <wim@iguana.be> +(cherry picked from commit 8fce9b367d672332d2d101175b10737ee5c18b59) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + drivers/watchdog/of_xilinx_wdt.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/watchdog/of_xilinx_wdt.c b/drivers/watchdog/of_xilinx_wdt.c +index d4a35ab89e01..4dd281f2c33f 100644 +--- a/drivers/watchdog/of_xilinx_wdt.c ++++ b/drivers/watchdog/of_xilinx_wdt.c +@@ -384,6 +384,7 @@ static int xwdt_remove(struct platform_device *dev) + + /* Match table for of_platform binding */ + static struct of_device_id xwdt_of_match[] = { ++ { .compatible = "xlnx,xps-timebase-wdt-1.00.a", }, + { .compatible = "xlnx,xps-timebase-wdt-1.01.a", }, + {}, + }; +-- +1.8.5.rc3 + diff --git a/patches.zynq/0068-watchdog-Get-rid-of-MODULE_ALIAS_MISCDEV-statements.patch b/patches.zynq/0068-watchdog-Get-rid-of-MODULE_ALIAS_MISCDEV-statements.patch new file mode 100644 index 00000000000000..79a7dd27e99866 --- /dev/null +++ b/patches.zynq/0068-watchdog-Get-rid-of-MODULE_ALIAS_MISCDEV-statements.patch @@ -0,0 +1,55 @@ +From 430a9757ebdaa09122c5f6429e2e791f34a27ec7 Mon Sep 17 00:00:00 2001 +From: Jean Delvare <jdelvare@suse.de> +Date: Mon, 21 Oct 2013 17:38:49 +0200 +Subject: watchdog: Get rid of MODULE_ALIAS_MISCDEV statements + +I just can't find any value in MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR) +and MODULE_ALIAS_MISCDEV(TEMP_MINOR) statements. + +Either the device is enumerated and the driver already has a module +alias (e.g. PCI, USB etc.) that will get the right driver loaded +automatically. + +Or the device is not enumerated and loading its driver will lead to +more or less intrusive hardware poking. Such hardware poking should be +limited to a bare minimum, so the user should really decide which +drivers should be tried and in what order. Trying them all in +arbitrary order can't do any good. + +On top of that, loading that many drivers at once bloats the kernel +log. Also many drivers will stay loaded afterward, bloating the output +of "lsmod" and wasting memory. Some modules (cs5535_mfgpt which gets +loaded as a dependency) can't even be unloaded! + +If defining char-major-10-130 is needed then it should happen in +user-space. + +Signed-off-by: Jean Delvare <jdelvare@suse.de> +Acked-by: Guenter Roeck <linux@roeck-us.net> +Signed-off-by: Wim Van Sebroeck <wim@iguana.be> +Cc: Stephen Warren <swarren@wwwdotorg.org> +Cc: Mike Frysinger <vapier.adi@gmail.com> +Cc: Wan ZongShun <mcuos.com@gmail.com> +Cc: Ben Dooks <ben-linux@fluff.org> +Cc: Kukjin Kim <kgene.kim@samsung.com> +Cc: Zwane Mwaikambo <zwane@arm.linux.org.uk> +Cc: Jim Cromie <jim.cromie@gmail.com> +(cherry picked from commit 487722cf2d66126338217896642bd5eec832c34b) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + drivers/watchdog/of_xilinx_wdt.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/drivers/watchdog/of_xilinx_wdt.c b/drivers/watchdog/of_xilinx_wdt.c +index 4dd281f2c33f..fb57103c8ebc 100644 +--- a/drivers/watchdog/of_xilinx_wdt.c ++++ b/drivers/watchdog/of_xilinx_wdt.c +@@ -405,4 +405,3 @@ module_platform_driver(xwdt_driver); + MODULE_AUTHOR("Alejandro Cabrera <aldaya@gmail.com>"); + MODULE_DESCRIPTION("Xilinx Watchdog driver"); + MODULE_LICENSE("GPL v2"); +-MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); +-- +1.8.5.rc3 + diff --git a/patches.zynq/0069-DT-Add-documentation-for-gpio-xilinx.patch b/patches.zynq/0069-DT-Add-documentation-for-gpio-xilinx.patch new file mode 100644 index 00000000000000..a72a7e9f1f7a50 --- /dev/null +++ b/patches.zynq/0069-DT-Add-documentation-for-gpio-xilinx.patch @@ -0,0 +1,74 @@ +From 97bee269bbd0af7c8757d37a6ae3683f7f7575b4 Mon Sep 17 00:00:00 2001 +From: Michal Simek <michal.simek@xilinx.com> +Date: Mon, 3 Jun 2013 14:31:21 +0200 +Subject: DT: Add documentation for gpio-xilinx + +Describe gpio-xilinx binding. + +Signed-off-by: Michal Simek <michal.simek@xilinx.com> +Signed-off-by: Linus Walleij <linus.walleij@linaro.org> +(cherry picked from commit 6090a0fa5cefe6cc0aa95786b21dcf1bf19942da) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + .../devicetree/bindings/gpio/gpio-xilinx.txt | 48 ++++++++++++++++++++++ + 1 file changed, 48 insertions(+) + create mode 100644 Documentation/devicetree/bindings/gpio/gpio-xilinx.txt + +diff --git a/Documentation/devicetree/bindings/gpio/gpio-xilinx.txt b/Documentation/devicetree/bindings/gpio/gpio-xilinx.txt +new file mode 100644 +index 000000000000..63bf4becd5f0 +--- /dev/null ++++ b/Documentation/devicetree/bindings/gpio/gpio-xilinx.txt +@@ -0,0 +1,48 @@ ++Xilinx plb/axi GPIO controller ++ ++Dual channel GPIO controller with configurable number of pins ++(from 1 to 32 per channel). Every pin can be configured as ++input/output/tristate. Both channels share the same global IRQ but ++local interrupts can be enabled on channel basis. ++ ++Required properties: ++- compatible : Should be "xlnx,xps-gpio-1.00.a" ++- reg : Address and length of the register set for the device ++- #gpio-cells : Should be two. The first cell is the pin number and the ++ second cell is used to specify optional parameters (currently unused). ++- gpio-controller : Marks the device node as a GPIO controller. ++ ++Optional properties: ++- interrupts : Interrupt mapping for GPIO IRQ. ++- interrupt-parent : Phandle for the interrupt controller that ++ services interrupts for this device. ++- xlnx,all-inputs : if n-th bit is setup, GPIO-n is input ++- xlnx,dout-default : if n-th bit is 1, GPIO-n default value is 1 ++- xlnx,gpio-width : gpio width ++- xlnx,tri-default : if n-th bit is 1, GPIO-n is in tristate mode ++- xlnx,is-dual : if 1, controller also uses the second channel ++- xlnx,all-inputs-2 : as above but for the second channel ++- xlnx,dout-default-2 : as above but the second channel ++- xlnx,gpio2-width : as above but for the second channel ++- xlnx,tri-default-2 : as above but for the second channel ++ ++ ++Example: ++gpio: gpio@40000000 { ++ #gpio-cells = <2>; ++ compatible = "xlnx,xps-gpio-1.00.a"; ++ gpio-controller ; ++ interrupt-parent = <µblaze_0_intc>; ++ interrupts = < 6 2 >; ++ reg = < 0x40000000 0x10000 >; ++ xlnx,all-inputs = <0x0>; ++ xlnx,all-inputs-2 = <0x0>; ++ xlnx,dout-default = <0x0>; ++ xlnx,dout-default-2 = <0x0>; ++ xlnx,gpio-width = <0x2>; ++ xlnx,gpio2-width = <0x2>; ++ xlnx,interrupt-present = <0x1>; ++ xlnx,is-dual = <0x1>; ++ xlnx,tri-default = <0xffffffff>; ++ xlnx,tri-default-2 = <0xffffffff>; ++} ; +-- +1.8.5.rc3 + diff --git a/patches.zynq/0070-arm-dt-zynq-Add-support-for-the-zc706-platform.patch b/patches.zynq/0070-arm-dt-zynq-Add-support-for-the-zc706-platform.patch new file mode 100644 index 00000000000000..0754279e94a359 --- /dev/null +++ b/patches.zynq/0070-arm-dt-zynq-Add-support-for-the-zc706-platform.patch @@ -0,0 +1,70 @@ +From d429e826cbf1e3f1bac97f81e24d07cfb2880ed6 Mon Sep 17 00:00:00 2001 +From: Soren Brinkmann <soren.brinkmann@xilinx.com> +Date: Thu, 13 Jun 2013 09:37:17 -0700 +Subject: arm: dt: zynq: Add support for the zc706 platform + +Add a DT fragment for the zc706 Zynq platform and a corresponding +target to the Makefile. + +Signed-off-by: Soren Brinkmann <soren.brinkmann@xilinx.com> +Reviewed-by: Steffen Trumtrar <s.trumtrar@pengutronix.de> +Signed-off-by: Michal Simek <michal.simek@xilinx.com> +(cherry picked from commit 4bda2670e4759b99f725176dd31caa612ea098b6) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + arch/arm/boot/dts/Makefile | 3 ++- + arch/arm/boot/dts/zynq-zc706.dts | 35 +++++++++++++++++++++++++++++++++++ + 2 files changed, 37 insertions(+), 1 deletion(-) + create mode 100644 arch/arm/boot/dts/zynq-zc706.dts + +--- a/arch/arm/boot/dts/Makefile ++++ b/arch/arm/boot/dts/Makefile +@@ -216,7 +216,8 @@ dtb-$(CONFIG_ARCH_VT8500) += vt8500-bv07 + wm8505-ref.dtb \ + wm8650-mid.dtb \ + wm8850-w70v2.dtb +-dtb-$(CONFIG_ARCH_ZYNQ) += zynq-zc702.dtb ++dtb-$(CONFIG_ARCH_ZYNQ) += zynq-zc702.dtb \ ++ zynq-zc706.dtb + + targets += dtbs + targets += $(dtb-y) +--- /dev/null ++++ b/arch/arm/boot/dts/zynq-zc706.dts +@@ -0,0 +1,35 @@ ++/* ++ * Copyright (C) 2011 Xilinx ++ * Copyright (C) 2012 National Instruments Corp. ++ * Copyright (C) 2013 Xilinx ++ * ++ * This software is licensed under the terms of the GNU General Public ++ * License version 2, as published by the Free Software Foundation, and ++ * may be copied, distributed, and modified under those terms. ++ * ++ * 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. ++ */ ++/dts-v1/; ++/include/ "zynq-7000.dtsi" ++ ++/ { ++ model = "Zynq ZC706 Development Board"; ++ compatible = "xlnx,zynq-zc706", "xlnx,zynq-7000"; ++ ++ memory { ++ device_type = "memory"; ++ reg = <0 0x40000000>; ++ }; ++ ++ chosen { ++ bootargs = "console=ttyPS0,115200 earlyprintk"; ++ }; ++ ++}; ++ ++&uart1 { ++ status = "okay"; ++}; diff --git a/patches.zynq/0071-USB-host-use-platform_-get-set-_drvdata.patch b/patches.zynq/0071-USB-host-use-platform_-get-set-_drvdata.patch new file mode 100644 index 00000000000000..fbf4d4ce345467 --- /dev/null +++ b/patches.zynq/0071-USB-host-use-platform_-get-set-_drvdata.patch @@ -0,0 +1,48 @@ +From 7e8ff703fd299418886672365a64f85e93c5f50b Mon Sep 17 00:00:00 2001 +From: Jingoo Han <jg1.han@samsung.com> +Date: Thu, 23 May 2013 19:18:39 +0900 +Subject: USB: host: use platform_{get,set}_drvdata() + +Use the wrapper functions for getting and setting the driver data using +platform_device instead of using dev_{get,set}_drvdata() with &pdev->dev, +so we can directly pass a struct platform_device. + +Also, unnecessary dev_set_drvdata() is removed, because the driver core +clears the driver data to NULL after device_release or on probe failure. + +Signed-off-by: Jingoo Han <jg1.han@samsung.com> +Acked-by: Alan Stern <stern@rowland.harvard.edu> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +(cherry picked from commit 477527baf6a8d4c8652f979f0aa3546216635184) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + drivers/usb/host/ehci-xilinx-of.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +diff --git a/drivers/usb/host/ehci-xilinx-of.c b/drivers/usb/host/ehci-xilinx-of.c +index d845e3bcfaff..35c7f90384a6 100644 +--- a/drivers/usb/host/ehci-xilinx-of.c ++++ b/drivers/usb/host/ehci-xilinx-of.c +@@ -209,8 +209,7 @@ err_irq: + */ + static int ehci_hcd_xilinx_of_remove(struct platform_device *op) + { +- struct usb_hcd *hcd = dev_get_drvdata(&op->dev); +- dev_set_drvdata(&op->dev, NULL); ++ struct usb_hcd *hcd = platform_get_drvdata(op); + + dev_dbg(&op->dev, "stopping XILINX-OF USB Controller\n"); + +@@ -229,7 +228,7 @@ static int ehci_hcd_xilinx_of_remove(struct platform_device *op) + */ + static void ehci_hcd_xilinx_of_shutdown(struct platform_device *op) + { +- struct usb_hcd *hcd = dev_get_drvdata(&op->dev); ++ struct usb_hcd *hcd = platform_get_drvdata(op); + + if (hcd->driver->shutdown) + hcd->driver->shutdown(hcd); +-- +1.8.5.rc3 + diff --git a/patches.zynq/0072-USB-host-Use-usb_hcd_platform_shutdown-wherever-poss.patch b/patches.zynq/0072-USB-host-Use-usb_hcd_platform_shutdown-wherever-poss.patch new file mode 100644 index 00000000000000..086b068d610509 --- /dev/null +++ b/patches.zynq/0072-USB-host-Use-usb_hcd_platform_shutdown-wherever-poss.patch @@ -0,0 +1,58 @@ +From 11a94a61d5a3eb4f6c44af725ae51786338fcb7b Mon Sep 17 00:00:00 2001 +From: Roger Quadros <rogerq@ti.com> +Date: Mon, 22 Jul 2013 15:04:50 +0300 +Subject: USB: host: Use usb_hcd_platform_shutdown() wherever possible + +Most HCD drivers are doing the same thing in their ".shutdown" callback +so it makes sense to use the generic usb_hcd_platform_shutdown() +handler there. + +Signed-off-by: Roger Quadros <rogerq@ti.com> +Reviewed-by: Felipe Balbi <balbi@ti.com> +Acked-by: Alan Stern <stern@rowland.harvard.edu> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +(cherry picked from commit aaf6b52d50f85ed792c9c8987f5169f3dce2adea) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + drivers/usb/host/ehci-xilinx-of.c | 17 +---------------- + 1 file changed, 1 insertion(+), 16 deletions(-) + +diff --git a/drivers/usb/host/ehci-xilinx-of.c b/drivers/usb/host/ehci-xilinx-of.c +index 35c7f90384a6..eba962e6ebfb 100644 +--- a/drivers/usb/host/ehci-xilinx-of.c ++++ b/drivers/usb/host/ehci-xilinx-of.c +@@ -220,21 +220,6 @@ static int ehci_hcd_xilinx_of_remove(struct platform_device *op) + return 0; + } + +-/** +- * ehci_hcd_xilinx_of_shutdown - shutdown the hcd +- * @op: pointer to platform_device structure that is to be removed +- * +- * Properly shutdown the hcd, call driver's shutdown routine. +- */ +-static void ehci_hcd_xilinx_of_shutdown(struct platform_device *op) +-{ +- struct usb_hcd *hcd = platform_get_drvdata(op); +- +- if (hcd->driver->shutdown) +- hcd->driver->shutdown(hcd); +-} +- +- + static const struct of_device_id ehci_hcd_xilinx_of_match[] = { + {.compatible = "xlnx,xps-usb-host-1.00.a",}, + {}, +@@ -244,7 +229,7 @@ MODULE_DEVICE_TABLE(of, ehci_hcd_xilinx_of_match); + static struct platform_driver ehci_hcd_xilinx_of_driver = { + .probe = ehci_hcd_xilinx_of_probe, + .remove = ehci_hcd_xilinx_of_remove, +- .shutdown = ehci_hcd_xilinx_of_shutdown, ++ .shutdown = usb_hcd_platform_shutdown, + .driver = { + .name = "xilinx-of-ehci", + .owner = THIS_MODULE, +-- +1.8.5.rc3 + diff --git a/patches.zynq/0073-clocksource-cadence_ttc-Remove-unused-header.patch b/patches.zynq/0073-clocksource-cadence_ttc-Remove-unused-header.patch new file mode 100644 index 00000000000000..f0ab2c47b0273d --- /dev/null +++ b/patches.zynq/0073-clocksource-cadence_ttc-Remove-unused-header.patch @@ -0,0 +1,31 @@ +From 513f6e9cee5ca385c71ef30d66015e6c9d8605fe Mon Sep 17 00:00:00 2001 +From: Soren Brinkmann <soren.brinkmann@xilinx.com> +Date: Mon, 8 Jul 2013 09:51:37 -0700 +Subject: clocksource: cadence_ttc: Remove unused header + +The clk-provider.h header is not required by this driver. + +Signed-off-by: Soren Brinkmann <soren.brinkmann@xilinx.com> +Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org> +(cherry picked from commit 9bbf914043e04f65e619f3c0ff67c387812f9458) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + drivers/clocksource/cadence_ttc_timer.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/drivers/clocksource/cadence_ttc_timer.c b/drivers/clocksource/cadence_ttc_timer.c +index 4cbe28c74631..0eefc8d8622b 100644 +--- a/drivers/clocksource/cadence_ttc_timer.c ++++ b/drivers/clocksource/cadence_ttc_timer.c +@@ -21,7 +21,6 @@ + #include <linux/of_address.h> + #include <linux/of_irq.h> + #include <linux/slab.h> +-#include <linux/clk-provider.h> + + /* + * This driver configures the 2 16-bit count-up timers as follows: +-- +1.8.5.rc3 + diff --git a/patches.zynq/0074-net-ethernet-use-platform_-get-set-_drvdata.patch b/patches.zynq/0074-net-ethernet-use-platform_-get-set-_drvdata.patch new file mode 100644 index 00000000000000..da8ec412d77236 --- /dev/null +++ b/patches.zynq/0074-net-ethernet-use-platform_-get-set-_drvdata.patch @@ -0,0 +1,86 @@ +From 5f3f406e9cb151174bfe553025a1f1e0e05e64fd Mon Sep 17 00:00:00 2001 +From: Jingoo Han <jg1.han@samsung.com> +Date: Thu, 23 May 2013 00:52:31 +0000 +Subject: net: ethernet: use platform_{get,set}_drvdata() + +Use the wrapper functions for getting and setting the driver data using +platform_device instead of using dev_{get,set}_drvdata() with &pdev->dev, +so we can directly pass a struct platform_device. + +Also, unnecessary dev_set_drvdata() is removed, because the driver core +clears the driver data to NULL after device_release or on probe failure. + +Signed-off-by: Jingoo Han <jg1.han@samsung.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +(cherry picked from commit 8513fbd880093f00a47e85a552f14ca2de8d84d6) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + drivers/net/ethernet/xilinx/ll_temac_main.c | 5 ++--- + drivers/net/ethernet/xilinx/xilinx_axienet_main.c | 6 ++---- + 2 files changed, 4 insertions(+), 7 deletions(-) + +diff --git a/drivers/net/ethernet/xilinx/ll_temac_main.c b/drivers/net/ethernet/xilinx/ll_temac_main.c +index 5444f2b87d01..96cb89795ee4 100644 +--- a/drivers/net/ethernet/xilinx/ll_temac_main.c ++++ b/drivers/net/ethernet/xilinx/ll_temac_main.c +@@ -1013,7 +1013,7 @@ static int temac_of_probe(struct platform_device *op) + return -ENOMEM; + + ether_setup(ndev); +- dev_set_drvdata(&op->dev, ndev); ++ platform_set_drvdata(op, ndev); + SET_NETDEV_DEV(ndev, &op->dev); + ndev->flags &= ~IFF_MULTICAST; /* clear multicast */ + ndev->features = NETIF_F_SG | NETIF_F_FRAGLIST; +@@ -1142,7 +1142,7 @@ static int temac_of_probe(struct platform_device *op) + + static int temac_of_remove(struct platform_device *op) + { +- struct net_device *ndev = dev_get_drvdata(&op->dev); ++ struct net_device *ndev = platform_get_drvdata(op); + struct temac_local *lp = netdev_priv(ndev); + + temac_mdio_teardown(lp); +@@ -1151,7 +1151,6 @@ static int temac_of_remove(struct platform_device *op) + if (lp->phy_node) + of_node_put(lp->phy_node); + lp->phy_node = NULL; +- dev_set_drvdata(&op->dev, NULL); + iounmap(lp->regs); + if (lp->sdma_regs) + iounmap(lp->sdma_regs); +diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c +index 24748e8367a1..fb7d1c28a2ea 100644 +--- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c ++++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c +@@ -1484,7 +1484,7 @@ static int axienet_of_probe(struct platform_device *op) + return -ENOMEM; + + ether_setup(ndev); +- dev_set_drvdata(&op->dev, ndev); ++ platform_set_drvdata(op, ndev); + + SET_NETDEV_DEV(ndev, &op->dev); + ndev->flags &= ~IFF_MULTICAST; /* clear multicast */ +@@ -1622,7 +1622,7 @@ nodev: + + static int axienet_of_remove(struct platform_device *op) + { +- struct net_device *ndev = dev_get_drvdata(&op->dev); ++ struct net_device *ndev = platform_get_drvdata(op); + struct axienet_local *lp = netdev_priv(ndev); + + axienet_mdio_teardown(lp); +@@ -1632,8 +1632,6 @@ static int axienet_of_remove(struct platform_device *op) + of_node_put(lp->phy_node); + lp->phy_node = NULL; + +- dev_set_drvdata(&op->dev, NULL); +- + iounmap(lp->regs); + if (lp->dma_regs) + iounmap(lp->dma_regs); +-- +1.8.5.rc3 + diff --git a/patches.zynq/0075-drivers-net-Convert-dma_alloc_coherent-.__GFP_ZERO-t.patch b/patches.zynq/0075-drivers-net-Convert-dma_alloc_coherent-.__GFP_ZERO-t.patch new file mode 100644 index 00000000000000..43cf3f5173fde4 --- /dev/null +++ b/patches.zynq/0075-drivers-net-Convert-dma_alloc_coherent-.__GFP_ZERO-t.patch @@ -0,0 +1,89 @@ +From f9b4ed9ae06661e53e45507d4cab61cf0a192cc8 Mon Sep 17 00:00:00 2001 +From: Joe Perches <joe@perches.com> +Date: Mon, 26 Aug 2013 22:45:23 -0700 +Subject: drivers:net: Convert dma_alloc_coherent(...__GFP_ZERO) to + dma_zalloc_coherent + +__GFP_ZERO is an uncommon flag and perhaps is better +not used. static inline dma_zalloc_coherent exists +so convert the uses of dma_alloc_coherent with __GFP_ZERO +to the more common kernel style with zalloc. + +Remove memset from the static inline dma_zalloc_coherent +and add just one use of __GFP_ZERO instead. + +Trivially reduces the size of the existing uses of +dma_zalloc_coherent. + +Realign arguments as appropriate. + +Signed-off-by: Joe Perches <joe@perches.com> +Acked-by: Neil Horman <nhorman@tuxdriver.com> +Acked-by: Jesse Brandeburg <jesse.brandeburg@intel.com> +Acked-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +(cherry picked from commit ede23fa8161c1a04aa1b3bf5447812ca14b3fef1) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + drivers/net/ethernet/xilinx/ll_temac_main.c | 12 ++++++------ + drivers/net/ethernet/xilinx/xilinx_axienet_main.c | 14 ++++++-------- + 2 files changed, 12 insertions(+), 14 deletions(-) + +diff --git a/drivers/net/ethernet/xilinx/ll_temac_main.c b/drivers/net/ethernet/xilinx/ll_temac_main.c +index 96cb89795ee4..0029148077a9 100644 +--- a/drivers/net/ethernet/xilinx/ll_temac_main.c ++++ b/drivers/net/ethernet/xilinx/ll_temac_main.c +@@ -243,15 +243,15 @@ static int temac_dma_bd_init(struct net_device *ndev) + + /* allocate the tx and rx ring buffer descriptors. */ + /* returns a virtual address and a physical address. */ +- lp->tx_bd_v = dma_alloc_coherent(ndev->dev.parent, +- sizeof(*lp->tx_bd_v) * TX_BD_NUM, +- &lp->tx_bd_p, GFP_KERNEL | __GFP_ZERO); ++ lp->tx_bd_v = dma_zalloc_coherent(ndev->dev.parent, ++ sizeof(*lp->tx_bd_v) * TX_BD_NUM, ++ &lp->tx_bd_p, GFP_KERNEL); + if (!lp->tx_bd_v) + goto out; + +- lp->rx_bd_v = dma_alloc_coherent(ndev->dev.parent, +- sizeof(*lp->rx_bd_v) * RX_BD_NUM, +- &lp->rx_bd_p, GFP_KERNEL | __GFP_ZERO); ++ lp->rx_bd_v = dma_zalloc_coherent(ndev->dev.parent, ++ sizeof(*lp->rx_bd_v) * RX_BD_NUM, ++ &lp->rx_bd_p, GFP_KERNEL); + if (!lp->rx_bd_v) + goto out; + +diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c +index fb7d1c28a2ea..b2ff038d6d20 100644 +--- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c ++++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c +@@ -201,17 +201,15 @@ static int axienet_dma_bd_init(struct net_device *ndev) + /* + * Allocate the Tx and Rx buffer descriptors. + */ +- lp->tx_bd_v = dma_alloc_coherent(ndev->dev.parent, +- sizeof(*lp->tx_bd_v) * TX_BD_NUM, +- &lp->tx_bd_p, +- GFP_KERNEL | __GFP_ZERO); ++ lp->tx_bd_v = dma_zalloc_coherent(ndev->dev.parent, ++ sizeof(*lp->tx_bd_v) * TX_BD_NUM, ++ &lp->tx_bd_p, GFP_KERNEL); + if (!lp->tx_bd_v) + goto out; + +- lp->rx_bd_v = dma_alloc_coherent(ndev->dev.parent, +- sizeof(*lp->rx_bd_v) * RX_BD_NUM, +- &lp->rx_bd_p, +- GFP_KERNEL | __GFP_ZERO); ++ lp->rx_bd_v = dma_zalloc_coherent(ndev->dev.parent, ++ sizeof(*lp->rx_bd_v) * RX_BD_NUM, ++ &lp->rx_bd_p, GFP_KERNEL); + if (!lp->rx_bd_v) + goto out; + +-- +1.8.5.rc3 + diff --git a/patches.zynq/0076-net-emaclite-Report-failures-in-mdio-setup.patch b/patches.zynq/0076-net-emaclite-Report-failures-in-mdio-setup.patch new file mode 100644 index 00000000000000..4a45e78ca6a477 --- /dev/null +++ b/patches.zynq/0076-net-emaclite-Report-failures-in-mdio-setup.patch @@ -0,0 +1,59 @@ +From 6e811ed59c47a4fdfefb4cbfc672e9cfd13c3c07 Mon Sep 17 00:00:00 2001 +From: Michal Simek <michal.simek@xilinx.com> +Date: Thu, 30 May 2013 00:28:03 +0000 +Subject: net: emaclite: Report failures in mdio setup + +Be more verbose when any problem happens. + +Signed-off-by: Michal Simek <michal.simek@xilinx.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +(cherry picked from commit ccfecdfe16a872ed3e8322ea48e34502568eb849) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + drivers/net/ethernet/xilinx/xilinx_emaclite.c | 12 +++++++++--- + 1 file changed, 9 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/ethernet/xilinx/xilinx_emaclite.c b/drivers/net/ethernet/xilinx/xilinx_emaclite.c +index b7268b3dae77..1fabaef46d7b 100644 +--- a/drivers/net/ethernet/xilinx/xilinx_emaclite.c ++++ b/drivers/net/ethernet/xilinx/xilinx_emaclite.c +@@ -852,8 +852,10 @@ static int xemaclite_mdio_setup(struct net_local *lp, struct device *dev) + /* Don't register the MDIO bus if the phy_node or its parent node + * can't be found. + */ +- if (!np) ++ if (!np) { ++ dev_err(dev, "Failed to register mdio bus.\n"); + return -ENODEV; ++ } + + /* Enable the MDIO bus by asserting the enable bit in MDIO Control + * register. +@@ -862,8 +864,10 @@ static int xemaclite_mdio_setup(struct net_local *lp, struct device *dev) + XEL_MDIOCTRL_MDIOEN_MASK); + + bus = mdiobus_alloc(); +- if (!bus) ++ if (!bus) { ++ dev_err(dev, "Failed to allocal mdiobus\n"); + return -ENOMEM; ++ } + + of_address_to_resource(np, 0, &res); + snprintf(bus->id, MII_BUS_ID_SIZE, "%.8llx", +@@ -879,8 +883,10 @@ static int xemaclite_mdio_setup(struct net_local *lp, struct device *dev) + lp->mii_bus = bus; + + rc = of_mdiobus_register(bus, np); +- if (rc) ++ if (rc) { ++ dev_err(dev, "Failed to register mdio bus.\n"); + goto err_register; ++ } + + return 0; + +-- +1.8.5.rc3 + diff --git a/patches.zynq/0077-net-emaclite-Support-multiple-phys-connected-to-one-.patch b/patches.zynq/0077-net-emaclite-Support-multiple-phys-connected-to-one-.patch new file mode 100644 index 00000000000000..02042aa97689c6 --- /dev/null +++ b/patches.zynq/0077-net-emaclite-Support-multiple-phys-connected-to-one-.patch @@ -0,0 +1,100 @@ +From 4278cc5433cdac8006a1f207ef8eeeceed9f4bfa Mon Sep 17 00:00:00 2001 +From: Michal Simek <michal.simek@xilinx.com> +Date: Thu, 30 May 2013 00:28:04 +0000 +Subject: net: emaclite: Support multiple phys connected to one MDIO bus + +For system which contains at least two ethernet IP where +one IP manage MDIO bus with several PHYs. + +Example dts node: +ethernet_mac0: ethernet@81000000 { + compatible = "xlnx,xps-ethernetlite-1.00.a"; + device_type = "network"; + interrupt-parent = <&xps_intc_0>; + interrupts = < 1 0 >; + local-mac-address = [ 00 0a 35 00 db bb ]; + phy-handle = <ðernet_mac0_phy0>; + reg = < 0x81000000 0x10000 >; + xlnx,duplex = <0x1>; + xlnx,family = "spartan3e"; + xlnx,include-internal-loopback = <0x0>; + xlnx,include-mdio = <0x1>; + xlnx,rx-ping-pong = <0x0>; + xlnx,tx-ping-pong = <0x0>; + ethernet_mac0_mdio { + #address-cells = <1>; + #size-cells = <0>; + ethernet_mac0_phy0: phy@1 { + reg = <0x1>; + } ; + ethernet_mac0_phy1: phy@3 { + reg = <0x3>; + } ; + } ; +} ; +ethernet_mac2: ethernet@81040000 { + compatible = "xlnx,xps-ethernetlite-1.00.a"; + device_type = "network"; + interrupt-parent = <&xps_intc_0>; + interrupts = < 11 0 >; + local-mac-address = [ 00 0a 35 00 db bb ]; + phy-handle = <ðernet_mac0_phy1>; + reg = < 0x81040000 0x10000 >; + xlnx,duplex = <0x1>; + xlnx,family = "spartan3e"; + xlnx,include-internal-loopback = <0x0>; + xlnx,include-mdio = <0x0>; + xlnx,rx-ping-pong = <0x0>; + xlnx,tx-ping-pong = <0x0>; +} ; + +Signed-off-by: Michal Simek <michal.simek@xilinx.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +(cherry picked from commit e0a3bc65448c01289a74329ddf6c84d8c0594e59) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + drivers/net/ethernet/xilinx/xilinx_emaclite.c | 13 ++++++++++++- + 1 file changed, 12 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/xilinx/xilinx_emaclite.c b/drivers/net/ethernet/xilinx/xilinx_emaclite.c +index 1fabaef46d7b..c13081e1f593 100644 +--- a/drivers/net/ethernet/xilinx/xilinx_emaclite.c ++++ b/drivers/net/ethernet/xilinx/xilinx_emaclite.c +@@ -848,6 +848,7 @@ static int xemaclite_mdio_setup(struct net_local *lp, struct device *dev) + int rc; + struct resource res; + struct device_node *np = of_get_parent(lp->phy_node); ++ struct device_node *npp; + + /* Don't register the MDIO bus if the phy_node or its parent node + * can't be found. +@@ -856,6 +857,17 @@ static int xemaclite_mdio_setup(struct net_local *lp, struct device *dev) + dev_err(dev, "Failed to register mdio bus.\n"); + return -ENODEV; + } ++ npp = of_get_parent(np); ++ ++ of_address_to_resource(npp, 0, &res); ++ if (lp->ndev->mem_start != res.start) { ++ struct phy_device *phydev; ++ phydev = of_phy_find_device(lp->phy_node); ++ if (!phydev) ++ dev_info(dev, ++ "MDIO of the phy is not registered yet\n"); ++ return 0; ++ } + + /* Enable the MDIO bus by asserting the enable bit in MDIO Control + * register. +@@ -869,7 +881,6 @@ static int xemaclite_mdio_setup(struct net_local *lp, struct device *dev) + return -ENOMEM; + } + +- of_address_to_resource(np, 0, &res); + snprintf(bus->id, MII_BUS_ID_SIZE, "%.8llx", + (unsigned long long)res.start); + bus->priv = lp; +-- +1.8.5.rc3 + diff --git a/patches.zynq/0078-net-emaclite-Let-s-make-xemaclite_adjust_link-static.patch b/patches.zynq/0078-net-emaclite-Let-s-make-xemaclite_adjust_link-static.patch new file mode 100644 index 00000000000000..b787e345406fe0 --- /dev/null +++ b/patches.zynq/0078-net-emaclite-Let-s-make-xemaclite_adjust_link-static.patch @@ -0,0 +1,35 @@ +From 5fe49777c7c349f4bdce20bce9c26a6f7374fb1c Mon Sep 17 00:00:00 2001 +From: Michal Simek <michal.simek@xilinx.com> +Date: Thu, 30 May 2013 00:28:05 +0000 +Subject: net: emaclite: Let's make xemaclite_adjust_link static + +xemaclite_adjust_link is used locally. +It removes sparse warning: +drivers/net/ethernet/xilinx/xilinx_emaclite.c:916:6: warning: +symbol 'xemaclite_adjust_link' was not declared. Should it be static? + +Signed-off-by: Michal Simek <michal.simek@xilinx.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +(cherry picked from commit 3fb99fa7c7d2310791bf39929285da44b201fd40) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + drivers/net/ethernet/xilinx/xilinx_emaclite.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/xilinx/xilinx_emaclite.c b/drivers/net/ethernet/xilinx/xilinx_emaclite.c +index c13081e1f593..bda574db42ff 100644 +--- a/drivers/net/ethernet/xilinx/xilinx_emaclite.c ++++ b/drivers/net/ethernet/xilinx/xilinx_emaclite.c +@@ -913,7 +913,7 @@ err_register: + * There's nothing in the Emaclite device to be configured when the link + * state changes. We just print the status. + */ +-void xemaclite_adjust_link(struct net_device *ndev) ++static void xemaclite_adjust_link(struct net_device *ndev) + { + struct net_local *lp = netdev_priv(ndev); + struct phy_device *phy = lp->phy_dev; +-- +1.8.5.rc3 + diff --git a/patches.zynq/0079-net-emaclite-Do-not-use-microblaze-and-ppc-IO-functi.patch b/patches.zynq/0079-net-emaclite-Do-not-use-microblaze-and-ppc-IO-functi.patch new file mode 100644 index 00000000000000..dee2c90c7732fc --- /dev/null +++ b/patches.zynq/0079-net-emaclite-Do-not-use-microblaze-and-ppc-IO-functi.patch @@ -0,0 +1,345 @@ +From 0e9dfb478e21866f4bcc39a5c01a4dea34782897 Mon Sep 17 00:00:00 2001 +From: Michal Simek <michal.simek@xilinx.com> +Date: Thu, 30 May 2013 00:28:06 +0000 +Subject: net: emaclite: Do not use microblaze and ppc IO functions + +Emaclite can be used on ARM zynq where in_be32/out_be32 IO +functions are not present. Use standard __raw_readl/__raw_writel +IO functions instead. + +Signed-off-by: Michal Simek <michal.simek@xilinx.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +(cherry picked from commit 123c1407af877b9b036b852b77013a6f9f6049b0) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + drivers/net/ethernet/xilinx/xilinx_emaclite.c | 138 +++++++++++++------------- + 1 file changed, 69 insertions(+), 69 deletions(-) + +diff --git a/drivers/net/ethernet/xilinx/xilinx_emaclite.c b/drivers/net/ethernet/xilinx/xilinx_emaclite.c +index bda574db42ff..476ce5bb385f 100644 +--- a/drivers/net/ethernet/xilinx/xilinx_emaclite.c ++++ b/drivers/net/ethernet/xilinx/xilinx_emaclite.c +@@ -159,34 +159,32 @@ static void xemaclite_enable_interrupts(struct net_local *drvdata) + u32 reg_data; + + /* Enable the Tx interrupts for the first Buffer */ +- reg_data = in_be32(drvdata->base_addr + XEL_TSR_OFFSET); +- out_be32(drvdata->base_addr + XEL_TSR_OFFSET, +- reg_data | XEL_TSR_XMIT_IE_MASK); ++ reg_data = __raw_readl(drvdata->base_addr + XEL_TSR_OFFSET); ++ __raw_writel(reg_data | XEL_TSR_XMIT_IE_MASK, ++ drvdata->base_addr + XEL_TSR_OFFSET); + + /* Enable the Tx interrupts for the second Buffer if + * configured in HW */ + if (drvdata->tx_ping_pong != 0) { +- reg_data = in_be32(drvdata->base_addr + ++ reg_data = __raw_readl(drvdata->base_addr + + XEL_BUFFER_OFFSET + XEL_TSR_OFFSET); +- out_be32(drvdata->base_addr + XEL_BUFFER_OFFSET + +- XEL_TSR_OFFSET, +- reg_data | XEL_TSR_XMIT_IE_MASK); ++ __raw_writel(reg_data | XEL_TSR_XMIT_IE_MASK, ++ drvdata->base_addr + XEL_BUFFER_OFFSET + ++ XEL_TSR_OFFSET); + } + + /* Enable the Rx interrupts for the first buffer */ +- out_be32(drvdata->base_addr + XEL_RSR_OFFSET, +- XEL_RSR_RECV_IE_MASK); ++ __raw_writel(XEL_RSR_RECV_IE_MASK, drvdata->base_addr + XEL_RSR_OFFSET); + + /* Enable the Rx interrupts for the second Buffer if + * configured in HW */ + if (drvdata->rx_ping_pong != 0) { +- out_be32(drvdata->base_addr + XEL_BUFFER_OFFSET + +- XEL_RSR_OFFSET, +- XEL_RSR_RECV_IE_MASK); ++ __raw_writel(XEL_RSR_RECV_IE_MASK, drvdata->base_addr + ++ XEL_BUFFER_OFFSET + XEL_RSR_OFFSET); + } + + /* Enable the Global Interrupt Enable */ +- out_be32(drvdata->base_addr + XEL_GIER_OFFSET, XEL_GIER_GIE_MASK); ++ __raw_writel(XEL_GIER_GIE_MASK, drvdata->base_addr + XEL_GIER_OFFSET); + } + + /** +@@ -201,37 +199,37 @@ static void xemaclite_disable_interrupts(struct net_local *drvdata) + u32 reg_data; + + /* Disable the Global Interrupt Enable */ +- out_be32(drvdata->base_addr + XEL_GIER_OFFSET, XEL_GIER_GIE_MASK); ++ __raw_writel(XEL_GIER_GIE_MASK, drvdata->base_addr + XEL_GIER_OFFSET); + + /* Disable the Tx interrupts for the first buffer */ +- reg_data = in_be32(drvdata->base_addr + XEL_TSR_OFFSET); +- out_be32(drvdata->base_addr + XEL_TSR_OFFSET, +- reg_data & (~XEL_TSR_XMIT_IE_MASK)); ++ reg_data = __raw_readl(drvdata->base_addr + XEL_TSR_OFFSET); ++ __raw_writel(reg_data & (~XEL_TSR_XMIT_IE_MASK), ++ drvdata->base_addr + XEL_TSR_OFFSET); + + /* Disable the Tx interrupts for the second Buffer + * if configured in HW */ + if (drvdata->tx_ping_pong != 0) { +- reg_data = in_be32(drvdata->base_addr + XEL_BUFFER_OFFSET + ++ reg_data = __raw_readl(drvdata->base_addr + XEL_BUFFER_OFFSET + + XEL_TSR_OFFSET); +- out_be32(drvdata->base_addr + XEL_BUFFER_OFFSET + +- XEL_TSR_OFFSET, +- reg_data & (~XEL_TSR_XMIT_IE_MASK)); ++ __raw_writel(reg_data & (~XEL_TSR_XMIT_IE_MASK), ++ drvdata->base_addr + XEL_BUFFER_OFFSET + ++ XEL_TSR_OFFSET); + } + + /* Disable the Rx interrupts for the first buffer */ +- reg_data = in_be32(drvdata->base_addr + XEL_RSR_OFFSET); +- out_be32(drvdata->base_addr + XEL_RSR_OFFSET, +- reg_data & (~XEL_RSR_RECV_IE_MASK)); ++ reg_data = __raw_readl(drvdata->base_addr + XEL_RSR_OFFSET); ++ __raw_writel(reg_data & (~XEL_RSR_RECV_IE_MASK), ++ drvdata->base_addr + XEL_RSR_OFFSET); + + /* Disable the Rx interrupts for the second buffer + * if configured in HW */ + if (drvdata->rx_ping_pong != 0) { + +- reg_data = in_be32(drvdata->base_addr + XEL_BUFFER_OFFSET + ++ reg_data = __raw_readl(drvdata->base_addr + XEL_BUFFER_OFFSET + + XEL_RSR_OFFSET); +- out_be32(drvdata->base_addr + XEL_BUFFER_OFFSET + +- XEL_RSR_OFFSET, +- reg_data & (~XEL_RSR_RECV_IE_MASK)); ++ __raw_writel(reg_data & (~XEL_RSR_RECV_IE_MASK), ++ drvdata->base_addr + XEL_BUFFER_OFFSET + ++ XEL_RSR_OFFSET); + } + } + +@@ -351,7 +349,7 @@ static int xemaclite_send_data(struct net_local *drvdata, u8 *data, + byte_count = ETH_FRAME_LEN; + + /* Check if the expected buffer is available */ +- reg_data = in_be32(addr + XEL_TSR_OFFSET); ++ reg_data = __raw_readl(addr + XEL_TSR_OFFSET); + if ((reg_data & (XEL_TSR_XMIT_BUSY_MASK | + XEL_TSR_XMIT_ACTIVE_MASK)) == 0) { + +@@ -364,7 +362,7 @@ static int xemaclite_send_data(struct net_local *drvdata, u8 *data, + + addr = (void __iomem __force *)((u32 __force)addr ^ + XEL_BUFFER_OFFSET); +- reg_data = in_be32(addr + XEL_TSR_OFFSET); ++ reg_data = __raw_readl(addr + XEL_TSR_OFFSET); + + if ((reg_data & (XEL_TSR_XMIT_BUSY_MASK | + XEL_TSR_XMIT_ACTIVE_MASK)) != 0) +@@ -375,15 +373,16 @@ static int xemaclite_send_data(struct net_local *drvdata, u8 *data, + /* Write the frame to the buffer */ + xemaclite_aligned_write(data, (u32 __force *) addr, byte_count); + +- out_be32(addr + XEL_TPLR_OFFSET, (byte_count & XEL_TPLR_LENGTH_MASK)); ++ __raw_writel((byte_count & XEL_TPLR_LENGTH_MASK), ++ addr + XEL_TPLR_OFFSET); + + /* Update the Tx Status Register to indicate that there is a + * frame to send. Set the XEL_TSR_XMIT_ACTIVE_MASK flag which + * is used by the interrupt handler to check whether a frame + * has been transmitted */ +- reg_data = in_be32(addr + XEL_TSR_OFFSET); ++ reg_data = __raw_readl(addr + XEL_TSR_OFFSET); + reg_data |= (XEL_TSR_XMIT_BUSY_MASK | XEL_TSR_XMIT_ACTIVE_MASK); +- out_be32(addr + XEL_TSR_OFFSET, reg_data); ++ __raw_writel(reg_data, addr + XEL_TSR_OFFSET); + + return 0; + } +@@ -408,7 +407,7 @@ static u16 xemaclite_recv_data(struct net_local *drvdata, u8 *data) + addr = (drvdata->base_addr + drvdata->next_rx_buf_to_use); + + /* Verify which buffer has valid data */ +- reg_data = in_be32(addr + XEL_RSR_OFFSET); ++ reg_data = __raw_readl(addr + XEL_RSR_OFFSET); + + if ((reg_data & XEL_RSR_RECV_DONE_MASK) == XEL_RSR_RECV_DONE_MASK) { + if (drvdata->rx_ping_pong != 0) +@@ -425,14 +424,14 @@ static u16 xemaclite_recv_data(struct net_local *drvdata, u8 *data) + return 0; /* No data was available */ + + /* Verify that buffer has valid data */ +- reg_data = in_be32(addr + XEL_RSR_OFFSET); ++ reg_data = __raw_readl(addr + XEL_RSR_OFFSET); + if ((reg_data & XEL_RSR_RECV_DONE_MASK) != + XEL_RSR_RECV_DONE_MASK) + return 0; /* No data was available */ + } + + /* Get the protocol type of the ethernet frame that arrived */ +- proto_type = ((ntohl(in_be32(addr + XEL_HEADER_OFFSET + ++ proto_type = ((ntohl(__raw_readl(addr + XEL_HEADER_OFFSET + + XEL_RXBUFF_OFFSET)) >> XEL_HEADER_SHIFT) & + XEL_RPLR_LENGTH_MASK); + +@@ -441,7 +440,7 @@ static u16 xemaclite_recv_data(struct net_local *drvdata, u8 *data) + if (proto_type > (ETH_FRAME_LEN + ETH_FCS_LEN)) { + + if (proto_type == ETH_P_IP) { +- length = ((ntohl(in_be32(addr + ++ length = ((ntohl(__raw_readl(addr + + XEL_HEADER_IP_LENGTH_OFFSET + + XEL_RXBUFF_OFFSET)) >> + XEL_HEADER_SHIFT) & +@@ -463,9 +462,9 @@ static u16 xemaclite_recv_data(struct net_local *drvdata, u8 *data) + data, length); + + /* Acknowledge the frame */ +- reg_data = in_be32(addr + XEL_RSR_OFFSET); ++ reg_data = __raw_readl(addr + XEL_RSR_OFFSET); + reg_data &= ~XEL_RSR_RECV_DONE_MASK; +- out_be32(addr + XEL_RSR_OFFSET, reg_data); ++ __raw_writel(reg_data, addr + XEL_RSR_OFFSET); + + return length; + } +@@ -492,14 +491,14 @@ static void xemaclite_update_address(struct net_local *drvdata, + + xemaclite_aligned_write(address_ptr, (u32 __force *) addr, ETH_ALEN); + +- out_be32(addr + XEL_TPLR_OFFSET, ETH_ALEN); ++ __raw_writel(ETH_ALEN, addr + XEL_TPLR_OFFSET); + + /* Update the MAC address in the EmacLite */ +- reg_data = in_be32(addr + XEL_TSR_OFFSET); +- out_be32(addr + XEL_TSR_OFFSET, reg_data | XEL_TSR_PROG_MAC_ADDR); ++ reg_data = __raw_readl(addr + XEL_TSR_OFFSET); ++ __raw_writel(reg_data | XEL_TSR_PROG_MAC_ADDR, addr + XEL_TSR_OFFSET); + + /* Wait for EmacLite to finish with the MAC address update */ +- while ((in_be32(addr + XEL_TSR_OFFSET) & ++ while ((__raw_readl(addr + XEL_TSR_OFFSET) & + XEL_TSR_PROG_MAC_ADDR) != 0) + ; + } +@@ -669,31 +668,32 @@ static irqreturn_t xemaclite_interrupt(int irq, void *dev_id) + u32 tx_status; + + /* Check if there is Rx Data available */ +- if ((in_be32(base_addr + XEL_RSR_OFFSET) & XEL_RSR_RECV_DONE_MASK) || +- (in_be32(base_addr + XEL_BUFFER_OFFSET + XEL_RSR_OFFSET) ++ if ((__raw_readl(base_addr + XEL_RSR_OFFSET) & ++ XEL_RSR_RECV_DONE_MASK) || ++ (__raw_readl(base_addr + XEL_BUFFER_OFFSET + XEL_RSR_OFFSET) + & XEL_RSR_RECV_DONE_MASK)) + + xemaclite_rx_handler(dev); + + /* Check if the Transmission for the first buffer is completed */ +- tx_status = in_be32(base_addr + XEL_TSR_OFFSET); ++ tx_status = __raw_readl(base_addr + XEL_TSR_OFFSET); + if (((tx_status & XEL_TSR_XMIT_BUSY_MASK) == 0) && + (tx_status & XEL_TSR_XMIT_ACTIVE_MASK) != 0) { + + tx_status &= ~XEL_TSR_XMIT_ACTIVE_MASK; +- out_be32(base_addr + XEL_TSR_OFFSET, tx_status); ++ __raw_writel(tx_status, base_addr + XEL_TSR_OFFSET); + + tx_complete = true; + } + + /* Check if the Transmission for the second buffer is completed */ +- tx_status = in_be32(base_addr + XEL_BUFFER_OFFSET + XEL_TSR_OFFSET); ++ tx_status = __raw_readl(base_addr + XEL_BUFFER_OFFSET + XEL_TSR_OFFSET); + if (((tx_status & XEL_TSR_XMIT_BUSY_MASK) == 0) && + (tx_status & XEL_TSR_XMIT_ACTIVE_MASK) != 0) { + + tx_status &= ~XEL_TSR_XMIT_ACTIVE_MASK; +- out_be32(base_addr + XEL_BUFFER_OFFSET + XEL_TSR_OFFSET, +- tx_status); ++ __raw_writel(tx_status, base_addr + XEL_BUFFER_OFFSET + ++ XEL_TSR_OFFSET); + + tx_complete = true; + } +@@ -726,7 +726,7 @@ static int xemaclite_mdio_wait(struct net_local *lp) + /* wait for the MDIO interface to not be busy or timeout + after some time. + */ +- while (in_be32(lp->base_addr + XEL_MDIOCTRL_OFFSET) & ++ while (__raw_readl(lp->base_addr + XEL_MDIOCTRL_OFFSET) & + XEL_MDIOCTRL_MDIOSTS_MASK) { + if (end - jiffies <= 0) { + WARN_ON(1); +@@ -762,17 +762,17 @@ static int xemaclite_mdio_read(struct mii_bus *bus, int phy_id, int reg) + * MDIO Address register. Set the Status bit in the MDIO Control + * register to start a MDIO read transaction. + */ +- ctrl_reg = in_be32(lp->base_addr + XEL_MDIOCTRL_OFFSET); +- out_be32(lp->base_addr + XEL_MDIOADDR_OFFSET, +- XEL_MDIOADDR_OP_MASK | +- ((phy_id << XEL_MDIOADDR_PHYADR_SHIFT) | reg)); +- out_be32(lp->base_addr + XEL_MDIOCTRL_OFFSET, +- ctrl_reg | XEL_MDIOCTRL_MDIOSTS_MASK); ++ ctrl_reg = __raw_readl(lp->base_addr + XEL_MDIOCTRL_OFFSET); ++ __raw_writel(XEL_MDIOADDR_OP_MASK | ++ ((phy_id << XEL_MDIOADDR_PHYADR_SHIFT) | reg), ++ lp->base_addr + XEL_MDIOADDR_OFFSET); ++ __raw_writel(ctrl_reg | XEL_MDIOCTRL_MDIOSTS_MASK, ++ lp->base_addr + XEL_MDIOCTRL_OFFSET); + + if (xemaclite_mdio_wait(lp)) + return -ETIMEDOUT; + +- rc = in_be32(lp->base_addr + XEL_MDIORD_OFFSET); ++ rc = __raw_readl(lp->base_addr + XEL_MDIORD_OFFSET); + + dev_dbg(&lp->ndev->dev, + "xemaclite_mdio_read(phy_id=%i, reg=%x) == %x\n", +@@ -809,13 +809,13 @@ static int xemaclite_mdio_write(struct mii_bus *bus, int phy_id, int reg, + * Data register. Finally, set the Status bit in the MDIO Control + * register to start a MDIO write transaction. + */ +- ctrl_reg = in_be32(lp->base_addr + XEL_MDIOCTRL_OFFSET); +- out_be32(lp->base_addr + XEL_MDIOADDR_OFFSET, +- ~XEL_MDIOADDR_OP_MASK & +- ((phy_id << XEL_MDIOADDR_PHYADR_SHIFT) | reg)); +- out_be32(lp->base_addr + XEL_MDIOWR_OFFSET, val); +- out_be32(lp->base_addr + XEL_MDIOCTRL_OFFSET, +- ctrl_reg | XEL_MDIOCTRL_MDIOSTS_MASK); ++ ctrl_reg = __raw_readl(lp->base_addr + XEL_MDIOCTRL_OFFSET); ++ __raw_writel(~XEL_MDIOADDR_OP_MASK & ++ ((phy_id << XEL_MDIOADDR_PHYADR_SHIFT) | reg), ++ lp->base_addr + XEL_MDIOADDR_OFFSET); ++ __raw_writel(val, lp->base_addr + XEL_MDIOWR_OFFSET); ++ __raw_writel(ctrl_reg | XEL_MDIOCTRL_MDIOSTS_MASK, ++ lp->base_addr + XEL_MDIOCTRL_OFFSET); + + return 0; + } +@@ -872,8 +872,8 @@ static int xemaclite_mdio_setup(struct net_local *lp, struct device *dev) + /* Enable the MDIO bus by asserting the enable bit in MDIO Control + * register. + */ +- out_be32(lp->base_addr + XEL_MDIOCTRL_OFFSET, +- XEL_MDIOCTRL_MDIOEN_MASK); ++ __raw_writel(XEL_MDIOCTRL_MDIOEN_MASK, ++ lp->base_addr + XEL_MDIOCTRL_OFFSET); + + bus = mdiobus_alloc(); + if (!bus) { +@@ -1198,8 +1198,8 @@ static int xemaclite_of_probe(struct platform_device *ofdev) + dev_warn(dev, "No MAC address found\n"); + + /* Clear the Tx CSR's in case this is a restart */ +- out_be32(lp->base_addr + XEL_TSR_OFFSET, 0); +- out_be32(lp->base_addr + XEL_BUFFER_OFFSET + XEL_TSR_OFFSET, 0); ++ __raw_writel(0, lp->base_addr + XEL_TSR_OFFSET); ++ __raw_writel(0, lp->base_addr + XEL_BUFFER_OFFSET + XEL_TSR_OFFSET); + + /* Set the MAC address in the EmacLite device */ + xemaclite_update_address(lp, ndev->dev_addr); +-- +1.8.5.rc3 + diff --git a/patches.zynq/0080-net-emaclite-Update-driver-header.patch b/patches.zynq/0080-net-emaclite-Update-driver-header.patch new file mode 100644 index 00000000000000..03c75054d53500 --- /dev/null +++ b/patches.zynq/0080-net-emaclite-Update-driver-header.patch @@ -0,0 +1,35 @@ +From 2dab913ba0a6e9d1db99eee05f0f4fb87f6be856 Mon Sep 17 00:00:00 2001 +From: Michal Simek <michal.simek@xilinx.com> +Date: Thu, 30 May 2013 00:28:08 +0000 +Subject: net: emaclite: Update driver header + +Correct email address and years. + +Signed-off-by: Michal Simek <michal.simek@xilinx.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +(cherry picked from commit 9e7c414350a6fa4e5f9b7e5f7e074fa75ba850c3) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + drivers/net/ethernet/xilinx/xilinx_emaclite.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/ethernet/xilinx/xilinx_emaclite.c b/drivers/net/ethernet/xilinx/xilinx_emaclite.c +index 476ce5bb385f..db16a063d2db 100644 +--- a/drivers/net/ethernet/xilinx/xilinx_emaclite.c ++++ b/drivers/net/ethernet/xilinx/xilinx_emaclite.c +@@ -2,9 +2,9 @@ + * Xilinx EmacLite Linux driver for the Xilinx Ethernet MAC Lite device. + * + * This is a new flat driver which is based on the original emac_lite +- * driver from John Williams <john.williams@petalogix.com>. ++ * driver from John Williams <john.williams@xilinx.com>. + * +- * 2007-2009 (c) Xilinx, Inc. ++ * 2007 - 2013 (c) Xilinx, Inc. + * + * 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 +-- +1.8.5.rc3 + diff --git a/patches.zynq/0081-net-emaclite-Fix-typo-in-error-message.patch b/patches.zynq/0081-net-emaclite-Fix-typo-in-error-message.patch new file mode 100644 index 00000000000000..52a2c7b2915410 --- /dev/null +++ b/patches.zynq/0081-net-emaclite-Fix-typo-in-error-message.patch @@ -0,0 +1,33 @@ +From be3069672ca5b9e0bf0e091e02a4e23e1c8b912a Mon Sep 17 00:00:00 2001 +From: "Jens Renner \\\\\\\\(EFE\\\\\\\\)" <renner@efe-gmbh.de> +Date: Sun, 2 Jun 2013 05:19:06 +0000 +Subject: net: emaclite: Fix typo in error message + +s/allocal/allocate/ + +Signed-off-by: Jens Renner <renner@efe-gmbh.de> +Acked-by: Michal Simek <monstr@monstr.eu> +Signed-off-by: David S. Miller <davem@davemloft.net> +(cherry picked from commit f1362e378ab27844f968f1f390e33b6c77861ec0) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + drivers/net/ethernet/xilinx/xilinx_emaclite.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/xilinx/xilinx_emaclite.c b/drivers/net/ethernet/xilinx/xilinx_emaclite.c +index db16a063d2db..277ed5df8b51 100644 +--- a/drivers/net/ethernet/xilinx/xilinx_emaclite.c ++++ b/drivers/net/ethernet/xilinx/xilinx_emaclite.c +@@ -877,7 +877,7 @@ static int xemaclite_mdio_setup(struct net_local *lp, struct device *dev) + + bus = mdiobus_alloc(); + if (!bus) { +- dev_err(dev, "Failed to allocal mdiobus\n"); ++ dev_err(dev, "Failed to allocate mdiobus\n"); + return -ENOMEM; + } + +-- +1.8.5.rc3 + diff --git a/patches.zynq/0082-net-emaclite-Use-platform-resource-table.patch b/patches.zynq/0082-net-emaclite-Use-platform-resource-table.patch new file mode 100644 index 00000000000000..7b579fb373c0e6 --- /dev/null +++ b/patches.zynq/0082-net-emaclite-Use-platform-resource-table.patch @@ -0,0 +1,153 @@ +From 84657794da4cb1c84d487de1612a61feee13da4a Mon Sep 17 00:00:00 2001 +From: Michal Simek <michal.simek@xilinx.com> +Date: Tue, 4 Jun 2013 00:03:27 +0000 +Subject: net: emaclite: Use platform resource table + +Read data directly from platform recource table +and do not use of_irq_to_resource(). +Also use devm_request_and_ioremap() for probe +functions simplification. + +Signed-off-by: Michal Simek <michal.simek@xilinx.com> +Acked-by: Arnd Bergmann <arnd@arndb.de> +Signed-off-by: David S. Miller <davem@davemloft.net> +(cherry picked from commit 7a3e2585f2fd543ac7284a1f09641628f730f720) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + drivers/net/ethernet/xilinx/xilinx_emaclite.c | 67 +++++++++------------------ + 1 file changed, 22 insertions(+), 45 deletions(-) + +diff --git a/drivers/net/ethernet/xilinx/xilinx_emaclite.c b/drivers/net/ethernet/xilinx/xilinx_emaclite.c +index 277ed5df8b51..1cd131bde680 100644 +--- a/drivers/net/ethernet/xilinx/xilinx_emaclite.c ++++ b/drivers/net/ethernet/xilinx/xilinx_emaclite.c +@@ -1075,13 +1075,14 @@ static int xemaclite_send(struct sk_buff *orig_skb, struct net_device *dev) + * This function un maps the IO region of the Emaclite device and frees the net + * device. + */ +-static void xemaclite_remove_ndev(struct net_device *ndev) ++static void xemaclite_remove_ndev(struct net_device *ndev, ++ struct platform_device *pdev) + { + if (ndev) { + struct net_local *lp = netdev_priv(ndev); + + if (lp->base_addr) +- iounmap((void __iomem __force *) (lp->base_addr)); ++ devm_iounmap(&pdev->dev, lp->base_addr); + free_netdev(ndev); + } + } +@@ -1127,8 +1128,7 @@ static struct net_device_ops xemaclite_netdev_ops; + */ + static int xemaclite_of_probe(struct platform_device *ofdev) + { +- struct resource r_irq; /* Interrupt resources */ +- struct resource r_mem; /* IO mem resources */ ++ struct resource *res; + struct net_device *ndev = NULL; + struct net_local *lp = NULL; + struct device *dev = &ofdev->dev; +@@ -1138,20 +1138,6 @@ static int xemaclite_of_probe(struct platform_device *ofdev) + + dev_info(dev, "Device Tree Probing\n"); + +- /* Get iospace for the device */ +- rc = of_address_to_resource(ofdev->dev.of_node, 0, &r_mem); +- if (rc) { +- dev_err(dev, "invalid address\n"); +- return rc; +- } +- +- /* Get IRQ for the device */ +- rc = of_irq_to_resource(ofdev->dev.of_node, 0, &r_irq); +- if (!rc) { +- dev_err(dev, "no IRQ found\n"); +- return rc; +- } +- + /* Create an ethernet device instance */ + ndev = alloc_etherdev(sizeof(struct net_local)); + if (!ndev) +@@ -1160,29 +1146,25 @@ static int xemaclite_of_probe(struct platform_device *ofdev) + dev_set_drvdata(dev, ndev); + SET_NETDEV_DEV(ndev, &ofdev->dev); + +- ndev->irq = r_irq.start; +- ndev->mem_start = r_mem.start; +- ndev->mem_end = r_mem.end; +- + lp = netdev_priv(ndev); + lp->ndev = ndev; + +- if (!request_mem_region(ndev->mem_start, +- ndev->mem_end - ndev->mem_start + 1, +- DRIVER_NAME)) { +- dev_err(dev, "Couldn't lock memory region at %p\n", +- (void *)ndev->mem_start); +- rc = -EBUSY; +- goto error2; ++ /* Get IRQ for the device */ ++ res = platform_get_resource(ofdev, IORESOURCE_IRQ, 0); ++ if (!res) { ++ dev_err(dev, "no IRQ found\n"); ++ goto error; + } + +- /* Get the virtual base address for the device */ +- lp->base_addr = ioremap(r_mem.start, resource_size(&r_mem)); +- if (NULL == lp->base_addr) { +- dev_err(dev, "EmacLite: Could not allocate iomem\n"); +- rc = -EIO; +- goto error1; +- } ++ ndev->irq = res->start; ++ ++ res = platform_get_resource(ofdev, IORESOURCE_MEM, 0); ++ lp->base_addr = devm_request_and_ioremap(&ofdev->dev, res); ++ if (!lp->base_addr) ++ goto error; ++ ++ ndev->mem_start = res->start; ++ ndev->mem_end = res->end; + + spin_lock_init(&lp->reset_lock); + lp->next_tx_buf_to_use = 0x0; +@@ -1220,7 +1202,7 @@ static int xemaclite_of_probe(struct platform_device *ofdev) + if (rc) { + dev_err(dev, + "Cannot register network device, aborting\n"); +- goto error1; ++ goto error; + } + + dev_info(dev, +@@ -1229,11 +1211,8 @@ static int xemaclite_of_probe(struct platform_device *ofdev) + (unsigned int __force)lp->base_addr, ndev->irq); + return 0; + +-error1: +- release_mem_region(ndev->mem_start, resource_size(&r_mem)); +- +-error2: +- xemaclite_remove_ndev(ndev); ++error: ++ xemaclite_remove_ndev(ndev, ofdev); + return rc; + } + +@@ -1268,9 +1247,7 @@ static int xemaclite_of_remove(struct platform_device *of_dev) + of_node_put(lp->phy_node); + lp->phy_node = NULL; + +- release_mem_region(ndev->mem_start, ndev->mem_end-ndev->mem_start + 1); +- +- xemaclite_remove_ndev(ndev); ++ xemaclite_remove_ndev(ndev, of_dev); + dev_set_drvdata(dev, NULL); + + return 0; +-- +1.8.5.rc3 + diff --git a/patches.zynq/0083-net-emaclite-Convert-to-use-devm_ioremap_resource.patch b/patches.zynq/0083-net-emaclite-Convert-to-use-devm_ioremap_resource.patch new file mode 100644 index 00000000000000..22b3288c3bf76e --- /dev/null +++ b/patches.zynq/0083-net-emaclite-Convert-to-use-devm_ioremap_resource.patch @@ -0,0 +1,42 @@ +From 6c30c07d8845bf77822a34b374dd2315751f9d64 Mon Sep 17 00:00:00 2001 +From: Tushar Behera <tushar.behera@linaro.org> +Date: Mon, 10 Jun 2013 17:05:06 +0530 +Subject: net: emaclite: Convert to use devm_ioremap_resource + +Commit 75096579c3ac ("lib: devres: Introduce devm_ioremap_resource()") +introduced devm_ioremap_resource() and deprecated the use of +devm_request_and_ioremap(). + +Signed-off-by: Tushar Behera <tushar.behera@linaro.org> +CC: netdev@vger.kernel.org +CC: "David S. Miller" <davem@davemloft.net> +CC: Michal Simek <michal.simek@xilinx.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +(cherry picked from commit eed5d29d7818cc7a84e60123555cae154e5b4a73) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + drivers/net/ethernet/xilinx/xilinx_emaclite.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/ethernet/xilinx/xilinx_emaclite.c b/drivers/net/ethernet/xilinx/xilinx_emaclite.c +index 1cd131bde680..fd4dbdae5331 100644 +--- a/drivers/net/ethernet/xilinx/xilinx_emaclite.c ++++ b/drivers/net/ethernet/xilinx/xilinx_emaclite.c +@@ -1159,9 +1159,11 @@ static int xemaclite_of_probe(struct platform_device *ofdev) + ndev->irq = res->start; + + res = platform_get_resource(ofdev, IORESOURCE_MEM, 0); +- lp->base_addr = devm_request_and_ioremap(&ofdev->dev, res); +- if (!lp->base_addr) ++ lp->base_addr = devm_ioremap_resource(&ofdev->dev, res); ++ if (IS_ERR(lp->base_addr)) { ++ rc = PTR_ERR(lp->base_addr); + goto error; ++ } + + ndev->mem_start = res->start; + ndev->mem_end = res->end; +-- +1.8.5.rc3 + diff --git a/patches.zynq/0084-net-xilinx_emaclite-use-platform_-get-set-_drvdata.patch b/patches.zynq/0084-net-xilinx_emaclite-use-platform_-get-set-_drvdata.patch new file mode 100644 index 00000000000000..a70bb812bba880 --- /dev/null +++ b/patches.zynq/0084-net-xilinx_emaclite-use-platform_-get-set-_drvdata.patch @@ -0,0 +1,36 @@ +From faaca44d1439cafd192cddd3697a26f9c447e459 Mon Sep 17 00:00:00 2001 +From: Libo Chen <clbchenlibo.chen@huawei.com> +Date: Mon, 19 Aug 2013 20:00:25 +0800 +Subject: net: xilinx_emaclite: use platform_{get,set}_drvdata() + +Use the wrapper functions for getting and setting the driver data using +platform_device instead of using dev_{get,set}_drvdata() with &of_dev->dev, +so we can directly pass a struct platform_device. + +Signed-off-by: Libo Chen <libo.chen@huawei.com> +Acked-by: Michal Simek <monstr@monstr.eu> +Signed-off-by: David S. Miller <davem@davemloft.net> +(cherry picked from commit 34e0184d98bd3a0e19b1d55bfdbd2186bfe5eca4) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + drivers/net/ethernet/xilinx/xilinx_emaclite.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/drivers/net/ethernet/xilinx/xilinx_emaclite.c b/drivers/net/ethernet/xilinx/xilinx_emaclite.c +index fd4dbdae5331..7c1ccbcb47be 100644 +--- a/drivers/net/ethernet/xilinx/xilinx_emaclite.c ++++ b/drivers/net/ethernet/xilinx/xilinx_emaclite.c +@@ -1230,8 +1230,7 @@ error: + */ + static int xemaclite_of_remove(struct platform_device *of_dev) + { +- struct device *dev = &of_dev->dev; +- struct net_device *ndev = dev_get_drvdata(dev); ++ struct net_device *ndev = platform_get_drvdata(of_dev); + + struct net_local *lp = netdev_priv(ndev); + +-- +1.8.5.rc3 + diff --git a/patches.zynq/0085-net-xilinx_emaclite-remove-unnecessary-dev_set_drvda.patch b/patches.zynq/0085-net-xilinx_emaclite-remove-unnecessary-dev_set_drvda.patch new file mode 100644 index 00000000000000..df2de0fab6f438 --- /dev/null +++ b/patches.zynq/0085-net-xilinx_emaclite-remove-unnecessary-dev_set_drvda.patch @@ -0,0 +1,33 @@ +From d86c156dc2af3f3ca187be9b613a594b80b0c662 Mon Sep 17 00:00:00 2001 +From: Libo Chen <libo.chen@huawei.com> +Date: Wed, 21 Aug 2013 15:02:36 +0800 +Subject: net: xilinx_emaclite: remove unnecessary dev_set_drvdata() + +Unnecessary dev_set_drvdata() is removed, because the driver core +clears the driver data to NULL after device_release or on probe failure. + +Signed-off-by: Libo Chen <libo.chen@huawei.com> +Acked-by: Michal Simek <monstr@monstr.eu> +Signed-off-by: David S. Miller <davem@davemloft.net> +(cherry picked from commit 0c671dc0c4979e69e0b342c8f4e80690660929db) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + drivers/net/ethernet/xilinx/xilinx_emaclite.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/drivers/net/ethernet/xilinx/xilinx_emaclite.c b/drivers/net/ethernet/xilinx/xilinx_emaclite.c +index 7c1ccbcb47be..4c619ea5189f 100644 +--- a/drivers/net/ethernet/xilinx/xilinx_emaclite.c ++++ b/drivers/net/ethernet/xilinx/xilinx_emaclite.c +@@ -1249,7 +1249,6 @@ static int xemaclite_of_remove(struct platform_device *of_dev) + lp->phy_node = NULL; + + xemaclite_remove_ndev(ndev, of_dev); +- dev_set_drvdata(dev, NULL); + + return 0; + } +-- +1.8.5.rc3 + diff --git a/patches.zynq/0086-net-emaclite-Not-necessary-to-call-devm_iounmap.patch b/patches.zynq/0086-net-emaclite-Not-necessary-to-call-devm_iounmap.patch new file mode 100644 index 00000000000000..adf93d97f21854 --- /dev/null +++ b/patches.zynq/0086-net-emaclite-Not-necessary-to-call-devm_iounmap.patch @@ -0,0 +1,57 @@ +From d06fa8fb32fbcea7f449009d6907fe860a7c9148 Mon Sep 17 00:00:00 2001 +From: Michal Simek <michal.simek@xilinx.com> +Date: Thu, 12 Sep 2013 09:05:10 +0200 +Subject: net: emaclite: Not necessary to call devm_iounmap + +devm_iounmap is called automatically. + +Signed-off-by: Michal Simek <michal.simek@xilinx.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +(cherry picked from commit 37c67c6e2bb5b8f287d92e543acb0f8fa41af0e9) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + drivers/net/ethernet/xilinx/xilinx_emaclite.c | 11 +++-------- + 1 file changed, 3 insertions(+), 8 deletions(-) + +diff --git a/drivers/net/ethernet/xilinx/xilinx_emaclite.c b/drivers/net/ethernet/xilinx/xilinx_emaclite.c +index 4c619ea5189f..de3909878f42 100644 +--- a/drivers/net/ethernet/xilinx/xilinx_emaclite.c ++++ b/drivers/net/ethernet/xilinx/xilinx_emaclite.c +@@ -1075,14 +1075,9 @@ static int xemaclite_send(struct sk_buff *orig_skb, struct net_device *dev) + * This function un maps the IO region of the Emaclite device and frees the net + * device. + */ +-static void xemaclite_remove_ndev(struct net_device *ndev, +- struct platform_device *pdev) ++static void xemaclite_remove_ndev(struct net_device *ndev) + { + if (ndev) { +- struct net_local *lp = netdev_priv(ndev); +- +- if (lp->base_addr) +- devm_iounmap(&pdev->dev, lp->base_addr); + free_netdev(ndev); + } + } +@@ -1214,7 +1209,7 @@ static int xemaclite_of_probe(struct platform_device *ofdev) + return 0; + + error: +- xemaclite_remove_ndev(ndev, ofdev); ++ xemaclite_remove_ndev(ndev); + return rc; + } + +@@ -1248,7 +1243,7 @@ static int xemaclite_of_remove(struct platform_device *of_dev) + of_node_put(lp->phy_node); + lp->phy_node = NULL; + +- xemaclite_remove_ndev(ndev, of_dev); ++ xemaclite_remove_ndev(ndev); + + return 0; + } +-- +1.8.5.rc3 + diff --git a/patches.zynq/0087-net-emaclite-Code-cleanup.patch b/patches.zynq/0087-net-emaclite-Code-cleanup.patch new file mode 100644 index 00000000000000..fc80008384130e --- /dev/null +++ b/patches.zynq/0087-net-emaclite-Code-cleanup.patch @@ -0,0 +1,81 @@ +From 719ac1a1d2302ca98fa5552738915e7556e8e1df Mon Sep 17 00:00:00 2001 +From: Michal Simek <michal.simek@xilinx.com> +Date: Thu, 12 Sep 2013 09:05:11 +0200 +Subject: net: emaclite: Code cleanup + +No function changes (s/\ \t/\t/g) + +Signed-off-by: Michal Simek <michal.simek@xilinx.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +(cherry picked from commit cd738c4edeb30507789bcd69ca25c4c569c60971) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + drivers/net/ethernet/xilinx/xilinx_emaclite.c | 28 +++++++++++++-------------- + 1 file changed, 14 insertions(+), 14 deletions(-) + +diff --git a/drivers/net/ethernet/xilinx/xilinx_emaclite.c b/drivers/net/ethernet/xilinx/xilinx_emaclite.c +index de3909878f42..80dd40417850 100644 +--- a/drivers/net/ethernet/xilinx/xilinx_emaclite.c ++++ b/drivers/net/ethernet/xilinx/xilinx_emaclite.c +@@ -31,7 +31,7 @@ + #define DRIVER_NAME "xilinx_emaclite" + + /* Register offsets for the EmacLite Core */ +-#define XEL_TXBUFF_OFFSET 0x0 /* Transmit Buffer */ ++#define XEL_TXBUFF_OFFSET 0x0 /* Transmit Buffer */ + #define XEL_MDIOADDR_OFFSET 0x07E4 /* MDIO Address Register */ + #define XEL_MDIOWR_OFFSET 0x07E8 /* MDIO Write Data Register */ + #define XEL_MDIORD_OFFSET 0x07EC /* MDIO Read Data Register */ +@@ -63,13 +63,13 @@ + #define XEL_MDIOCTRL_MDIOEN_MASK 0x00000008 /* MDIO Enable */ + + /* Global Interrupt Enable Register (GIER) Bit Masks */ +-#define XEL_GIER_GIE_MASK 0x80000000 /* Global Enable */ ++#define XEL_GIER_GIE_MASK 0x80000000 /* Global Enable */ + + /* Transmit Status Register (TSR) Bit Masks */ +-#define XEL_TSR_XMIT_BUSY_MASK 0x00000001 /* Tx complete */ +-#define XEL_TSR_PROGRAM_MASK 0x00000002 /* Program the MAC address */ +-#define XEL_TSR_XMIT_IE_MASK 0x00000008 /* Tx interrupt enable bit */ +-#define XEL_TSR_XMIT_ACTIVE_MASK 0x80000000 /* Buffer is active, SW bit ++#define XEL_TSR_XMIT_BUSY_MASK 0x00000001 /* Tx complete */ ++#define XEL_TSR_PROGRAM_MASK 0x00000002 /* Program the MAC address */ ++#define XEL_TSR_XMIT_IE_MASK 0x00000008 /* Tx interrupt enable bit */ ++#define XEL_TSR_XMIT_ACTIVE_MASK 0x80000000 /* Buffer is active, SW bit + * only. This is not documented + * in the HW spec */ + +@@ -77,21 +77,21 @@ + #define XEL_TSR_PROG_MAC_ADDR (XEL_TSR_XMIT_BUSY_MASK | XEL_TSR_PROGRAM_MASK) + + /* Receive Status Register (RSR) */ +-#define XEL_RSR_RECV_DONE_MASK 0x00000001 /* Rx complete */ +-#define XEL_RSR_RECV_IE_MASK 0x00000008 /* Rx interrupt enable bit */ ++#define XEL_RSR_RECV_DONE_MASK 0x00000001 /* Rx complete */ ++#define XEL_RSR_RECV_IE_MASK 0x00000008 /* Rx interrupt enable bit */ + + /* Transmit Packet Length Register (TPLR) */ +-#define XEL_TPLR_LENGTH_MASK 0x0000FFFF /* Tx packet length */ ++#define XEL_TPLR_LENGTH_MASK 0x0000FFFF /* Tx packet length */ + + /* Receive Packet Length Register (RPLR) */ +-#define XEL_RPLR_LENGTH_MASK 0x0000FFFF /* Rx packet length */ ++#define XEL_RPLR_LENGTH_MASK 0x0000FFFF /* Rx packet length */ + +-#define XEL_HEADER_OFFSET 12 /* Offset to length field */ +-#define XEL_HEADER_SHIFT 16 /* Shift value for length */ ++#define XEL_HEADER_OFFSET 12 /* Offset to length field */ ++#define XEL_HEADER_SHIFT 16 /* Shift value for length */ + + /* General Ethernet Definitions */ +-#define XEL_ARP_PACKET_SIZE 28 /* Max ARP packet size */ +-#define XEL_HEADER_IP_LENGTH_OFFSET 16 /* IP Length Offset */ ++#define XEL_ARP_PACKET_SIZE 28 /* Max ARP packet size */ ++#define XEL_HEADER_IP_LENGTH_OFFSET 16 /* IP Length Offset */ + + + +-- +1.8.5.rc3 + diff --git a/patches.zynq/0088-net-drivers-net-Miscellaneous-conversions-to-ETH_ALE.patch b/patches.zynq/0088-net-drivers-net-Miscellaneous-conversions-to-ETH_ALE.patch new file mode 100644 index 00000000000000..4a7c687facd28a --- /dev/null +++ b/patches.zynq/0088-net-drivers-net-Miscellaneous-conversions-to-ETH_ALE.patch @@ -0,0 +1,37 @@ +From 2adf21bf924409584d87c91c14352a17ffbe3cec Mon Sep 17 00:00:00 2001 +From: Joe Perches <joe@perches.com> +Date: Tue, 1 Oct 2013 19:04:40 -0700 +Subject: net:drivers/net: Miscellaneous conversions to ETH_ALEN + +Convert the memset/memcpy uses of 6 to ETH_ALEN +where appropriate. + +Also convert some struct definitions and u8 array +declarations of [6] to ETH_ALEN. + +Signed-off-by: Joe Perches <joe@perches.com> +Acked-by: Arend van Spriel <arend@broadcom.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +(cherry picked from commit d458cdf712e0c671e8e819abb16ecd6e44f9daec) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + drivers/net/ethernet/xilinx/xilinx_emaclite.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/xilinx/xilinx_emaclite.c b/drivers/net/ethernet/xilinx/xilinx_emaclite.c +index 80dd40417850..74234a51c851 100644 +--- a/drivers/net/ethernet/xilinx/xilinx_emaclite.c ++++ b/drivers/net/ethernet/xilinx/xilinx_emaclite.c +@@ -1172,7 +1172,7 @@ static int xemaclite_of_probe(struct platform_device *ofdev) + + if (mac_address) + /* Set the MAC address. */ +- memcpy(ndev->dev_addr, mac_address, 6); ++ memcpy(ndev->dev_addr, mac_address, ETH_ALEN); + else + dev_warn(dev, "No MAC address found\n"); + +-- +1.8.5.rc3 + diff --git a/patches.zynq/0089-net-xilinx-fix-memleak.patch b/patches.zynq/0089-net-xilinx-fix-memleak.patch new file mode 100644 index 00000000000000..e15b595c0050ae --- /dev/null +++ b/patches.zynq/0089-net-xilinx-fix-memleak.patch @@ -0,0 +1,31 @@ +From c5edcd0ec952e1793f75641ab413d3c06f7426cc Mon Sep 17 00:00:00 2001 +From: Libo Chen <clbchenlibo.chen@huawei.com> +Date: Mon, 26 Aug 2013 11:30:55 +0800 +Subject: net: xilinx: fix memleak + +decrease device_node refcount np1 in err case. + +Signed-off-by: Libo Chen <libo.chen@huawei.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +(cherry picked from commit 282a1dffc1b9976cdf1b0eea3f6f68fda23a7c7e) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c b/drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c +index e90e1f46121e..64b4639f43b6 100644 +--- a/drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c ++++ b/drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c +@@ -175,6 +175,7 @@ int axienet_mdio_setup(struct axienet_local *lp, struct device_node *np) + printk(KERN_WARNING "Setting MDIO clock divisor to " + "default %d\n", DEFAULT_CLOCK_DIVISOR); + clk_div = DEFAULT_CLOCK_DIVISOR; ++ of_node_put(np1); + goto issue; + } + +-- +1.8.5.rc3 + diff --git a/patches.zynq/0090-net-emaclite-Enable-emaclite-for-Xilinx-Arm-Zynq-pla.patch b/patches.zynq/0090-net-emaclite-Enable-emaclite-for-Xilinx-Arm-Zynq-pla.patch new file mode 100644 index 00000000000000..cd2f8e09bbb6c6 --- /dev/null +++ b/patches.zynq/0090-net-emaclite-Enable-emaclite-for-Xilinx-Arm-Zynq-pla.patch @@ -0,0 +1,41 @@ +From 718522d276fb1e1d51825b2e4bc4f95ad66aa486 Mon Sep 17 00:00:00 2001 +From: Michal Simek <michal.simek@xilinx.com> +Date: Thu, 30 May 2013 00:28:07 +0000 +Subject: net: emaclite: Enable emaclite for Xilinx Arm Zynq platform + +Enable emaclite for Xilinx ARM Zynq platform. + +Signed-off-by: Michal Simek <michal.simek@xilinx.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +(cherry picked from commit 1156ee88dd3992bbacd5e4c659530f9d18c07378) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + drivers/net/ethernet/xilinx/Kconfig | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/ethernet/xilinx/Kconfig b/drivers/net/ethernet/xilinx/Kconfig +index 122d60c0481b..7b90a5eba099 100644 +--- a/drivers/net/ethernet/xilinx/Kconfig ++++ b/drivers/net/ethernet/xilinx/Kconfig +@@ -5,7 +5,7 @@ + config NET_VENDOR_XILINX + bool "Xilinx devices" + default y +- depends on PPC || PPC32 || MICROBLAZE ++ depends on PPC || PPC32 || MICROBLAZE || ARCH_ZYNQ + ---help--- + If you have a network (Ethernet) card belonging to this class, say Y + and read the Ethernet-HOWTO, available from +@@ -20,7 +20,7 @@ if NET_VENDOR_XILINX + + config XILINX_EMACLITE + tristate "Xilinx 10/100 Ethernet Lite support" +- depends on (PPC32 || MICROBLAZE) ++ depends on (PPC32 || MICROBLAZE || ARCH_ZYNQ) + select PHYLIB + ---help--- + This driver supports the 10/100 Ethernet Lite from Xilinx. +-- +1.8.5.rc3 + diff --git a/patches.zynq/0091-microblaze-clean-up-prom.h-implicit-includes.patch b/patches.zynq/0091-microblaze-clean-up-prom.h-implicit-includes.patch new file mode 100644 index 00000000000000..54ff315e737dc1 --- /dev/null +++ b/patches.zynq/0091-microblaze-clean-up-prom.h-implicit-includes.patch @@ -0,0 +1,36 @@ +From 14ec0ffcfb7545768e634df49a932ab297892eab Mon Sep 17 00:00:00 2001 +From: Rob Herring <rob.herring@calxeda.com> +Date: Sat, 7 Sep 2013 14:05:10 -0500 +Subject: microblaze: clean-up prom.h implicit includes + +While powerpc is a mess of implicit includes by prom.h, microblaze just +copied this and is easily fixed. Add the necessary explicit includes and +remove unnecessary includes and other parts from prom.h + +Signed-off-by: Rob Herring <rob.herring@calxeda.com> +Acked-by: Grant Likely <grant.likely@linaro.org> +Cc: Michal Simek <monstr@monstr.eu> +Cc: microblaze-uclinux@itee.uq.edu.au +Cc: netdev@vger.kernel.org +(cherry picked from commit 5c9f303e996516dd0dcc2ce8c2b95504d3137b19) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + drivers/net/ethernet/xilinx/ll_temac_main.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/net/ethernet/xilinx/ll_temac_main.c b/drivers/net/ethernet/xilinx/ll_temac_main.c +index 0029148077a9..1f2364126323 100644 +--- a/drivers/net/ethernet/xilinx/ll_temac_main.c ++++ b/drivers/net/ethernet/xilinx/ll_temac_main.c +@@ -36,6 +36,7 @@ + #include <linux/netdevice.h> + #include <linux/of.h> + #include <linux/of_device.h> ++#include <linux/of_irq.h> + #include <linux/of_mdio.h> + #include <linux/of_platform.h> + #include <linux/of_address.h> +-- +1.8.5.rc3 + diff --git a/patches.zynq/0092-video-xilinxfb-Fix-OF-probing-on-little-endian-syste.patch b/patches.zynq/0092-video-xilinxfb-Fix-OF-probing-on-little-endian-syste.patch new file mode 100644 index 00000000000000..3b65e5498012e3 --- /dev/null +++ b/patches.zynq/0092-video-xilinxfb-Fix-OF-probing-on-little-endian-syste.patch @@ -0,0 +1,47 @@ +From 6eab05d19e8c76621d29e41a4b1101b9c3fe61a9 Mon Sep 17 00:00:00 2001 +From: Michal Simek <monstr@monstr.eu> +Date: Mon, 3 Jun 2013 12:13:16 +0200 +Subject: video: xilinxfb: Fix OF probing on little-endian systems + +DTB is always big-endian that's why it is necessary +to properly convert value (*p). +It is automatically done in of_property_read_u32(). + +Signed-off-by: Michal Simek <michal.simek@xilinx.com> +Acked-by: Arnd Bergmann <arnd@arndb.de> +Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com> +(cherry picked from commit 0f5e17c5fde5d28b26cd83e077c21d28bbf50a80) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + drivers/video/xilinxfb.c | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +diff --git a/drivers/video/xilinxfb.c b/drivers/video/xilinxfb.c +index af0b4fdf9aa9..aecd15d0b8e5 100644 +--- a/drivers/video/xilinxfb.c ++++ b/drivers/video/xilinxfb.c +@@ -406,8 +406,7 @@ static int xilinxfb_release(struct device *dev) + static int xilinxfb_of_probe(struct platform_device *op) + { + const u32 *prop; +- u32 *p; +- u32 tft_access; ++ u32 tft_access = 0; + struct xilinxfb_platform_data pdata; + struct resource res; + int size, rc; +@@ -427,8 +426,8 @@ static int xilinxfb_of_probe(struct platform_device *op) + * To check whether the core is connected directly to DCR or PLB + * interface and initialize the tft_access accordingly. + */ +- p = (u32 *)of_get_property(op->dev.of_node, "xlnx,dcr-splb-slave-if", NULL); +- tft_access = p ? *p : 0; ++ of_property_read_u32(op->dev.of_node, "xlnx,dcr-splb-slave-if", ++ &tft_access); + + /* + * Fill the resource structure if its direct PLB interface +-- +1.8.5.rc3 + diff --git a/patches.zynq/0093-video-xilinxfb-Do-not-name-out_be32-in-function-name.patch b/patches.zynq/0093-video-xilinxfb-Do-not-name-out_be32-in-function-name.patch new file mode 100644 index 00000000000000..dc532abb7aeefa --- /dev/null +++ b/patches.zynq/0093-video-xilinxfb-Do-not-name-out_be32-in-function-name.patch @@ -0,0 +1,97 @@ +From 06d9bcbefcf59969ffce43888d5d319d4d89b0c9 Mon Sep 17 00:00:00 2001 +From: Michal Simek <michal.simek@xilinx.com> +Date: Mon, 3 Jun 2013 12:13:17 +0200 +Subject: video: xilinxfb: Do not name out_be32 in function name + +out_be32 IO function is not supported by ARM. +It is only available for PPC and Microblaze. +Because this driver can be used on ARM let's +remove out_be32 from function name. + +Signed-off-by: Michal Simek <michal.simek@xilinx.com> +Acked-by: Arnd Bergmann <arnd@arndb.de> +Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com> +(cherry picked from commit ec05e7a8aaf5fd73a64d28fc9f28384ea247cc1c) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + drivers/video/xilinxfb.c | 16 ++++++++-------- + 1 file changed, 8 insertions(+), 8 deletions(-) + +diff --git a/drivers/video/xilinxfb.c b/drivers/video/xilinxfb.c +index aecd15d0b8e5..c9b442b928e5 100644 +--- a/drivers/video/xilinxfb.c ++++ b/drivers/video/xilinxfb.c +@@ -57,7 +57,7 @@ + * In case of direct PLB access the second control register will be at + * an offset of 4 as compared to the DCR access where the offset is 1 + * i.e. REG_CTRL. So this is taken care in the function +- * xilinx_fb_out_be32 where it left shifts the offset 2 times in case of ++ * xilinx_fb_out32 where it left shifts the offset 2 times in case of + * direct PLB access. + */ + #define NUM_REGS 2 +@@ -150,7 +150,7 @@ struct xilinxfb_drvdata { + * To perform the read/write on the registers we need to check on + * which bus its connected and call the appropriate write API. + */ +-static void xilinx_fb_out_be32(struct xilinxfb_drvdata *drvdata, u32 offset, ++static void xilinx_fb_out32(struct xilinxfb_drvdata *drvdata, u32 offset, + u32 val) + { + if (drvdata->flags & PLB_ACCESS_FLAG) +@@ -197,7 +197,7 @@ xilinx_fb_blank(int blank_mode, struct fb_info *fbi) + switch (blank_mode) { + case FB_BLANK_UNBLANK: + /* turn on panel */ +- xilinx_fb_out_be32(drvdata, REG_CTRL, drvdata->reg_ctrl_default); ++ xilinx_fb_out32(drvdata, REG_CTRL, drvdata->reg_ctrl_default); + break; + + case FB_BLANK_NORMAL: +@@ -205,7 +205,7 @@ xilinx_fb_blank(int blank_mode, struct fb_info *fbi) + case FB_BLANK_HSYNC_SUSPEND: + case FB_BLANK_POWERDOWN: + /* turn off panel */ +- xilinx_fb_out_be32(drvdata, REG_CTRL, 0); ++ xilinx_fb_out32(drvdata, REG_CTRL, 0); + default: + break; + +@@ -280,13 +280,13 @@ static int xilinxfb_assign(struct device *dev, + memset_io((void __iomem *)drvdata->fb_virt, 0, fbsize); + + /* Tell the hardware where the frame buffer is */ +- xilinx_fb_out_be32(drvdata, REG_FB_ADDR, drvdata->fb_phys); ++ xilinx_fb_out32(drvdata, REG_FB_ADDR, drvdata->fb_phys); + + /* Turn on the display */ + drvdata->reg_ctrl_default = REG_CTRL_ENABLE; + if (pdata->rotate_screen) + drvdata->reg_ctrl_default |= REG_CTRL_ROTATE; +- xilinx_fb_out_be32(drvdata, REG_CTRL, ++ xilinx_fb_out32(drvdata, REG_CTRL, + drvdata->reg_ctrl_default); + + /* Fill struct fb_info */ +@@ -345,7 +345,7 @@ err_cmap: + iounmap(drvdata->fb_virt); + + /* Turn off the display */ +- xilinx_fb_out_be32(drvdata, REG_CTRL, 0); ++ xilinx_fb_out32(drvdata, REG_CTRL, 0); + + err_fbmem: + if (drvdata->flags & PLB_ACCESS_FLAG) +@@ -381,7 +381,7 @@ static int xilinxfb_release(struct device *dev) + iounmap(drvdata->fb_virt); + + /* Turn off the display */ +- xilinx_fb_out_be32(drvdata, REG_CTRL, 0); ++ xilinx_fb_out32(drvdata, REG_CTRL, 0); + + /* Release the resources, as allocated based on interface */ + if (drvdata->flags & PLB_ACCESS_FLAG) { +-- +1.8.5.rc3 + diff --git a/patches.zynq/0094-video-xilinxfb-Rename-PLB_ACCESS_FLAG-to-BUS_ACCESS_.patch b/patches.zynq/0094-video-xilinxfb-Rename-PLB_ACCESS_FLAG-to-BUS_ACCESS_.patch new file mode 100644 index 00000000000000..5c7a36782c904e --- /dev/null +++ b/patches.zynq/0094-video-xilinxfb-Rename-PLB_ACCESS_FLAG-to-BUS_ACCESS_.patch @@ -0,0 +1,151 @@ +From d0d6431effc0e1841db0555b9ad4eefa8da18491 Mon Sep 17 00:00:00 2001 +From: Michal Simek <michal.simek@xilinx.com> +Date: Mon, 3 Jun 2013 12:13:18 +0200 +Subject: video: xilinxfb: Rename PLB_ACCESS_FLAG to BUS_ACCESS_FLAG + +Using only PLB name is wrong for a long time because +the same access functions are also used for AXI. +s/PLB/BUS/g + +Signed-off-by: Michal Simek <michal.simek@xilinx.com> +Acked-by: Arnd Bergmann <arnd@arndb.de> +Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com> +(cherry picked from commit 5130af35bf34e7b57e86c7f72c08b8c68adbb425) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + drivers/video/xilinxfb.c | 32 ++++++++++++++++---------------- + 1 file changed, 16 insertions(+), 16 deletions(-) + +diff --git a/drivers/video/xilinxfb.c b/drivers/video/xilinxfb.c +index c9b442b928e5..d94c99280144 100644 +--- a/drivers/video/xilinxfb.c ++++ b/drivers/video/xilinxfb.c +@@ -44,7 +44,7 @@ + + + /* +- * Xilinx calls it "PLB TFT LCD Controller" though it can also be used for ++ * Xilinx calls it "TFT LCD Controller" though it can also be used for + * the VGA port on the Xilinx ML40x board. This is a hardware display + * controller for a 640x480 resolution TFT or VGA screen. + * +@@ -54,11 +54,11 @@ + * don't start thinking about scrolling). The second allows the LCD to + * be turned on or off as well as rotated 180 degrees. + * +- * In case of direct PLB access the second control register will be at ++ * In case of direct BUS access the second control register will be at + * an offset of 4 as compared to the DCR access where the offset is 1 + * i.e. REG_CTRL. So this is taken care in the function + * xilinx_fb_out32 where it left shifts the offset 2 times in case of +- * direct PLB access. ++ * direct BUS access. + */ + #define NUM_REGS 2 + #define REG_FB_ADDR 0 +@@ -116,7 +116,7 @@ static struct fb_var_screeninfo xilinx_fb_var = { + }; + + +-#define PLB_ACCESS_FLAG 0x1 /* 1 = PLB, 0 = DCR */ ++#define BUS_ACCESS_FLAG 0x1 /* 1 = BUS, 0 = DCR */ + + struct xilinxfb_drvdata { + +@@ -146,14 +146,14 @@ struct xilinxfb_drvdata { + container_of(_info, struct xilinxfb_drvdata, info) + + /* +- * The XPS TFT Controller can be accessed through PLB or DCR interface. ++ * The XPS TFT Controller can be accessed through BUS or DCR interface. + * To perform the read/write on the registers we need to check on + * which bus its connected and call the appropriate write API. + */ + static void xilinx_fb_out32(struct xilinxfb_drvdata *drvdata, u32 offset, + u32 val) + { +- if (drvdata->flags & PLB_ACCESS_FLAG) ++ if (drvdata->flags & BUS_ACCESS_FLAG) + out_be32(drvdata->regs + (offset << 2), val); + #ifdef CONFIG_PPC_DCR + else +@@ -235,10 +235,10 @@ static int xilinxfb_assign(struct device *dev, + int rc; + int fbsize = pdata->xvirt * pdata->yvirt * BYTES_PER_PIXEL; + +- if (drvdata->flags & PLB_ACCESS_FLAG) { ++ if (drvdata->flags & BUS_ACCESS_FLAG) { + /* + * Map the control registers in if the controller +- * is on direct PLB interface. ++ * is on direct BUS interface. + */ + if (!request_mem_region(physaddr, 8, DRIVER_NAME)) { + dev_err(dev, "Couldn't lock memory region at 0x%08lX\n", +@@ -270,7 +270,7 @@ static int xilinxfb_assign(struct device *dev, + if (!drvdata->fb_virt) { + dev_err(dev, "Could not allocate frame buffer memory\n"); + rc = -ENOMEM; +- if (drvdata->flags & PLB_ACCESS_FLAG) ++ if (drvdata->flags & BUS_ACCESS_FLAG) + goto err_fbmem; + else + goto err_region; +@@ -323,7 +323,7 @@ static int xilinxfb_assign(struct device *dev, + goto err_regfb; + } + +- if (drvdata->flags & PLB_ACCESS_FLAG) { ++ if (drvdata->flags & BUS_ACCESS_FLAG) { + /* Put a banner in the log (for DEBUG) */ + dev_dbg(dev, "regs: phys=%lx, virt=%p\n", physaddr, + drvdata->regs); +@@ -348,11 +348,11 @@ err_cmap: + xilinx_fb_out32(drvdata, REG_CTRL, 0); + + err_fbmem: +- if (drvdata->flags & PLB_ACCESS_FLAG) ++ if (drvdata->flags & BUS_ACCESS_FLAG) + iounmap(drvdata->regs); + + err_map: +- if (drvdata->flags & PLB_ACCESS_FLAG) ++ if (drvdata->flags & BUS_ACCESS_FLAG) + release_mem_region(physaddr, 8); + + err_region: +@@ -384,7 +384,7 @@ static int xilinxfb_release(struct device *dev) + xilinx_fb_out32(drvdata, REG_CTRL, 0); + + /* Release the resources, as allocated based on interface */ +- if (drvdata->flags & PLB_ACCESS_FLAG) { ++ if (drvdata->flags & BUS_ACCESS_FLAG) { + iounmap(drvdata->regs); + release_mem_region(drvdata->regs_phys, 8); + } +@@ -423,18 +423,18 @@ static int xilinxfb_of_probe(struct platform_device *op) + } + + /* +- * To check whether the core is connected directly to DCR or PLB ++ * To check whether the core is connected directly to DCR or BUS + * interface and initialize the tft_access accordingly. + */ + of_property_read_u32(op->dev.of_node, "xlnx,dcr-splb-slave-if", + &tft_access); + + /* +- * Fill the resource structure if its direct PLB interface ++ * Fill the resource structure if its direct BUS interface + * otherwise fill the dcr_host structure. + */ + if (tft_access) { +- drvdata->flags |= PLB_ACCESS_FLAG; ++ drvdata->flags |= BUS_ACCESS_FLAG; + rc = of_address_to_resource(op->dev.of_node, 0, &res); + if (rc) { + dev_err(&op->dev, "invalid address\n"); +-- +1.8.5.rc3 + diff --git a/patches.zynq/0095-video-xilinxfb-Use-drvdata-regs_phys-instead-of-phys.patch b/patches.zynq/0095-video-xilinxfb-Use-drvdata-regs_phys-instead-of-phys.patch new file mode 100644 index 00000000000000..c57a462c0ffb2a --- /dev/null +++ b/patches.zynq/0095-video-xilinxfb-Use-drvdata-regs_phys-instead-of-phys.patch @@ -0,0 +1,42 @@ +From 384f3bb3d5a332ad2f21bea84f1c2e5afc225b09 Mon Sep 17 00:00:00 2001 +From: Michal Simek <michal.simek@xilinx.com> +Date: Mon, 3 Jun 2013 12:13:19 +0200 +Subject: video: xilinxfb: Use drvdata->regs_phys instead of physaddr + +physaddr will be remove in the next patch. + +Signed-off-by: Michal Simek <michal.simek@xilinx.com> +Acked-by: Arnd Bergmann <arnd@arndb.de> +Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com> +(cherry picked from commit c88fafef0135e1e1c3e23c3e32ccbeeabc587f81) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + drivers/video/xilinxfb.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/video/xilinxfb.c b/drivers/video/xilinxfb.c +index d94c99280144..1b55f18e0b42 100644 +--- a/drivers/video/xilinxfb.c ++++ b/drivers/video/xilinxfb.c +@@ -325,7 +325,7 @@ static int xilinxfb_assign(struct device *dev, + + if (drvdata->flags & BUS_ACCESS_FLAG) { + /* Put a banner in the log (for DEBUG) */ +- dev_dbg(dev, "regs: phys=%lx, virt=%p\n", physaddr, ++ dev_dbg(dev, "regs: phys=%x, virt=%p\n", drvdata->regs_phys, + drvdata->regs); + } + /* Put a banner in the log (for DEBUG) */ +@@ -353,7 +353,7 @@ err_fbmem: + + err_map: + if (drvdata->flags & BUS_ACCESS_FLAG) +- release_mem_region(physaddr, 8); ++ release_mem_region(drvdata->regs_phys, 8); + + err_region: + kfree(drvdata); +-- +1.8.5.rc3 + diff --git a/patches.zynq/0096-video-xilinxfb-Group-bus-initialization.patch b/patches.zynq/0096-video-xilinxfb-Group-bus-initialization.patch new file mode 100644 index 00000000000000..a59e414cefcb25 --- /dev/null +++ b/patches.zynq/0096-video-xilinxfb-Group-bus-initialization.patch @@ -0,0 +1,141 @@ +From 5dcdbd8fc9a080df4abc050cffbe75974cc481b9 Mon Sep 17 00:00:00 2001 +From: Michal Simek <michal.simek@xilinx.com> +Date: Mon, 3 Jun 2013 12:13:20 +0200 +Subject: video: xilinxfb: Group bus initialization + +Move of_address_to_resource() to xilinxfb_assign() +which simplify driver probing. + +Signed-off-by: Michal Simek <michal.simek@xilinx.com> +Acked-by: Arnd Bergmann <arnd@arndb.de> +Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com> +(cherry picked from commit a8f045aa07b3d40f46e35536eeb54e3c5423c5c2) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + drivers/video/xilinxfb.c | 56 +++++++++++++----------------------------------- + 1 file changed, 15 insertions(+), 41 deletions(-) + +diff --git a/drivers/video/xilinxfb.c b/drivers/video/xilinxfb.c +index 1b55f18e0b42..bd3b85d890d4 100644 +--- a/drivers/video/xilinxfb.c ++++ b/drivers/video/xilinxfb.c +@@ -227,33 +227,23 @@ static struct fb_ops xilinxfb_ops = + * Bus independent setup/teardown + */ + +-static int xilinxfb_assign(struct device *dev, ++static int xilinxfb_assign(struct platform_device *pdev, + struct xilinxfb_drvdata *drvdata, +- unsigned long physaddr, + struct xilinxfb_platform_data *pdata) + { + int rc; ++ struct device *dev = &pdev->dev; + int fbsize = pdata->xvirt * pdata->yvirt * BYTES_PER_PIXEL; + + if (drvdata->flags & BUS_ACCESS_FLAG) { +- /* +- * Map the control registers in if the controller +- * is on direct BUS interface. +- */ +- if (!request_mem_region(physaddr, 8, DRIVER_NAME)) { +- dev_err(dev, "Couldn't lock memory region at 0x%08lX\n", +- physaddr); +- rc = -ENODEV; +- goto err_region; +- } ++ struct resource *res; + +- drvdata->regs_phys = physaddr; +- drvdata->regs = ioremap(physaddr, 8); ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ drvdata->regs_phys = res->start; ++ drvdata->regs = devm_request_and_ioremap(&pdev->dev, res); + if (!drvdata->regs) { +- dev_err(dev, "Couldn't lock memory region at 0x%08lX\n", +- physaddr); +- rc = -ENODEV; +- goto err_map; ++ rc = -EADDRNOTAVAIL; ++ goto err_region; + } + } + +@@ -349,11 +339,7 @@ err_cmap: + + err_fbmem: + if (drvdata->flags & BUS_ACCESS_FLAG) +- iounmap(drvdata->regs); +- +-err_map: +- if (drvdata->flags & BUS_ACCESS_FLAG) +- release_mem_region(drvdata->regs_phys, 8); ++ devm_iounmap(dev, drvdata->regs); + + err_region: + kfree(drvdata); +@@ -384,10 +370,8 @@ static int xilinxfb_release(struct device *dev) + xilinx_fb_out32(drvdata, REG_CTRL, 0); + + /* Release the resources, as allocated based on interface */ +- if (drvdata->flags & BUS_ACCESS_FLAG) { +- iounmap(drvdata->regs); +- release_mem_region(drvdata->regs_phys, 8); +- } ++ if (drvdata->flags & BUS_ACCESS_FLAG) ++ devm_iounmap(dev, drvdata->regs); + #ifdef CONFIG_PPC_DCR + else + dcr_unmap(drvdata->dcr_host, drvdata->dcr_len); +@@ -408,8 +392,7 @@ static int xilinxfb_of_probe(struct platform_device *op) + const u32 *prop; + u32 tft_access = 0; + struct xilinxfb_platform_data pdata; +- struct resource res; +- int size, rc; ++ int size; + struct xilinxfb_drvdata *drvdata; + + /* Copy with the default pdata (not a ptr reference!) */ +@@ -435,22 +418,17 @@ static int xilinxfb_of_probe(struct platform_device *op) + */ + if (tft_access) { + drvdata->flags |= BUS_ACCESS_FLAG; +- rc = of_address_to_resource(op->dev.of_node, 0, &res); +- if (rc) { +- dev_err(&op->dev, "invalid address\n"); +- goto err; +- } + } + #ifdef CONFIG_PPC_DCR + else { + int start; +- res.start = 0; + start = dcr_resource_start(op->dev.of_node, 0); + drvdata->dcr_len = dcr_resource_len(op->dev.of_node, 0); + drvdata->dcr_host = dcr_map(op->dev.of_node, start, drvdata->dcr_len); + if (!DCR_MAP_OK(drvdata->dcr_host)) { + dev_err(&op->dev, "invalid DCR address\n"); +- goto err; ++ kfree(drvdata); ++ return -ENODEV; + } + } + #endif +@@ -477,11 +455,7 @@ static int xilinxfb_of_probe(struct platform_device *op) + pdata.rotate_screen = 1; + + dev_set_drvdata(&op->dev, drvdata); +- return xilinxfb_assign(&op->dev, drvdata, res.start, &pdata); +- +- err: +- kfree(drvdata); +- return -ENODEV; ++ return xilinxfb_assign(op, drvdata, &pdata); + } + + static int xilinxfb_of_remove(struct platform_device *op) +-- +1.8.5.rc3 + diff --git a/patches.zynq/0097-video-xilinxfb-Add-support-for-little-endian-accesse.patch b/patches.zynq/0097-video-xilinxfb-Add-support-for-little-endian-accesse.patch new file mode 100644 index 00000000000000..da4d2ef619892b --- /dev/null +++ b/patches.zynq/0097-video-xilinxfb-Add-support-for-little-endian-accesse.patch @@ -0,0 +1,83 @@ +From 34682d82bb5fdacc605bebe92375d30d6fe5d96b Mon Sep 17 00:00:00 2001 +From: Michal Simek <michal.simek@xilinx.com> +Date: Mon, 3 Jun 2013 12:13:21 +0200 +Subject: video: xilinxfb: Add support for little endian accesses + +Dynamically detect endianess on IP and use +ioread/iowrite functions instead of powerpc and microblaze +specific out_be32. + +Signed-off-by: Michal Simek <michal.simek@xilinx.com> +Acked-by: Arnd Bergmann <arnd@arndb.de> +Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com> +(cherry picked from commit 2121c339eb6fd234df16172d6a748d7007eceba8) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + drivers/video/xilinxfb.c | 30 ++++++++++++++++++++++++++++-- + 1 file changed, 28 insertions(+), 2 deletions(-) + +diff --git a/drivers/video/xilinxfb.c b/drivers/video/xilinxfb.c +index bd3b85d890d4..f3d4a69e1e4e 100644 +--- a/drivers/video/xilinxfb.c ++++ b/drivers/video/xilinxfb.c +@@ -117,6 +117,7 @@ static struct fb_var_screeninfo xilinx_fb_var = { + + + #define BUS_ACCESS_FLAG 0x1 /* 1 = BUS, 0 = DCR */ ++#define LITTLE_ENDIAN_ACCESS 0x2 /* LITTLE ENDIAN IO functions */ + + struct xilinxfb_drvdata { + +@@ -153,14 +154,33 @@ struct xilinxfb_drvdata { + static void xilinx_fb_out32(struct xilinxfb_drvdata *drvdata, u32 offset, + u32 val) + { +- if (drvdata->flags & BUS_ACCESS_FLAG) +- out_be32(drvdata->regs + (offset << 2), val); ++ if (drvdata->flags & BUS_ACCESS_FLAG) { ++ if (drvdata->flags & LITTLE_ENDIAN_ACCESS) ++ iowrite32(val, drvdata->regs + (offset << 2)); ++ else ++ iowrite32be(val, drvdata->regs + (offset << 2)); ++ } + #ifdef CONFIG_PPC_DCR + else + dcr_write(drvdata->dcr_host, offset, val); + #endif + } + ++static u32 xilinx_fb_in32(struct xilinxfb_drvdata *drvdata, u32 offset) ++{ ++ if (drvdata->flags & BUS_ACCESS_FLAG) { ++ if (drvdata->flags & LITTLE_ENDIAN_ACCESS) ++ return ioread32(drvdata->regs + (offset << 2)); ++ else ++ return ioread32be(drvdata->regs + (offset << 2)); ++ } ++#ifdef CONFIG_PPC_DCR ++ else ++ return dcr_read(drvdata->dcr_host, offset); ++#endif ++ return 0; ++} ++ + static int + xilinx_fb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue, + unsigned transp, struct fb_info *fbi) +@@ -271,6 +291,12 @@ static int xilinxfb_assign(struct platform_device *pdev, + + /* Tell the hardware where the frame buffer is */ + xilinx_fb_out32(drvdata, REG_FB_ADDR, drvdata->fb_phys); ++ rc = xilinx_fb_in32(drvdata, REG_FB_ADDR); ++ /* Endianess detection */ ++ if (rc != drvdata->fb_phys) { ++ drvdata->flags |= LITTLE_ENDIAN_ACCESS; ++ xilinx_fb_out32(drvdata, REG_FB_ADDR, drvdata->fb_phys); ++ } + + /* Turn on the display */ + drvdata->reg_ctrl_default = REG_CTRL_ENABLE; +-- +1.8.5.rc3 + diff --git a/patches.zynq/0098-video-xilinxfb-Fix-compilation-warning.patch b/patches.zynq/0098-video-xilinxfb-Fix-compilation-warning.patch new file mode 100644 index 00000000000000..25c9af4f407abd --- /dev/null +++ b/patches.zynq/0098-video-xilinxfb-Fix-compilation-warning.patch @@ -0,0 +1,40 @@ +From f0205aa6dbc7b4a17a5aa0d15eb769a683477288 Mon Sep 17 00:00:00 2001 +From: Michal Simek <michal.simek@xilinx.com> +Date: Thu, 25 Jul 2013 15:45:26 +0200 +Subject: video: xilinxfb: Fix compilation warning + +regs_phys is phys_addr_t (u32 or u64). +Lets use %pa printk format specifier. + +Fixes compilation warning introduced by: +video: xilinxfb: Use drvdata->regs_phys instead of physaddr +(sha1: c88fafef0135e1e1c3e23c3e32ccbeeabc587f81) + +Signed-off-by: Michal Simek <michal.simek@xilinx.com> +Reviewed-by: Jingoo Han <jg1.han@samsung.com> +Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com> +(cherry picked from commit bf265c848f162c3189f6e3f0ba619de1a82bcbdc) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + drivers/video/xilinxfb.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/video/xilinxfb.c b/drivers/video/xilinxfb.c +index f3d4a69e1e4e..6629b29a8202 100644 +--- a/drivers/video/xilinxfb.c ++++ b/drivers/video/xilinxfb.c +@@ -341,8 +341,8 @@ static int xilinxfb_assign(struct platform_device *pdev, + + if (drvdata->flags & BUS_ACCESS_FLAG) { + /* Put a banner in the log (for DEBUG) */ +- dev_dbg(dev, "regs: phys=%x, virt=%p\n", drvdata->regs_phys, +- drvdata->regs); ++ dev_dbg(dev, "regs: phys=%pa, virt=%p\n", ++ &drvdata->regs_phys, drvdata->regs); + } + /* Put a banner in the log (for DEBUG) */ + dev_dbg(dev, "fb: phys=%llx, virt=%p, size=%x\n", +-- +1.8.5.rc3 + diff --git a/patches.zynq/0099-video-xilinxfb-replace-devm_request_and_ioremap-by-d.patch b/patches.zynq/0099-video-xilinxfb-replace-devm_request_and_ioremap-by-d.patch new file mode 100644 index 00000000000000..6acd06386265f6 --- /dev/null +++ b/patches.zynq/0099-video-xilinxfb-replace-devm_request_and_ioremap-by-d.patch @@ -0,0 +1,47 @@ +From 14f73b96a69880d35af29002ff017f4787f73c84 Mon Sep 17 00:00:00 2001 +From: Julia Lawall <Julia.Lawall@lip6.fr> +Date: Mon, 19 Aug 2013 13:20:40 +0200 +Subject: video: xilinxfb: replace devm_request_and_ioremap by + devm_ioremap_resource + +Use devm_ioremap_resource instead of devm_request_and_ioremap. + +This was done using the semantic patch +scripts/coccinelle/api/devm_ioremap_resource.cocci + +The initialization of drvdata->regs_phys was manually moved lower, to take +advantage of the NULL test on res performed by devm_ioremap_resource. + +Signed-off-by: Julia Lawall <Julia.Lawall@lip6.fr> +Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com> +(cherry picked from commit b1a9329cd5c4a26cdc2b12015ad055174a09e4ad) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + drivers/video/xilinxfb.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/video/xilinxfb.c b/drivers/video/xilinxfb.c +index 6629b29a8202..84c664ea8eb9 100644 +--- a/drivers/video/xilinxfb.c ++++ b/drivers/video/xilinxfb.c +@@ -259,12 +259,12 @@ static int xilinxfb_assign(struct platform_device *pdev, + struct resource *res; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); +- drvdata->regs_phys = res->start; +- drvdata->regs = devm_request_and_ioremap(&pdev->dev, res); +- if (!drvdata->regs) { +- rc = -EADDRNOTAVAIL; ++ drvdata->regs = devm_ioremap_resource(&pdev->dev, res); ++ if (IS_ERR(drvdata->regs)) { ++ rc = PTR_ERR(drvdata->regs); + goto err_region; + } ++ drvdata->regs_phys = res->start; + } + + /* Allocate the framebuffer memory */ +-- +1.8.5.rc3 + diff --git a/patches.zynq/0100-video-xilinxfb-Remove-redundant-dev_set_drvdata.patch b/patches.zynq/0100-video-xilinxfb-Remove-redundant-dev_set_drvdata.patch new file mode 100644 index 00000000000000..06a45124cb7483 --- /dev/null +++ b/patches.zynq/0100-video-xilinxfb-Remove-redundant-dev_set_drvdata.patch @@ -0,0 +1,39 @@ +From 85ebfe9c18110d7953d460fc7e0ba644a88c5d61 Mon Sep 17 00:00:00 2001 +From: Sachin Kamat <sachin.kamat@linaro.org> +Date: Fri, 20 Sep 2013 12:02:24 +0530 +Subject: video: xilinxfb: Remove redundant dev_set_drvdata + +Driver core sets driver data to NULL upon failure or remove. + +Signed-off-by: Sachin Kamat <sachin.kamat@linaro.org> +Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com> +(cherry picked from commit 090fd59308c9d50b8eabf71cd28b5513250a7b79) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + drivers/video/xilinxfb.c | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/drivers/video/xilinxfb.c b/drivers/video/xilinxfb.c +index 84c664ea8eb9..0e1dd3380a1e 100644 +--- a/drivers/video/xilinxfb.c ++++ b/drivers/video/xilinxfb.c +@@ -369,7 +369,6 @@ err_fbmem: + + err_region: + kfree(drvdata); +- dev_set_drvdata(dev, NULL); + + return rc; + } +@@ -404,7 +403,6 @@ static int xilinxfb_release(struct device *dev) + #endif + + kfree(drvdata); +- dev_set_drvdata(dev, NULL); + + return 0; + } +-- +1.8.5.rc3 + diff --git a/patches.zynq/0101-video-xilinxfb-Use-standard-variable-name-convention.patch b/patches.zynq/0101-video-xilinxfb-Use-standard-variable-name-convention.patch new file mode 100644 index 00000000000000..8f78064a0dfc9d --- /dev/null +++ b/patches.zynq/0101-video-xilinxfb-Use-standard-variable-name-convention.patch @@ -0,0 +1,87 @@ +From edb72c418671f12b26b12967477c0c9b6a301156 Mon Sep 17 00:00:00 2001 +From: Michal Simek <michal.simek@xilinx.com> +Date: Thu, 10 Oct 2013 08:30:20 +0200 +Subject: video: xilinxfb: Use standard variable name convention + +s/op/pdev/ in xilinxfb_of_probe(). +No functional chagnes. + +Signed-off-by: Michal Simek <michal.simek@xilinx.com> +Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com> +(cherry picked from commit 353846fb8bb7d84986116a5be110eefed451af3c) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + drivers/video/xilinxfb.c | 18 +++++++++--------- + 1 file changed, 9 insertions(+), 9 deletions(-) + +diff --git a/drivers/video/xilinxfb.c b/drivers/video/xilinxfb.c +index 0e1dd3380a1e..d12345f7fca4 100644 +--- a/drivers/video/xilinxfb.c ++++ b/drivers/video/xilinxfb.c +@@ -411,7 +411,7 @@ static int xilinxfb_release(struct device *dev) + * OF bus binding + */ + +-static int xilinxfb_of_probe(struct platform_device *op) ++static int xilinxfb_of_probe(struct platform_device *pdev) + { + const u32 *prop; + u32 tft_access = 0; +@@ -425,7 +425,7 @@ static int xilinxfb_of_probe(struct platform_device *op) + /* Allocate the driver data region */ + drvdata = kzalloc(sizeof(*drvdata), GFP_KERNEL); + if (!drvdata) { +- dev_err(&op->dev, "Couldn't allocate device private record\n"); ++ dev_err(&pdev->dev, "Couldn't allocate device private record\n"); + return -ENOMEM; + } + +@@ -433,7 +433,7 @@ static int xilinxfb_of_probe(struct platform_device *op) + * To check whether the core is connected directly to DCR or BUS + * interface and initialize the tft_access accordingly. + */ +- of_property_read_u32(op->dev.of_node, "xlnx,dcr-splb-slave-if", ++ of_property_read_u32(pdev->dev.of_node, "xlnx,dcr-splb-slave-if", + &tft_access); + + /* +@@ -457,29 +457,29 @@ static int xilinxfb_of_probe(struct platform_device *op) + } + #endif + +- prop = of_get_property(op->dev.of_node, "phys-size", &size); ++ prop = of_get_property(pdev->dev.of_node, "phys-size", &size); + if ((prop) && (size >= sizeof(u32)*2)) { + pdata.screen_width_mm = prop[0]; + pdata.screen_height_mm = prop[1]; + } + +- prop = of_get_property(op->dev.of_node, "resolution", &size); ++ prop = of_get_property(pdev->dev.of_node, "resolution", &size); + if ((prop) && (size >= sizeof(u32)*2)) { + pdata.xres = prop[0]; + pdata.yres = prop[1]; + } + +- prop = of_get_property(op->dev.of_node, "virtual-resolution", &size); ++ prop = of_get_property(pdev->dev.of_node, "virtual-resolution", &size); + if ((prop) && (size >= sizeof(u32)*2)) { + pdata.xvirt = prop[0]; + pdata.yvirt = prop[1]; + } + +- if (of_find_property(op->dev.of_node, "rotate-display", NULL)) ++ if (of_find_property(pdev->dev.of_node, "rotate-display", NULL)) + pdata.rotate_screen = 1; + +- dev_set_drvdata(&op->dev, drvdata); +- return xilinxfb_assign(op, drvdata, &pdata); ++ dev_set_drvdata(&pdev->dev, drvdata); ++ return xilinxfb_assign(pdev, drvdata, &pdata); + } + + static int xilinxfb_of_remove(struct platform_device *op) +-- +1.8.5.rc3 + diff --git a/patches.zynq/0102-video-xilinxfb-Use-devm_kzalloc-instead-of-kzalloc.patch b/patches.zynq/0102-video-xilinxfb-Use-devm_kzalloc-instead-of-kzalloc.patch new file mode 100644 index 00000000000000..82601b15a8de0a --- /dev/null +++ b/patches.zynq/0102-video-xilinxfb-Use-devm_kzalloc-instead-of-kzalloc.patch @@ -0,0 +1,64 @@ +From b845f6e9f70e2a0e1008d9238e19e4305f780d04 Mon Sep 17 00:00:00 2001 +From: Michal Simek <michal.simek@xilinx.com> +Date: Thu, 10 Oct 2013 08:30:21 +0200 +Subject: video: xilinxfb: Use devm_kzalloc instead of kzalloc + +Simplify driver probe and release function. + +Signed-off-by: Michal Simek <michal.simek@xilinx.com> +Reviewed-by: Jingoo Han <jg1.han@samsung.com> +Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com> +(cherry picked from commit 5c128df7471a6917f84cde3cea786541aaa404a2) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + drivers/video/xilinxfb.c | 11 ++--------- + 1 file changed, 2 insertions(+), 9 deletions(-) + +diff --git a/drivers/video/xilinxfb.c b/drivers/video/xilinxfb.c +index d12345f7fca4..c420328afb40 100644 +--- a/drivers/video/xilinxfb.c ++++ b/drivers/video/xilinxfb.c +@@ -368,8 +368,6 @@ err_fbmem: + devm_iounmap(dev, drvdata->regs); + + err_region: +- kfree(drvdata); +- + return rc; + } + +@@ -402,8 +400,6 @@ static int xilinxfb_release(struct device *dev) + dcr_unmap(drvdata->dcr_host, drvdata->dcr_len); + #endif + +- kfree(drvdata); +- + return 0; + } + +@@ -423,11 +419,9 @@ static int xilinxfb_of_probe(struct platform_device *pdev) + pdata = xilinx_fb_default_pdata; + + /* Allocate the driver data region */ +- drvdata = kzalloc(sizeof(*drvdata), GFP_KERNEL); +- if (!drvdata) { +- dev_err(&pdev->dev, "Couldn't allocate device private record\n"); ++ drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL); ++ if (!drvdata) + return -ENOMEM; +- } + + /* + * To check whether the core is connected directly to DCR or BUS +@@ -451,7 +445,6 @@ static int xilinxfb_of_probe(struct platform_device *pdev) + drvdata->dcr_host = dcr_map(op->dev.of_node, start, drvdata->dcr_len); + if (!DCR_MAP_OK(drvdata->dcr_host)) { + dev_err(&op->dev, "invalid DCR address\n"); +- kfree(drvdata); + return -ENODEV; + } + } +-- +1.8.5.rc3 + diff --git a/patches.zynq/0103-video-xilinxfb-Simplify-error-path.patch b/patches.zynq/0103-video-xilinxfb-Simplify-error-path.patch new file mode 100644 index 00000000000000..fb78e53ff18a6d --- /dev/null +++ b/patches.zynq/0103-video-xilinxfb-Simplify-error-path.patch @@ -0,0 +1,80 @@ +From c3de3f9aaa8948a1a39093eb17725d01c01daa85 Mon Sep 17 00:00:00 2001 +From: Michal Simek <michal.simek@xilinx.com> +Date: Thu, 10 Oct 2013 08:30:22 +0200 +Subject: video: xilinxfb: Simplify error path + +devm_iounmap is called automatically that's why remove it from the code +dev_set_drvdata(dev, NULL) is called by generic code +after device_release or on probe failure. + +Signed-off-by: Michal Simek <michal.simek@xilinx.com> + +Reviewed-by: Jingoo Han <jg1.han@samsung.com> +Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com> +(cherry picked from commit 718b90ac4c21c81f42b6db062ca0867f3cac7648) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + drivers/video/xilinxfb.c | 24 ++++++------------------ + 1 file changed, 6 insertions(+), 18 deletions(-) + +diff --git a/drivers/video/xilinxfb.c b/drivers/video/xilinxfb.c +index c420328afb40..9eedf9673b7f 100644 +--- a/drivers/video/xilinxfb.c ++++ b/drivers/video/xilinxfb.c +@@ -260,10 +260,9 @@ static int xilinxfb_assign(struct platform_device *pdev, + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + drvdata->regs = devm_ioremap_resource(&pdev->dev, res); +- if (IS_ERR(drvdata->regs)) { +- rc = PTR_ERR(drvdata->regs); +- goto err_region; +- } ++ if (IS_ERR(drvdata->regs)) ++ return PTR_ERR(drvdata->regs); ++ + drvdata->regs_phys = res->start; + } + +@@ -279,11 +278,7 @@ static int xilinxfb_assign(struct platform_device *pdev, + + if (!drvdata->fb_virt) { + dev_err(dev, "Could not allocate frame buffer memory\n"); +- rc = -ENOMEM; +- if (drvdata->flags & BUS_ACCESS_FLAG) +- goto err_fbmem; +- else +- goto err_region; ++ return -ENOMEM; + } + + /* Clear (turn to black) the framebuffer */ +@@ -363,11 +358,6 @@ err_cmap: + /* Turn off the display */ + xilinx_fb_out32(drvdata, REG_CTRL, 0); + +-err_fbmem: +- if (drvdata->flags & BUS_ACCESS_FLAG) +- devm_iounmap(dev, drvdata->regs); +- +-err_region: + return rc; + } + +@@ -392,11 +382,9 @@ static int xilinxfb_release(struct device *dev) + /* Turn off the display */ + xilinx_fb_out32(drvdata, REG_CTRL, 0); + +- /* Release the resources, as allocated based on interface */ +- if (drvdata->flags & BUS_ACCESS_FLAG) +- devm_iounmap(dev, drvdata->regs); + #ifdef CONFIG_PPC_DCR +- else ++ /* Release the resources, as allocated based on interface */ ++ if (!(drvdata->flags & BUS_ACCESS_FLAG)) + dcr_unmap(drvdata->dcr_host, drvdata->dcr_len); + #endif + +-- +1.8.5.rc3 + diff --git a/patches.zynq/0104-video-xilinxfb-Fix-for-Use-standard-variable-name-co.patch b/patches.zynq/0104-video-xilinxfb-Fix-for-Use-standard-variable-name-co.patch new file mode 100644 index 00000000000000..3419e4dce88ce5 --- /dev/null +++ b/patches.zynq/0104-video-xilinxfb-Fix-for-Use-standard-variable-name-co.patch @@ -0,0 +1,38 @@ +From 8b7cfe2778ce23971f159dddb0205a78eb56dd50 Mon Sep 17 00:00:00 2001 +From: Stephen Rothwell <sfr@canb.auug.org.au> +Date: Tue, 29 Oct 2013 01:18:22 +1100 +Subject: video: xilinxfb: Fix for "Use standard variable name convention" + +Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au> +Tested-by: Michal Simek <monstr@monstr.eu> +Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com> +(cherry picked from commit 33826d01d0f7e46eccd670e1ecdae1dff1cebfd2) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + drivers/video/xilinxfb.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/video/xilinxfb.c b/drivers/video/xilinxfb.c +index 9eedf9673b7f..6ff1a91e9dfd 100644 +--- a/drivers/video/xilinxfb.c ++++ b/drivers/video/xilinxfb.c +@@ -428,11 +428,11 @@ static int xilinxfb_of_probe(struct platform_device *pdev) + #ifdef CONFIG_PPC_DCR + else { + int start; +- start = dcr_resource_start(op->dev.of_node, 0); +- drvdata->dcr_len = dcr_resource_len(op->dev.of_node, 0); +- drvdata->dcr_host = dcr_map(op->dev.of_node, start, drvdata->dcr_len); ++ start = dcr_resource_start(pdev->dev.of_node, 0); ++ drvdata->dcr_len = dcr_resource_len(pdev->dev.of_node, 0); ++ drvdata->dcr_host = dcr_map(pdev->dev.of_node, start, drvdata->dcr_len); + if (!DCR_MAP_OK(drvdata->dcr_host)) { +- dev_err(&op->dev, "invalid DCR address\n"); ++ dev_err(&pdev->dev, "invalid DCR address\n"); + return -ENODEV; + } + } +-- +1.8.5.rc3 + diff --git a/patches.zynq/0105-i2c-use-dev_get_platdata.patch b/patches.zynq/0105-i2c-use-dev_get_platdata.patch new file mode 100644 index 00000000000000..8072215cbb6533 --- /dev/null +++ b/patches.zynq/0105-i2c-use-dev_get_platdata.patch @@ -0,0 +1,33 @@ +From 0c162606d98f39f2d8736e91bc79b6fffea7b2c3 Mon Sep 17 00:00:00 2001 +From: Jingoo Han <jg1.han@samsung.com> +Date: Tue, 30 Jul 2013 16:59:33 +0900 +Subject: i2c: use dev_get_platdata() + +Use the wrapper function for retrieving the platform data instead of +accessing dev->platform_data directly. + +Signed-off-by: Jingoo Han <jg1.han@samsung.com> +Signed-off-by: Wolfram Sang <wsa@the-dreams.de> +(cherry picked from commit 6d4028c644edc0a2e4a8c948ebf81e8f2f09726e) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + drivers/i2c/busses/i2c-xiic.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/i2c/busses/i2c-xiic.c b/drivers/i2c/busses/i2c-xiic.c +index 3d0f0520c1b4..433f377b3869 100644 +--- a/drivers/i2c/busses/i2c-xiic.c ++++ b/drivers/i2c/busses/i2c-xiic.c +@@ -703,7 +703,7 @@ static int xiic_i2c_probe(struct platform_device *pdev) + if (irq < 0) + goto resource_missing; + +- pdata = (struct xiic_i2c_platform_data *) pdev->dev.platform_data; ++ pdata = (struct xiic_i2c_platform_data *)dev_get_platdata(&pdev->dev); + + i2c = kzalloc(sizeof(*i2c), GFP_KERNEL); + if (!i2c) +-- +1.8.5.rc3 + diff --git a/patches.zynq/0106-i2c-move-OF-helpers-into-the-core.patch b/patches.zynq/0106-i2c-move-OF-helpers-into-the-core.patch new file mode 100644 index 00000000000000..00f9cae0ea2e89 --- /dev/null +++ b/patches.zynq/0106-i2c-move-OF-helpers-into-the-core.patch @@ -0,0 +1,43 @@ +From 7a39796c4ef5ae419ab7c7c03487298bfef4c48b Mon Sep 17 00:00:00 2001 +From: Wolfram Sang <wsa@the-dreams.de> +Date: Thu, 11 Jul 2013 12:56:15 +0100 +Subject: i2c: move OF helpers into the core + +I2C of helpers used to live in of_i2c.c but experience (from SPI) shows +that it is much cleaner to have this in the core. This also removes a +circular dependency between the helpers and the core, and so we can +finally register child nodes in the core instead of doing this manually +in each driver. So, fix the drivers and documentation, too. + +Signed-off-by: Wolfram Sang <wsa@the-dreams.de> +(cherry picked from commit 687b81d083c082bc1e853032e3a2a54f8c251d27) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + drivers/i2c/busses/i2c-xiic.c | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/drivers/i2c/busses/i2c-xiic.c b/drivers/i2c/busses/i2c-xiic.c +index 433f377b3869..4c8b368d463b 100644 +--- a/drivers/i2c/busses/i2c-xiic.c ++++ b/drivers/i2c/busses/i2c-xiic.c +@@ -40,7 +40,6 @@ + #include <linux/i2c-xiic.h> + #include <linux/io.h> + #include <linux/slab.h> +-#include <linux/of_i2c.h> + + #define DRIVER_NAME "xiic-i2c" + +@@ -752,8 +751,6 @@ static int xiic_i2c_probe(struct platform_device *pdev) + i2c_new_device(&i2c->adap, pdata->devices + i); + } + +- of_i2c_register_devices(&i2c->adap); +- + return 0; + + add_adapter_failed: +-- +1.8.5.rc3 + diff --git a/patches.zynq/0107-i2c-xiic-Remove-casting-the-return-value-which-is-a-.patch b/patches.zynq/0107-i2c-xiic-Remove-casting-the-return-value-which-is-a-.patch new file mode 100644 index 00000000000000..f35a02b98f1fb6 --- /dev/null +++ b/patches.zynq/0107-i2c-xiic-Remove-casting-the-return-value-which-is-a-.patch @@ -0,0 +1,34 @@ +From 31c6919def0a6fa9d1a688cc88135d24bdd67ff0 Mon Sep 17 00:00:00 2001 +From: Jingoo Han <jg1.han@samsung.com> +Date: Mon, 9 Sep 2013 14:31:29 +0900 +Subject: i2c: xiic: Remove casting the return value which is a void pointer + +Casting the return value which is a void pointer is redundant. +The conversion from void pointer to any other pointer type is +guaranteed by the C programming language. + +Signed-off-by: Jingoo Han <jg1.han@samsung.com> +Signed-off-by: Wolfram Sang <wsa@the-dreams.de> +(cherry picked from commit ab0dc7a81df2595a18b328d2c7031b00bd7efb1e) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + drivers/i2c/busses/i2c-xiic.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/i2c/busses/i2c-xiic.c b/drivers/i2c/busses/i2c-xiic.c +index 4c8b368d463b..6e7b09c1804e 100644 +--- a/drivers/i2c/busses/i2c-xiic.c ++++ b/drivers/i2c/busses/i2c-xiic.c +@@ -702,7 +702,7 @@ static int xiic_i2c_probe(struct platform_device *pdev) + if (irq < 0) + goto resource_missing; + +- pdata = (struct xiic_i2c_platform_data *)dev_get_platdata(&pdev->dev); ++ pdata = dev_get_platdata(&pdev->dev); + + i2c = kzalloc(sizeof(*i2c), GFP_KERNEL); + if (!i2c) +-- +1.8.5.rc3 + diff --git a/patches.zynq/0108-i2c-Include-linux-of.h-header.patch b/patches.zynq/0108-i2c-Include-linux-of.h-header.patch new file mode 100644 index 00000000000000..e58b20192df187 --- /dev/null +++ b/patches.zynq/0108-i2c-Include-linux-of.h-header.patch @@ -0,0 +1,27 @@ +From b23190e75268c9d372d2ba5f0c258b32a4fffe82 Mon Sep 17 00:00:00 2001 +From: Sachin Kamat <sachin.kamat@linaro.org> +Date: Wed, 16 Oct 2013 15:26:33 +0530 +Subject: i2c: Include linux/of.h header + +'of_match_ptr' is defined in linux/of.h. Include it explicitly to +avoid build breakage in the future. + +Signed-off-by: Sachin Kamat <sachin.kamat@linaro.org> +Signed-off-by: Wolfram Sang <wsa@the-dreams.de> +(cherry picked from commit 4edd65e63fe4a998164a8d7d8c8c86f4300825d7) +Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> +Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> +--- + drivers/i2c/busses/i2c-xiic.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/i2c/busses/i2c-xiic.c ++++ b/drivers/i2c/busses/i2c-xiic.c +@@ -40,6 +40,7 @@ + #include <linux/i2c-xiic.h> + #include <linux/io.h> + #include <linux/slab.h> ++#include <linux/of.h> + + #define DRIVER_NAME "xiic-i2c" + @@ -882,6 +882,119 @@ patches.renesas/0237-ASoC-rcar-select-REGMAP.patch ############################################################################# +# Zynq SOC patches +# +patches.zynq/0001-ARM-zynq-Remove-init_irq-declaration-in-machine-desc.patch +patches.zynq/0002-ARM-zynq-Not-to-rewrite-jump-code-when-starting-addr.patch +patches.zynq/0003-arm-zynq-Remove-board-specific-compatibility-string.patch +patches.zynq/0004-ARM-zynq-use-DT_MACHINE_START.patch +patches.zynq/0005-arm-zynq-slcr-Remove-redundant-header-includes.patch +patches.zynq/0006-arm-zynq-slcr-Clean-up-defines.patch +patches.zynq/0007-arm-zynq-slcr-Use-read-modify-write-for-register-wri.patch +patches.zynq/0008-arm-zynq-hotplug-Remove-unreachable-code.patch +patches.zynq/0009-arm-zynq-Enable-arm_global_timer.patch +patches.zynq/0010-ARM-zynq-Add-cpuidle-support.patch +patches.zynq/0011-ARM-zynq-cpuidle-Remove-useless-compatibility-string.patch +patches.zynq/0012-ARM-zynq-cpuidle-convert-to-platform-driver.patch +patches.zynq/0013-tty-xuartps-Remove-suspend-resume-functions.patch +patches.zynq/0014-arm-zynq-Migrate-platform-to-clock-controller.patch +patches.zynq/0015-serial-use-platform_-get-set-_drvdata.patch +patches.zynq/0016-tty-xuartps-Use-devm_clk_get.patch +patches.zynq/0017-tty-xuartps-Use-devm_kzalloc.patch +patches.zynq/0018-tty-xuartps-Implement-BREAK-detection-add-SYSRQ-supp.patch +patches.zynq/0019-tty-xuartps-Add-polled-mode-support-for-xuartps.patch +patches.zynq/0020-tty-xuartps-support-64-byte-FIFO-size.patch +patches.zynq/0021-tty-xuartps-Force-enable-the-UART-in-xuartps_console.patch +patches.zynq/0022-tty-xuartps-Updating-set_baud_rate.patch +patches.zynq/0023-tty-xuartps-Dynamically-adjust-to-input-frequency-ch.patch +patches.zynq/0024-tty-xuartps-Implement-suspend-resume-callbacks.patch +patches.zynq/0025-tty-xuartps-Update-copyright-information.patch +patches.zynq/0026-tty-xuartps-Fix-may-be-used-uninitialized-build-warn.patch +patches.zynq/0027-tty-xuartps-Fix-build-error-due-to-missing-forward-d.patch +patches.zynq/0028-tty-xuartps-Fix-build-error-when-COMMON_CLK-is-not-s.patch +patches.zynq/0029-GPIO-xilinx-Simplify-driver-probe-function.patch +patches.zynq/0030-GPIO-xilinx-Add-support-for-dual-channel.patch +patches.zynq/0031-GPIO-xilinx-Use-__raw_readl-__raw_writel-IO-function.patch +patches.zynq/0032-GPIO-xilinx-Use-BIT-macro.patch +patches.zynq/0033-arm-dt-zynq-Use-status-property-for-UART-nodes.patch +patches.zynq/0034-arm-zynq-dt-Set-correct-L2-ram-latencies.patch +patches.zynq/0035-clk-zynq-Add-clock-controller-driver.patch +patches.zynq/0036-clk-zynq-Remove-deprecated-clock-code.patch +patches.zynq/0037-clk-zynq-clkc-Add-dedicated-spinlock-for-the-SWDT.patch +patches.zynq/0038-clk-zynq-clkc-Add-CLK_SET_RATE_PARENT-flag-to-ethern.patch +patches.zynq/0039-clk-add-CLK_SET_RATE_NO_REPARENT-flag.patch +patches.zynq/0040-Merge-tag-clk-for-linus-3.12-of-git-git.linaro.org-p.patch +patches.zynq/0041-clk-zynq-Fix-possible-memory-leak.patch +patches.zynq/0042-clk-zynq-Factor-out-PLL-driver.patch +patches.zynq/0043-clk-zynq-pll-Fix-documentation-for-PLL-register-func.patch +patches.zynq/0044-clk-zynq-pll-Use-defines-for-fbdiv-min-max-values.patch +patches.zynq/0045-spi-spi-xilinx-Add-run-run-time-endian-detection.patch +patches.zynq/0046-spi-spi-xilinx-Remove-redundant-platform_set_drvdata.patch +patches.zynq/0047-spi-spi-xilinx-cleanup-a-check-in-xilinx_spi_txrx_bu.patch +patches.zynq/0048-spi-xilinx-Convert-to-devm_ioremap_resource.patch +patches.zynq/0049-spi-xilinx-Remove-remains-of-of_platform-device-regi.patch +patches.zynq/0050-spi-xilinx-Refer-to-platform-device-as-pdev-in-probe.patch +patches.zynq/0051-spi-xilinx-Remove-CONFIG_OF-from-the-driver.patch +patches.zynq/0052-spi-xilinx-Clean-ioremap-calling.patch +patches.zynq/0053-spi-xilinx-Use-of_property_read_u32-for-reading-valu.patch +patches.zynq/0054-spi-xilinx-Simplify-irq-allocation.patch +patches.zynq/0055-spi-xilinx-signedness-issue-checking-platform_get_ir.patch +patches.zynq/0056-spi-bitbang-Drop-empty-setup-functions.patch +patches.zynq/0057-spi-use-dev_get_platdata.patch +patches.zynq/0058-spi-bitbang-Let-spi_bitbang_start-take-a-reference-t.patch +patches.zynq/0059-Input-xilinx_ps2-remove-redundant-platform_set_drvda.patch +patches.zynq/0060-drivers-clean-up-prom.h-implicit-includes.patch +patches.zynq/0061-of-irq-Use-irq_of_parse_and_map.patch +patches.zynq/0062-char-xilinx_hwicap-Remove-casting-the-return-value-w.patch +patches.zynq/0063-char-hwicap-Remove-unnecessary-dev_set_drvdata.patch +patches.zynq/0064-char-xilinx_hwicap-Checkpatch.pl-cleanup.patch +patches.zynq/0065-char-xilinx_hwicap-Fix-typo-in-comment-and-extend-it.patch +patches.zynq/0066-watchdog-xilinx-Fix-driver-header.patch +patches.zynq/0067-watchdog-xilinx-Setup-the-origin-compatible-string.patch +patches.zynq/0068-watchdog-Get-rid-of-MODULE_ALIAS_MISCDEV-statements.patch +patches.zynq/0069-DT-Add-documentation-for-gpio-xilinx.patch +patches.zynq/0070-arm-dt-zynq-Add-support-for-the-zc706-platform.patch +patches.zynq/0071-USB-host-use-platform_-get-set-_drvdata.patch +patches.zynq/0072-USB-host-Use-usb_hcd_platform_shutdown-wherever-poss.patch +patches.zynq/0073-clocksource-cadence_ttc-Remove-unused-header.patch +patches.zynq/0074-net-ethernet-use-platform_-get-set-_drvdata.patch +patches.zynq/0075-drivers-net-Convert-dma_alloc_coherent-.__GFP_ZERO-t.patch +patches.zynq/0076-net-emaclite-Report-failures-in-mdio-setup.patch +patches.zynq/0077-net-emaclite-Support-multiple-phys-connected-to-one-.patch +patches.zynq/0078-net-emaclite-Let-s-make-xemaclite_adjust_link-static.patch +patches.zynq/0079-net-emaclite-Do-not-use-microblaze-and-ppc-IO-functi.patch +patches.zynq/0080-net-emaclite-Update-driver-header.patch +patches.zynq/0081-net-emaclite-Fix-typo-in-error-message.patch +patches.zynq/0082-net-emaclite-Use-platform-resource-table.patch +patches.zynq/0083-net-emaclite-Convert-to-use-devm_ioremap_resource.patch +patches.zynq/0084-net-xilinx_emaclite-use-platform_-get-set-_drvdata.patch +patches.zynq/0085-net-xilinx_emaclite-remove-unnecessary-dev_set_drvda.patch +patches.zynq/0086-net-emaclite-Not-necessary-to-call-devm_iounmap.patch +patches.zynq/0087-net-emaclite-Code-cleanup.patch +patches.zynq/0088-net-drivers-net-Miscellaneous-conversions-to-ETH_ALE.patch +patches.zynq/0089-net-xilinx-fix-memleak.patch +patches.zynq/0090-net-emaclite-Enable-emaclite-for-Xilinx-Arm-Zynq-pla.patch +patches.zynq/0091-microblaze-clean-up-prom.h-implicit-includes.patch +patches.zynq/0092-video-xilinxfb-Fix-OF-probing-on-little-endian-syste.patch +patches.zynq/0093-video-xilinxfb-Do-not-name-out_be32-in-function-name.patch +patches.zynq/0094-video-xilinxfb-Rename-PLB_ACCESS_FLAG-to-BUS_ACCESS_.patch +patches.zynq/0095-video-xilinxfb-Use-drvdata-regs_phys-instead-of-phys.patch +patches.zynq/0096-video-xilinxfb-Group-bus-initialization.patch +patches.zynq/0097-video-xilinxfb-Add-support-for-little-endian-accesse.patch +patches.zynq/0098-video-xilinxfb-Fix-compilation-warning.patch +patches.zynq/0099-video-xilinxfb-replace-devm_request_and_ioremap-by-d.patch +patches.zynq/0100-video-xilinxfb-Remove-redundant-dev_set_drvdata.patch +patches.zynq/0101-video-xilinxfb-Use-standard-variable-name-convention.patch +patches.zynq/0102-video-xilinxfb-Use-devm_kzalloc-instead-of-kzalloc.patch +patches.zynq/0103-video-xilinxfb-Simplify-error-path.patch +patches.zynq/0104-video-xilinxfb-Fix-for-Use-standard-variable-name-co.patch +patches.zynq/0105-i2c-use-dev_get_platdata.patch +patches.zynq/0106-i2c-move-OF-helpers-into-the-core.patch +patches.zynq/0107-i2c-xiic-Remove-casting-the-return-value-which-is-a-.patch +patches.zynq/0108-i2c-Include-linux-of.h-header.patch + + +############################################################################# # fixes that go after all of the above # |