Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] ARM: tegra: dalmore: fix irq trigger type
From: Stefan Agner @ 2014-02-11 21:21 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20140211204737.GA1895@mithrandir>

Am 2014-02-11 21:47, schrieb Thierry Reding:
> On Tue, Feb 11, 2014 at 09:11:32PM +0100, Stefan Agner wrote:
>> Trigger type needs to be IRQ_TYPE_LEVEL_HIGH since the interrupt
>> signal gets inverted by the PMC (configured by the invert-interrupt
>> property).
> 
> Isn't the reason the other way around? The PMIC generates a low-level
> interrupt, but the GIC can only be configured to accept high-level (or
> rising edge) and therefore the nvidia,invert-interrupt property needs to
> be set in the PMC node?
Hm yes agreed. I should also write the whole story here, maybe this:

The GIC only support high-active interrupts. When using a PMIC with
low-active interrupt, the PMC has to be configured by using the
nvidia,invert-interrupt property in its node.

This fix sets the GIC back to high-active and reverts commit
eca8f98e404934027f84f72882c5e92ffbd9e5f5.

> One nitpick below.
> 
>> diff --git a/arch/arm/boot/dts/tegra114-dalmore.dts b/arch/arm/boot/dts/tegra114-dalmore.dts
> [...]
>> @@ -888,8 +888,9 @@
>>  		palmas: tps65913 at 58 {
>>  			compatible = "ti,palmas";
>>  			reg = <0x58>;
>> -			interrupts = <0 86 IRQ_TYPE_LEVEL_LOW>;
>>
>> +			/* active-low configured by PMC invert-interrupt */
>> +			interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
> 
> I'd prefer to keep the properties grouped as before. interrupts is a
> "client" property, whereas #interrupt-cells and interrupt-controller
> are "provider" properties.
> 
> And I think the comment would be more appropriate in the pmc node, for
> the same reason that I think the commit description isn't entirely
> accurate.
Well, its kind a question where you are coming from. I read the data
sheet/schemata, and saw that its low-active. Then I went to the PMIC
node and checked how that interrupt is configured, and what you see is
HIGH_ACTIVE. You then think you've found the bug and fix it by setting
it to IRQ_TYPE_LEVEL_LOW. What you don't know is that PMC is in between
and alters the polarity...

^ permalink raw reply

* [PATCH] ARM: spear: Remove references to PLAT_SPEAR_SINGLE
From: Paul Bolle @ 2014-02-11 21:21 UTC (permalink / raw)
  To: linux-arm-kernel

The Kconfig symbol PLAT_SPEAR_SINGLE briefly appeared during the v3.10
development cycle. It was removed in a merge commit before v3.10. A few
references to it were left in the tree, probably because they didn't
generate merge conflicts. Whatever it was, they're useless now and can
safely be removed.

Reported-by: Martin Walch <walch.martin@web.de>
Signed-off-by: Paul Bolle <pebolle@tiscali.nl>
---
Untested.

 arch/arm/mach-spear/Kconfig | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/arch/arm/mach-spear/Kconfig b/arch/arm/mach-spear/Kconfig
index ac1710e6..1595776 100644
--- a/arch/arm/mach-spear/Kconfig
+++ b/arch/arm/mach-spear/Kconfig
@@ -4,7 +4,6 @@
 
 menuconfig PLAT_SPEAR
 	bool "ST SPEAr Family" if ARCH_MULTI_V7 || ARCH_MULTI_V5
-	default PLAT_SPEAR_SINGLE
 	select ARCH_REQUIRE_GPIOLIB
 	select ARM_AMBA
 	select CLKSRC_MMIO
@@ -15,7 +14,7 @@ if PLAT_SPEAR
 
 config ARCH_SPEAR13XX
 	bool "ST SPEAr13xx"
-	depends on ARCH_MULTI_V7 || PLAT_SPEAR_SINGLE
+	depends on ARCH_MULTI_V7
 	select ARCH_HAS_CPUFREQ
 	select ARM_GIC
 	select CPU_V7
@@ -47,7 +46,7 @@ endif #ARCH_SPEAR13XX
 
 config ARCH_SPEAR3XX
 	bool "ST SPEAr3xx"
-	depends on ARCH_MULTI_V5 || PLAT_SPEAR_SINGLE
+	depends on ARCH_MULTI_V5
 	depends on !ARCH_SPEAR13XX
 	select ARM_VIC
 	select CPU_ARM926T
@@ -80,7 +79,7 @@ endif
 
 config ARCH_SPEAR6XX
 	bool "ST SPEAr6XX"
-	depends on ARCH_MULTI_V5 || PLAT_SPEAR_SINGLE
+	depends on ARCH_MULTI_V5
 	depends on !ARCH_SPEAR13XX
 	select ARM_VIC
 	select CPU_ARM926T
@@ -95,7 +94,6 @@ config MACH_SPEAR600
 	  Supports ST SPEAr600 boards configured via the device-treesource "arch/arm/mach-spear6xx/Kconfig"
 
 config ARCH_SPEAR_AUTO
-	def_bool PLAT_SPEAR_SINGLE
 	depends on !ARCH_SPEAR13XX && !ARCH_SPEAR6XX
 	select ARCH_SPEAR3XX
 
-- 
1.8.5.3

^ permalink raw reply related

* [PATCH 4/9] ARM: Select V6K instead of V6 by default for multi-platform
From: Arnd Bergmann @ 2014-02-11 21:22 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1392153119-23248-5-git-send-email-robherring2@gmail.com>

On Tuesday 11 February 2014 15:11:54 Rob Herring wrote:
> @@ -1,9 +1,9 @@
>  config ARCH_CNS3XXX
>         bool "Cavium Networks CNS3XXX family" if ARCH_MULTI_V6
>         select ARM_GIC
> -       select CPU_V6K
>         select MIGHT_HAVE_PCI
>         select PCI_DOMAINS if PCI
> +       select CPU_V6
>         help
>           Support for Cavium Networks CNS3XXX platform.

I thought we had concluded that CNS3xxx is V6K as well. Do you
have newer information? Maybe Anton remembers.

	Arnd

^ permalink raw reply

* [PATCH 4/9] ARM: Select V6K instead of V6 by default for multi-platform
From: Rob Herring @ 2014-02-11 21:26 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1492617.b9HLFpaExO@wuerfel>

On Tue, Feb 11, 2014 at 3:22 PM, Arnd Bergmann <arnd@arndb.de> wrote:
> On Tuesday 11 February 2014 15:11:54 Rob Herring wrote:
>> @@ -1,9 +1,9 @@
>>  config ARCH_CNS3XXX
>>         bool "Cavium Networks CNS3XXX family" if ARCH_MULTI_V6
>>         select ARM_GIC
>> -       select CPU_V6K
>>         select MIGHT_HAVE_PCI
>>         select PCI_DOMAINS if PCI
>> +       select CPU_V6
>>         help
>>           Support for Cavium Networks CNS3XXX platform.
>
> I thought we had concluded that CNS3xxx is V6K as well. Do you
> have newer information? Maybe Anton remembers.

I believe it is being MP, but I split this up so that changing the
default doesn't change any platform and each platform change is a
separate patch which can be applied or not.

Rob

^ permalink raw reply

* [PATCH 4/9] ARM: Select V6K instead of V6 by default for multi-platform
From: Arnd Bergmann @ 2014-02-11 21:27 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAL_JsqK0MfdaBfytkOY-abJ614NU9R6FR0rGOeFUx8ojanjZ3A@mail.gmail.com>

On Tuesday 11 February 2014 15:26:14 Rob Herring wrote:
> On Tue, Feb 11, 2014 at 3:22 PM, Arnd Bergmann <arnd@arndb.de> wrote:
> > On Tuesday 11 February 2014 15:11:54 Rob Herring wrote:
> >> @@ -1,9 +1,9 @@
> >>  config ARCH_CNS3XXX
> >>         bool "Cavium Networks CNS3XXX family" if ARCH_MULTI_V6
> >>         select ARM_GIC
> >> -       select CPU_V6K
> >>         select MIGHT_HAVE_PCI
> >>         select PCI_DOMAINS if PCI
> >> +       select CPU_V6
> >>         help
> >>           Support for Cavium Networks CNS3XXX platform.
> >
> > I thought we had concluded that CNS3xxx is V6K as well. Do you
> > have newer information? Maybe Anton remembers.
> 
> I believe it is being MP, but I split this up so that changing the
> default doesn't change any platform and each platform change is a
> separate patch which can be applied or not.
> 

Ok, got it.

	Arnd

^ permalink raw reply

* [PATCH] ARM: spear: Remove references to PLAT_SPEAR_SINGLE
From: Paul Bolle @ 2014-02-11 21:27 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1392153676.14317.8.camel@x220>

I got a bounce for Shiraz' address. Has Shiraz left ST?


Paul Bolle

^ permalink raw reply

* [PATCH 1/4] arm64: topology: Implement basic CPU topology support
From: Mark Brown @ 2014-02-11 22:04 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAKfTPtDrLX6ZSV9cZckGztorrYRc-PNknaJch3nry=PzonZJHw@mail.gmail.com>

On Tue, Feb 11, 2014 at 03:46:04PM +0100, Vincent Guittot wrote:
> On 11 February 2014 15:07, Catalin Marinas <catalin.marinas@arm.com> wrote:

> > As Will said, smp_*mb() do not ensure absolute visibility, only relative
> > to subsequent memory accesses on the same processor. So just placing a
> > barrier at the end of a function does not mean much, it only shows half
> > of the problem it is trying to solve.

> OK, that's probably the shortcut that has been made, we want to drain
> the write buffer to make modification available to other cpus and I
> though smp_wmb and the associated mb(ishst) was there for that
> purpose.

It does also explain where I got to trying to figure out what exactly
the mechanism was!

> > So my proposal is to remove the smp_wmb() from topology.c and add it
> > where it is relevant as described above. If we have some race in
> > topology.c (like for example we may later decide to start more
> > secondaries at the same time), it needs to be solved using spinlocks.

I'll just repost a version dropping them from the topology series and
separately add the barriers elsewhere.  The 32 bit ARM implementation
probably ought to be fixed as well.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140211/af5fc293/attachment-0001.sig>

^ permalink raw reply

* [PATCH 1/4] arm64: topology: Implement basic CPU topology support
From: Mark Brown @ 2014-02-11 22:06 UTC (permalink / raw)
  To: linux-arm-kernel

From: Mark Brown <broonie@linaro.org>

Add basic CPU topology support to arm64, based on the existing pre-v8
code and some work done by Mark Hambleton.  This patch does not
implement any topology discovery support since that should be based on
information from firmware, it merely implements the scaffolding for
integration of topology support in the architecture.

The goal is to separate the architecture hookup for providing topology
information from the DT parsing in order to ease review and avoid
blocking the architecture code (which will be built on by other work)
with the DT code review by providing something simple and basic.

A following patch will implement support for parsing the DT topology
bindings for ARM, similar patches will be needed for ACPI.

Signed-off-by: Mark Brown <broonie@linaro.org>
---
 arch/arm64/Kconfig                | 24 +++++++++++
 arch/arm64/include/asm/topology.h | 39 +++++++++++++++++
 arch/arm64/kernel/Makefile        |  1 +
 arch/arm64/kernel/smp.c           | 11 +++++
 arch/arm64/kernel/topology.c      | 89 +++++++++++++++++++++++++++++++++++++++
 5 files changed, 164 insertions(+)
 create mode 100644 arch/arm64/include/asm/topology.h
 create mode 100644 arch/arm64/kernel/topology.c

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 27bbcfc7202a..fea7b477676b 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -164,6 +164,30 @@ config SMP
 
 	  If you don't know what to do here, say N.
 
+config CPU_TOPOLOGY
+	bool "Support CPU topology definition"
+	depends on SMP
+	default y
+	help
+	  Support CPU topology definition, based on configuration
+	  provided by the firmware.
+
+config SCHED_MC
+	bool "Multi-core scheduler support"
+	depends on CPU_TOPOLOGY
+	help
+	  Multi-core scheduler support improves the CPU scheduler's decision
+	  making when dealing with multi-core CPU chips at a cost of slightly
+	  increased overhead in some places. If unsure say N here.
+
+config SCHED_SMT
+	bool "SMT scheduler support"
+	depends on CPU_TOPOLOGY
+	help
+	  Improves the CPU scheduler's decision making when dealing with
+	  MultiThreading at a cost of slightly increased overhead in some
+	  places. If unsure say N here.
+
 config NR_CPUS
 	int "Maximum number of CPUs (2-32)"
 	range 2 32
diff --git a/arch/arm64/include/asm/topology.h b/arch/arm64/include/asm/topology.h
new file mode 100644
index 000000000000..c8a47e8f452b
--- /dev/null
+++ b/arch/arm64/include/asm/topology.h
@@ -0,0 +1,39 @@
+#ifndef __ASM_TOPOLOGY_H
+#define __ASM_TOPOLOGY_H
+
+#ifdef CONFIG_CPU_TOPOLOGY
+
+#include <linux/cpumask.h>
+
+struct cpu_topology {
+	int thread_id;
+	int core_id;
+	int cluster_id;
+	cpumask_t thread_sibling;
+	cpumask_t core_sibling;
+};
+
+extern struct cpu_topology cpu_topology[NR_CPUS];
+
+#define topology_physical_package_id(cpu)	(cpu_topology[cpu].cluster_id)
+#define topology_core_id(cpu)		(cpu_topology[cpu].core_id)
+#define topology_core_cpumask(cpu)	(&cpu_topology[cpu].core_sibling)
+#define topology_thread_cpumask(cpu)	(&cpu_topology[cpu].thread_sibling)
+
+#define mc_capable()	(cpu_topology[0].cluster_id != -1)
+#define smt_capable()	(cpu_topology[0].thread_id != -1)
+
+void init_cpu_topology(void);
+void store_cpu_topology(unsigned int cpuid);
+const struct cpumask *cpu_coregroup_mask(int cpu);
+
+#else
+
+static inline void init_cpu_topology(void) { }
+static inline void store_cpu_topology(unsigned int cpuid) { }
+
+#endif
+
+#include <asm-generic/topology.h>
+
+#endif /* _ASM_ARM_TOPOLOGY_H */
diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index 2d4554b13410..252b62181532 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -20,6 +20,7 @@ arm64-obj-$(CONFIG_HAVE_HW_BREAKPOINT)+= hw_breakpoint.o
 arm64-obj-$(CONFIG_EARLY_PRINTK)	+= early_printk.o
 arm64-obj-$(CONFIG_ARM64_CPU_SUSPEND)	+= sleep.o suspend.o
 arm64-obj-$(CONFIG_JUMP_LABEL)		+= jump_label.o
+arm64-obj-$(CONFIG_CPU_TOPOLOGY)	+= topology.o
 
 obj-y					+= $(arm64-obj-y) vdso/
 obj-m					+= $(arm64-obj-m)
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index 7cfb92a4ab66..9660750f34ba 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -114,6 +114,11 @@ int __cpu_up(unsigned int cpu, struct task_struct *idle)
 	return ret;
 }
 
+static void smp_store_cpu_info(unsigned int cpuid)
+{
+	store_cpu_topology(cpuid);
+}
+
 /*
  * This is the secondary CPU boot entry.  We're using this CPUs
  * idle thread stack, but a set of temporary page tables.
@@ -152,6 +157,8 @@ asmlinkage void secondary_start_kernel(void)
 	 */
 	notify_cpu_starting(cpu);
 
+	smp_store_cpu_info(cpu);
+
 	/*
 	 * OK, now it's safe to let the boot CPU continue.  Wait for
 	 * the CPU migration code to notice that the CPU is online
@@ -390,6 +397,10 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
 	int err;
 	unsigned int cpu, ncores = num_possible_cpus();
 
+	init_cpu_topology();
+
+	smp_store_cpu_info(smp_processor_id());
+
 	/*
 	 * are we trying to boot more cores than exist?
 	 */
diff --git a/arch/arm64/kernel/topology.c b/arch/arm64/kernel/topology.c
new file mode 100644
index 000000000000..cbb8d432214e
--- /dev/null
+++ b/arch/arm64/kernel/topology.c
@@ -0,0 +1,89 @@
+/*
+ * arch/arm64/kernel/topology.c
+ *
+ * Copyright (C) 2011,2013 Linaro Limited.
+ *
+ * Based on the arm32 version written by Vincent Guittot in turn based on
+ * arch/sh/kernel/topology.c
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/cpu.h>
+#include <linux/cpumask.h>
+#include <linux/init.h>
+#include <linux/percpu.h>
+#include <linux/node.h>
+#include <linux/nodemask.h>
+#include <linux/sched.h>
+
+#include <asm/topology.h>
+
+/*
+ * cpu topology table
+ */
+struct cpu_topology cpu_topology[NR_CPUS];
+EXPORT_SYMBOL_GPL(cpu_topology);
+
+const struct cpumask *cpu_coregroup_mask(int cpu)
+{
+	return &cpu_topology[cpu].core_sibling;
+}
+
+static void update_siblings_masks(unsigned int cpuid)
+{
+	struct cpu_topology *cpu_topo, *cpuid_topo = &cpu_topology[cpuid];
+	int cpu;
+
+	/* update core and thread sibling masks */
+	for_each_possible_cpu(cpu) {
+		cpu_topo = &cpu_topology[cpu];
+
+		if (cpuid_topo->cluster_id != cpu_topo->cluster_id)
+			continue;
+
+		cpumask_set_cpu(cpuid, &cpu_topo->core_sibling);
+		if (cpu != cpuid)
+			cpumask_set_cpu(cpu, &cpuid_topo->core_sibling);
+
+		if (cpuid_topo->core_id != cpu_topo->core_id)
+			continue;
+
+		cpumask_set_cpu(cpuid, &cpu_topo->thread_sibling);
+		if (cpu != cpuid)
+			cpumask_set_cpu(cpu, &cpuid_topo->thread_sibling);
+	}
+}
+
+void store_cpu_topology(unsigned int cpuid)
+{
+	struct cpu_topology *cpuid_topo = &cpu_topology[cpuid];
+
+	/* DT should have been parsed by the time we get here */
+	if (cpuid_topo->core_id == -1)
+		pr_info("CPU%u: No topology information configured\n", cpuid);
+	else
+		update_siblings_masks(cpuid);
+}
+
+/*
+ * init_cpu_topology is called at boot when only one cpu is running
+ * which prevent simultaneous write access to cpu_topology array
+ */
+void __init init_cpu_topology(void)
+{
+	unsigned int cpu;
+
+	/* init core mask and power*/
+	for_each_possible_cpu(cpu) {
+		struct cpu_topology *cpu_topo = &cpu_topology[cpu];
+
+		cpu_topo->thread_id = -1;
+		cpu_topo->core_id =  -1;
+		cpu_topo->cluster_id = -1;
+		cpumask_clear(&cpu_topo->core_sibling);
+		cpumask_clear(&cpu_topo->thread_sibling);
+	}
+}
-- 
1.9.0.rc3

^ permalink raw reply related

* [PATCH 2/4] arm64: topology: Add support for topology DT bindings
From: Mark Brown @ 2014-02-11 22:06 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1392156389-5497-1-git-send-email-broonie@kernel.org>

From: Mark Brown <broonie@linaro.org>

Add support for parsing the explicit topology bindings to discover the
topology of the system.

Since it is not currently clear how to map multi-level clusters for the
scheduler all leaf clusters are presented to the scheduler at the same
level. This should be enough to provide good support for current systems.

Signed-off-by: Mark Brown <broonie@linaro.org>
---
 arch/arm64/kernel/topology.c | 142 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 142 insertions(+)

diff --git a/arch/arm64/kernel/topology.c b/arch/arm64/kernel/topology.c
index cbb8d432214e..a757297992a1 100644
--- a/arch/arm64/kernel/topology.c
+++ b/arch/arm64/kernel/topology.c
@@ -17,10 +17,150 @@
 #include <linux/percpu.h>
 #include <linux/node.h>
 #include <linux/nodemask.h>
+#include <linux/of.h>
 #include <linux/sched.h>
 
 #include <asm/topology.h>
 
+#ifdef CONFIG_OF
+static int __init get_cpu_for_node(struct device_node *node)
+{
+	struct device_node *cpu_node;
+	int cpu;
+
+	cpu_node = of_parse_phandle(node, "cpu", 0);
+	if (!cpu_node)
+		return -1;
+
+	for_each_possible_cpu(cpu) {
+		if (of_get_cpu_node(cpu, NULL) == cpu_node)
+			return cpu;
+	}
+
+	pr_crit("Unable to find CPU node for %s\n", cpu_node->full_name);
+	return -1;
+}
+
+static void __init parse_core(struct device_node *core, int cluster_id,
+			      int core_id)
+{
+	char name[10];
+	bool leaf = true;
+	int i = 0;
+	int cpu;
+	struct device_node *t;
+
+	do {
+		snprintf(name, sizeof(name), "thread%d", i);
+		t = of_get_child_by_name(core, name);
+		if (t) {
+			leaf = false;
+			cpu = get_cpu_for_node(t);
+			if (cpu >= 0) {
+				cpu_topology[cpu].cluster_id = cluster_id;
+				cpu_topology[cpu].core_id = core_id;
+				cpu_topology[cpu].thread_id = i;
+			} else {
+				pr_err("%s: Can't get CPU for thread\n",
+				       t->full_name);
+			}
+		}
+		i++;
+	} while (t);
+
+	cpu = get_cpu_for_node(core);
+	if (cpu >= 0) {
+		if (!leaf) {
+			pr_err("%s: Core has both threads and CPU\n",
+			       core->full_name);
+			return;
+		}
+
+		cpu_topology[cpu].cluster_id = cluster_id;
+		cpu_topology[cpu].core_id = core_id;
+	} else if (leaf) {
+		pr_err("%s: Can't get CPU for leaf core\n", core->full_name);
+	}
+}
+
+static void __init parse_cluster(struct device_node *cluster, int depth)
+{
+	char name[10];
+	bool leaf = true;
+	bool has_cores = false;
+	struct device_node *c;
+	static int __initdata cluster_id;
+	int core_id = 0;
+	int i;
+
+	/*
+	 * First check for child clusters; we currently ignore any
+	 * information about the nesting of clusters and present the
+	 * scheduler with a flat list of them.
+	 */
+	i = 0;
+	do {
+		snprintf(name, sizeof(name), "cluster%d", i);
+		c = of_get_child_by_name(cluster, name);
+		if (c) {
+			parse_cluster(c, depth + 1);
+			leaf = false;
+		}
+		i++;
+	} while (c);
+
+	/* Now check for cores */
+	i = 0;
+	do {
+		snprintf(name, sizeof(name), "core%d", i);
+		c = of_get_child_by_name(cluster, name);
+		if (c) {
+			has_cores = true;
+
+			if (depth == 0)
+				pr_err("%s: cpu-map children should be clusters\n",
+				       c->full_name);
+
+			if (leaf)
+				parse_core(c, cluster_id, core_id++);
+			else
+				pr_err("%s: Non-leaf cluster with core %s\n",
+				       cluster->full_name, name);
+		}
+		i++;
+	} while (c);
+
+	if (leaf && !has_cores)
+		pr_warn("%s: empty cluster\n", cluster->full_name);
+
+	if (leaf)
+		cluster_id++;
+}
+
+static void __init parse_dt_topology(void)
+{
+	struct device_node *cn;
+
+	cn = of_find_node_by_path("/cpus");
+	if (!cn) {
+		pr_err("No CPU information found in DT\n");
+		return;
+	}
+
+	/*
+	 * When topology is provided cpu-map is essentially a root
+	 * cluster with restricted subnodes.
+	 */
+	cn = of_find_node_by_name(cn, "cpu-map");
+	if (!cn)
+		return;
+	parse_cluster(cn, 0);
+}
+
+#else
+static inline void parse_dt_topology(void) {}
+#endif
+
 /*
  * cpu topology table
  */
@@ -86,4 +226,6 @@ void __init init_cpu_topology(void)
 		cpumask_clear(&cpu_topo->core_sibling);
 		cpumask_clear(&cpu_topo->thread_sibling);
 	}
+
+	parse_dt_topology();
 }
-- 
1.9.0.rc3

^ permalink raw reply related

* [PATCH 3/4] arm64: topology: Tell the scheduler about the relative power of cores
From: Mark Brown @ 2014-02-11 22:06 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1392156389-5497-1-git-send-email-broonie@kernel.org>

From: Mark Brown <broonie@linaro.org>

In heterogeneous systems like big.LITTLE systems the scheduler will be
able to make better use of the available cores if we provide power numbers
to it indicating their relative performance. Do this by parsing the CPU
nodes in the DT.

This code currently has no effect as no information on the relative
performance of the cores is provided.

Signed-off-by: Mark Brown <broonie@linaro.org>
---
 arch/arm64/kernel/topology.c | 142 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 142 insertions(+)

diff --git a/arch/arm64/kernel/topology.c b/arch/arm64/kernel/topology.c
index a757297992a1..0f5a5d0cbbf0 100644
--- a/arch/arm64/kernel/topology.c
+++ b/arch/arm64/kernel/topology.c
@@ -19,9 +19,33 @@
 #include <linux/nodemask.h>
 #include <linux/of.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 
 #include <asm/topology.h>
 
+/*
+ * cpu power table
+ * This per cpu data structure describes the relative capacity of each core.
+ * On a heteregenous system, cores don't have the same computation capacity
+ * and we reflect that difference in the cpu_power field so the scheduler can
+ * take this difference into account during load balance. A per cpu structure
+ * is preferred because each CPU updates its own cpu_power field during the
+ * load balance except for idle cores. One idle core is selected to run the
+ * rebalance_domains for all idle cores and the cpu_power can be updated
+ * during this sequence.
+ */
+static DEFINE_PER_CPU(unsigned long, cpu_scale);
+
+unsigned long arch_scale_freq_power(struct sched_domain *sd, int cpu)
+{
+	return per_cpu(cpu_scale, cpu);
+}
+
+static void set_power_scale(unsigned int cpu, unsigned long power)
+{
+	per_cpu(cpu_scale, cpu) = power;
+}
+
 #ifdef CONFIG_OF
 static int __init get_cpu_for_node(struct device_node *node)
 {
@@ -137,9 +161,49 @@ static void __init parse_cluster(struct device_node *cluster, int depth)
 		cluster_id++;
 }
 
+struct cpu_efficiency {
+	const char *compatible;
+	unsigned long efficiency;
+};
+
+/*
+ * Table of relative efficiency of each processors
+ * The efficiency value must fit in 20bit and the final
+ * cpu_scale value must be in the range
+ *   0 < cpu_scale < 3*SCHED_POWER_SCALE/2
+ * in order to return@most 1 when DIV_ROUND_CLOSEST
+ * is used to compute the capacity of a CPU.
+ * Processors that are not defined in the table,
+ * use the default SCHED_POWER_SCALE value for cpu_scale.
+ */
+static const struct cpu_efficiency table_efficiency[] = {
+	{ NULL, },
+};
+
+static unsigned long *__cpu_capacity;
+#define cpu_capacity(cpu)	__cpu_capacity[cpu]
+
+static unsigned long middle_capacity = 1;
+
+/*
+ * Iterate all CPUs' descriptor in DT and compute the efficiency
+ * (as per table_efficiency). Also calculate a middle efficiency
+ * as close as possible to  (max{eff_i} - min{eff_i}) / 2
+ * This is later used to scale the cpu_power field such that an
+ * 'average' CPU is of middle power. Also see the comments near
+ * table_efficiency[] and update_cpu_power().
+ */
 static void __init parse_dt_topology(void)
 {
+	const struct cpu_efficiency *cpu_eff;
 	struct device_node *cn;
+	unsigned long min_capacity = ULONG_MAX;
+	unsigned long max_capacity = 0;
+	unsigned long capacity = 0;
+	int cpu;
+
+	__cpu_capacity = kcalloc(nr_cpu_ids, sizeof(*__cpu_capacity),
+				 GFP_NOWAIT);
 
 	cn = of_find_node_by_path("/cpus");
 	if (!cn) {
@@ -155,10 +219,84 @@ static void __init parse_dt_topology(void)
 	if (!cn)
 		return;
 	parse_cluster(cn, 0);
+
+	for_each_possible_cpu(cpu) {
+		const u32 *rate;
+		int len;
+
+		/* Too early to use cpu->of_node */
+		cn = of_get_cpu_node(cpu, NULL);
+		if (!cn) {
+			pr_err("Missing device node for CPU %d\n", cpu);
+			continue;
+		}
+
+		for (cpu_eff = table_efficiency; cpu_eff->compatible; cpu_eff++)
+			if (of_device_is_compatible(cn, cpu_eff->compatible))
+				break;
+
+		if (cpu_eff->compatible == NULL) {
+			pr_warn("%s: Unknown CPU type\n", cn->full_name);
+			continue;
+		}
+
+		rate = of_get_property(cn, "clock-frequency", &len);
+		if (!rate || len != 4) {
+			pr_err("%s: Missing clock-frequency property\n",
+				cn->full_name);
+			continue;
+		}
+
+		capacity = ((be32_to_cpup(rate)) >> 20) * cpu_eff->efficiency;
+
+		/* Save min capacity of the system */
+		if (capacity < min_capacity)
+			min_capacity = capacity;
+
+		/* Save max capacity of the system */
+		if (capacity > max_capacity)
+			max_capacity = capacity;
+
+		cpu_capacity(cpu) = capacity;
+	}
+
+	/* If min and max capacities are equal we bypass the update of the
+	 * cpu_scale because all CPUs have the same capacity. Otherwise, we
+	 * compute a middle_capacity factor that will ensure that the capacity
+	 * of an 'average' CPU of the system will be as close as possible to
+	 * SCHED_POWER_SCALE, which is the default value, but with the
+	 * constraint explained near table_efficiency[].
+	 */
+	if (min_capacity == max_capacity)
+		return;
+	else if (4 * max_capacity < (3 * (max_capacity + min_capacity)))
+		middle_capacity = (min_capacity + max_capacity)
+				>> (SCHED_POWER_SHIFT+1);
+	else
+		middle_capacity = ((max_capacity / 3)
+				>> (SCHED_POWER_SHIFT-1)) + 1;
+
+}
+
+/*
+ * Look for a customed capacity of a CPU in the cpu_topo_data table during the
+ * boot. The update of all CPUs is in O(n^2) for heteregeneous system but the
+ * function returns directly for SMP system.
+ */
+static void update_cpu_power(unsigned int cpu)
+{
+	if (!cpu_capacity(cpu))
+		return;
+
+	set_power_scale(cpu, cpu_capacity(cpu) / middle_capacity);
+
+	pr_info("CPU%u: update cpu_power %lu\n",
+		cpu, arch_scale_freq_power(NULL, cpu));
 }
 
 #else
 static inline void parse_dt_topology(void) {}
+static inline void update_cpu_power(unsigned int cpuid) {}
 #endif
 
 /*
@@ -206,6 +344,8 @@ void store_cpu_topology(unsigned int cpuid)
 		pr_info("CPU%u: No topology information configured\n", cpuid);
 	else
 		update_siblings_masks(cpuid);
+
+	update_cpu_power(cpuid);
 }
 
 /*
@@ -225,6 +365,8 @@ void __init init_cpu_topology(void)
 		cpu_topo->cluster_id = -1;
 		cpumask_clear(&cpu_topo->core_sibling);
 		cpumask_clear(&cpu_topo->thread_sibling);
+
+		set_power_scale(cpu, SCHED_POWER_SCALE);
 	}
 
 	parse_dt_topology();
-- 
1.9.0.rc3

^ permalink raw reply related

* [PATCH 4/4] arm64: topology: Provide relative power numbers for cores
From: Mark Brown @ 2014-02-11 22:06 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1392156389-5497-1-git-send-email-broonie@kernel.org>

From: Mark Brown <broonie@linaro.org>

Provide performance numbers to the scheduler to help it fill the cores in
the system on big.LITTLE systems. With the current scheduler this may
perform poorly for applications that try to do OpenMP style work over all
cores but should help for more common workloads. The current 32 bit ARM
implementation provides a similar estimate so this helps ensure that
work to improve big.LITTLE systems on ARMv7 systems performs similarly
on ARMv8 systems.

The power numbers are the same as for ARMv7 since it seems that the
expected differential between the big and little cores is very similar on
both ARMv7 and ARMv8.  In both ARMv7 and ARMv8 cases the numbers were
based on the published DMIPS numbers.

These numbers are just an initial and basic approximation for use with
the current scheduler, it is likely that both experience with silicon
and ongoing work on improving the scheduler will lead to further tuning
or will tune automatically at runtime and so make the specific choice of
numbers here less critical.

Signed-off-by: Mark Brown <broonie@linaro.org>
---
 arch/arm64/kernel/topology.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm64/kernel/topology.c b/arch/arm64/kernel/topology.c
index 0f5a5d0cbbf0..c37854fd0df5 100644
--- a/arch/arm64/kernel/topology.c
+++ b/arch/arm64/kernel/topology.c
@@ -177,6 +177,8 @@ struct cpu_efficiency {
  * use the default SCHED_POWER_SCALE value for cpu_scale.
  */
 static const struct cpu_efficiency table_efficiency[] = {
+	{ "arm,cortex-a57", 3891 },
+	{ "arm,cortex-a53", 2048 },
 	{ NULL, },
 };
 
-- 
1.9.0.rc3

^ permalink raw reply related

* [PATCH 0/2] Marvell Armada 375 and 38x timer support
From: Daniel Lezcano @ 2014-02-11 22:08 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20140211160335.GB24205@localhost>

On 02/11/2014 05:03 PM, Ezequiel Garcia wrote:
> Daniel,
>
> On Mon, Feb 10, 2014 at 04:07:52PM -0300, Ezequiel Garcia wrote:
>>
>> This small series adds support for the two new Marvell ARM SoCs:
>> the Armada 375 and Armada 38x.
>>
>
> Please omit these patches entirely, we don't need them.

Roger.

> The new agreement [1] is to add SoC-specific compatible strings and also
> declare the nodes as compatibles with the already supported SoC,
> whenever appropriate.
>
> [..]
>> The A375 SoC timer is modeled matching the A370 timer, while the
>> A38x SoC timer is modeled matching the AXP timer.
>>
>
> So, as per the statement above, the devicetree for Armada 375 and
> Armada 38x would have these timer nodes, respectively:
>
>    timer {
>        compatible = "marvell,armada-375-timer", "marvell,armada-370-timer"
>    }
>
>    timer {
>        compatible = "marvell,armada-380-timer", "marvell,armada-xp-timer"
>    }
>
> (Because the Armada 375 timer uses the provided parent clock, whereas the
> Armada 380 timer uses the fixed 25 MHz clock).
>
> Therefore, we don't need any changes in the clocksource driver for now.
>
> [1] http://www.spinics.net/lists/arm-kernel/msg306727.html
>


-- 
  <http://www.linaro.org/> Linaro.org ? Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

^ permalink raw reply

* [PATCH] arm64: vdso: clean up vdso_pagelist initialization
From: Nathan Lynch @ 2014-02-11 22:28 UTC (permalink / raw)
  To: linux-arm-kernel

Remove some unnecessary bits that were apparently carried over from
another architecture's implementation:

- No need to get_page() the vdso text/data - these are part of the
  kernel image.
- No need for ClearPageReserved on the vdso text.
- No need to vmap the first text page to check the ELF header - this
  can be done through &vdso_start.

Also some minor cleanup:
- Use kcalloc for vdso_pagelist array allocation.
- Don't print on allocation failure, slab/slub will do that for us.

Signed-off-by: Nathan Lynch <nathan_lynch@mentor.com>
---
 arch/arm64/kernel/vdso.c | 42 ++++++++++++------------------------------
 1 file changed, 12 insertions(+), 30 deletions(-)

diff --git a/arch/arm64/kernel/vdso.c b/arch/arm64/kernel/vdso.c
index a7149cae1615..50384fec56c4 100644
--- a/arch/arm64/kernel/vdso.c
+++ b/arch/arm64/kernel/vdso.c
@@ -106,49 +106,31 @@ int aarch32_setup_vectors_page(struct linux_binprm *bprm, int uses_interp)
 
 static int __init vdso_init(void)
 {
-	struct page *pg;
-	char *vbase;
-	int i, ret = 0;
+	int i;
+
+	if (memcmp(&vdso_start, "\177ELF", 4)) {
+		pr_err("vDSO is not a valid ELF object!\n");
+		return -EINVAL;
+	}
 
 	vdso_pages = (&vdso_end - &vdso_start) >> PAGE_SHIFT;
 	pr_info("vdso: %ld pages (%ld code, %ld data) at base %p\n",
 		vdso_pages + 1, vdso_pages, 1L, &vdso_start);
 
 	/* Allocate the vDSO pagelist, plus a page for the data. */
-	vdso_pagelist = kzalloc(sizeof(struct page *) * (vdso_pages + 1),
+	vdso_pagelist = kcalloc(vdso_pages + 1, sizeof(struct page *),
 				GFP_KERNEL);
-	if (vdso_pagelist == NULL) {
-		pr_err("Failed to allocate vDSO pagelist!\n");
+	if (vdso_pagelist == NULL)
 		return -ENOMEM;
-	}
 
 	/* Grab the vDSO code pages. */
-	for (i = 0; i < vdso_pages; i++) {
-		pg = virt_to_page(&vdso_start + i*PAGE_SIZE);
-		ClearPageReserved(pg);
-		get_page(pg);
-		vdso_pagelist[i] = pg;
-	}
-
-	/* Sanity check the shared object header. */
-	vbase = vmap(vdso_pagelist, 1, 0, PAGE_KERNEL);
-	if (vbase == NULL) {
-		pr_err("Failed to map vDSO pagelist!\n");
-		return -ENOMEM;
-	} else if (memcmp(vbase, "\177ELF", 4)) {
-		pr_err("vDSO is not a valid ELF object!\n");
-		ret = -EINVAL;
-		goto unmap;
-	}
+	for (i = 0; i < vdso_pages; i++)
+		vdso_pagelist[i] = virt_to_page(&vdso_start + i * PAGE_SIZE);
 
 	/* Grab the vDSO data page. */
-	pg = virt_to_page(vdso_data);
-	get_page(pg);
-	vdso_pagelist[i] = pg;
+	vdso_pagelist[i] = virt_to_page(vdso_data);
 
-unmap:
-	vunmap(vbase);
-	return ret;
+	return 0;
 }
 arch_initcall(vdso_init);
 
-- 
1.8.3.1

^ permalink raw reply related

* [PATCH] power: reset: msm - switch Kconfig to ARCH_QCOM depends
From: Dmitry Eremin-Solenikov @ 2014-02-11 22:46 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1392150126-21744-1-git-send-email-galak@codeaurora.org>

On Wed, Feb 12, 2014 at 12:22 AM, Kumar Gala <galak@codeaurora.org> wrote:
> We've split Qualcomm MSM support into legacy and multiplatform.  The reset
> driver is only relevant on the multiplatform supported SoCs so switch the
> Kconfig depends to ARCH_QCOM.
>
> Signed-off-by: Kumar Gala <galak@codeaurora.org>

Acked-by: Dmitry Eremin-Solenikov

> ---
> Dmitry, David,
>
> If you can ack this I'll send it via linux-qcom/arm-soc tree's

Please, go ahead.

>
> thanks



-- 
With best wishes
Dmitry

^ permalink raw reply

* [PATCH 1/3] arm64: dts: add initial dts for Samsung GH7 SoC and SSDK-GH7 board
From: Olof Johansson @ 2014-02-11 23:36 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1392100183-30930-2-git-send-email-kgene.kim@samsung.com>

Hi,

Besides what Mark Rutland already commented on:

On Mon, Feb 10, 2014 at 10:29 PM, Kukjin Kim <kgene.kim@samsung.com> wrote:
> +/ {
> +       model = "SAMSUNG GH7";
> +       compatible = "samsung,gh7";

Model and compatible in the dtsi should probably always be overridden
by a dts that includes it, so there's little use in having it here.

> +       interrupt-parent = <&gic>;
> +       #address-cells = <2>;
> +       #size-cells = <2>;
> +
> +       cpus {
> +               #address-cells = <2>;
> +               #size-cells = <0>;
> +
> +               cpu at 000 {
> +                       device_type = "cpu";
> +                       compatible = "arm,armv8";
> +                       reg = <0x0 0x000>;

No need to zero-pad cpu numbers in unit address or reg.

> +                       enable-method = "spin-table";
> +                       cpu-release-addr = <0x0 0x8000fff8>;
> +               };
> +               cpu at 001 {
> +                       device_type = "cpu";
> +                       compatible = "arm,armv8";
> +                       reg = <0x0 0x001>;
> +                       enable-method = "spin-table";
> +                       cpu-release-addr = <0x0 0x8000fff8>;
> +               };
> +               cpu at 002 {
> +                       device_type = "cpu";
> +                       compatible = "arm,armv8";
> +                       reg = <0x0 0x002>;
> +                       enable-method = "spin-table";
> +                       cpu-release-addr = <0x0 0x8000fff8>;
> +               };
> +               cpu at 003 {
> +                       device_type = "cpu";
> +                       compatible = "arm,armv8";
> +                       reg = <0x0 0x003>;
> +                       enable-method = "spin-table";
> +                       cpu-release-addr = <0x0 0x8000fff8>;
> +               };
> +       };
> +
> +       gic: interrupt-controller at 1C000000 {
> +               compatible = "arm,cortex-a15-gic", "arm,cortex-a9-gic";

This looks incorrect -- you should at the very least have a more
specific one than a15-gic? Marc?

> +               #interrupt-cells = <3>;
> +               #address-cells = <0>;
> +               interrupt-controller;
> +               reg = <0x0 0x1C001000 0 0x1000>,        /* GIC Dist */
> +                     <0x0 0x1C002000 0 0x1000>,        /* GIC CPU */
> +                     <0x0 0x1C004000 0 0x2000>,        /* GIC VCPU Control */
> +                     <0x0 0x1C006000 0 0x2000>;        /* GIC VCPU */
> +               interrupts = <1 9 0xf04>;       /* GIC Maintenence IRQ */
> +       };
> +
> +       timer {
> +               compatible = "arm,armv8-timer";
> +               interrupts = <1 13 0xff01>,     /* Secure Phys IRQ */
> +                            <1 14 0xff01>,     /* Non-secure Phys IRQ */
> +                            <1 11 0xff01>,     /* Virt IRQ */
> +                            <1 10 0xff01>;     /* Hyp IRQ */
> +               clock-frequency = <100000000>;
> +       };
> +
> +       pmu {
> +               compatible = "arm,armv8-pmuv3";
> +               interrupts = <0 294 8>,
> +                            <0 295 8>,
> +                            <0 296 8>,
> +                            <0 297 8>,
> +                            <0 298 8>,
> +                            <0 299 8>,
> +                            <0 300 8>,
> +                            <0 301 8>;
> +       };
> +
> +       amba {
> +               compatible = "arm,amba-bus";
> +               #address-cells = <1>;
> +               #size-cells = <1>;
> +               ranges;
> +
> +               serial at 12c00000 {
> +                       compatible = "arm,pl011", "arm,primecell";
> +                       reg = <0x12c00000 0x10000>;
> +                       interrupts = <418>;
> +               };
> +
> +               serial at 12c20000 {
> +                       compatible = "arm,pl011", "arm,primecell";
> +                       reg = <0x12c20000 0x10000>;
> +                       interrupts = <420>;
> +               };
> +       };
> +};
> diff --git a/arch/arm64/boot/dts/samsung-ssdk-gh7.dts b/arch/arm64/boot/dts/samsung-ssdk-gh7.dts
> new file mode 100644
> index 0000000..47afbc4
> --- /dev/null
> +++ b/arch/arm64/boot/dts/samsung-ssdk-gh7.dts
> @@ -0,0 +1,26 @@
> +/*
> + * SAMSUNG SSDK-GH7 board device tree source
> + *
> + * Copyright (c) 2014 Samsung Electronics Co., Ltd.
> + *             http://www.samsung.com
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> +*/
> +
> +/dts-v1/;
> +#include "samsung-gh7.dtsi"
> +
> +/ {
> +       model = "SAMSUNG SSDK-GH7 board based on GH7 SoC";
> +       compatible = "samsung,ssdk-gh7", "samsung,gh7";
> +
> +       chosen {
> +       };
> +
> +       memory at 80000000 {
> +               device_type = "memory";
> +               reg = <0x00000000 0x80000000 0 0x80000000>;
> +       };
> +};
> --
> 1.7.10.4
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* [PATCH 2/3] arm64: Add Kconfig option for Samsung GH7 SoC family
From: Olof Johansson @ 2014-02-11 23:39 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1392100183-30930-3-git-send-email-kgene.kim@samsung.com>

On Mon, Feb 10, 2014 at 10:29 PM, Kukjin Kim <kgene.kim@samsung.com> wrote:
> This patch adds support for Samsung GH7 SoC in arm64/Kconfig.
>
> Signed-off-by: Kukjin Kim <kgene.kim@samsung.com>
> Cc: Catalin Marinas <catalin.marinas@arm.com>

The overhead of building one more device tree isn't very large, and I
don't see any other need to have a Kconfig entry per SoC at this time.
It's of course up to Catalin, but you might just want to always
compile all dts files instead.


-Olof

^ permalink raw reply

* [PATCH] ARM: shmobile: set proper DMA masks for Ether devices
From: Sergei Shtylyov @ 2014-02-11 23:55 UTC (permalink / raw)
  To: linux-arm-kernel

Ether MAC is a DMA-capable device and so should have 'dev.dma_mask' and
'dev.coherent_dma_mask' fields set properly, to reflect 32-bit DMA addressing
ability.  Currently, the code works without DMA masks but in the future, when
support for NETIF_F_HIGHDMA & NETIF_F_SG would be added to the 'sh_eth' driver,
the DMA masks should start to matter...

Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>

---
The patch is against 'renesas-devel-v3.14-rc1-20140207' tag in Simon Horman's
'renesas.git' repo... 

 arch/arm/mach-shmobile/board-armadillo800eva.c |    2 ++
 arch/arm/mach-shmobile/board-bockw.c           |   21 ++++++++++++++-------
 arch/arm/mach-shmobile/board-genmai.c          |   19 ++++++++++++++-----
 arch/arm/mach-shmobile/board-koelsch.c         |   16 ++++++++++++----
 arch/arm/mach-shmobile/board-lager.c           |   19 ++++++++++++++-----
 5 files changed, 56 insertions(+), 21 deletions(-)

Index: renesas/arch/arm/mach-shmobile/board-armadillo800eva.c
===================================================================
--- renesas.orig/arch/arm/mach-shmobile/board-armadillo800eva.c
+++ renesas/arch/arm/mach-shmobile/board-armadillo800eva.c
@@ -383,6 +383,8 @@ static struct platform_device sh_eth_dev
 	.id = -1,
 	.dev = {
 		.platform_data = &sh_eth_platdata,
+		.dma_mask = &sh_eth_device.dev.coherent_dma_mask,
+		.coherent_dma_mask = DMA_BIT_MASK(32),
 	},
 	.resource = sh_eth_resources,
 	.num_resources = ARRAY_SIZE(sh_eth_resources),
Index: renesas/arch/arm/mach-shmobile/board-bockw.c
===================================================================
--- renesas.orig/arch/arm/mach-shmobile/board-bockw.c
+++ renesas/arch/arm/mach-shmobile/board-bockw.c
@@ -1,9 +1,9 @@
 /*
  * Bock-W board support
  *
- * Copyright (C) 2013  Renesas Solutions Corp.
+ * Copyright (C) 2013-2014  Renesas Solutions Corp.
  * Copyright (C) 2013  Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
- * Copyright (C) 2013  Cogent Embedded, Inc.
+ * Copyright (C) 2013-2014  Cogent Embedded, 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
@@ -235,6 +235,17 @@ static struct sh_eth_plat_data ether_pla
 	.no_ether_link	= 1,
 };
 
+static struct platform_device_info ether_info __initdata = {
+	.parent		= &platform_bus,
+	.name		= "r8a777x-ether",
+	.id		= -1,
+	.res		= ether_resources,
+	.num_res	= ARRAY_SIZE(ether_resources),
+	.data		= &ether_platform_data,
+	.size_data	= sizeof(ether_platform_data),
+	.dma_mask	= DMA_BIT_MASK(32),
+};
+
 /* I2C */
 static struct i2c_board_info i2c0_devices[] = {
 	{
@@ -592,11 +603,7 @@ static void __init bockw_init(void)
 	r8a7778_init_irq_extpin(1);
 	r8a7778_add_standard_devices();
 
-	platform_device_register_resndata(&platform_bus, "r8a777x-ether", -1,
-					  ether_resources,
-					  ARRAY_SIZE(ether_resources),
-					  &ether_platform_data,
-					  sizeof(ether_platform_data));
+	platform_device_register_full(&ether_info);
 
 	platform_device_register_full(&vin0_info);
 	/* VIN1 has a pin conflict with Ether */
Index: renesas/arch/arm/mach-shmobile/board-genmai.c
===================================================================
--- renesas.orig/arch/arm/mach-shmobile/board-genmai.c
+++ renesas/arch/arm/mach-shmobile/board-genmai.c
@@ -1,8 +1,9 @@
 /*
  * Genmai board support
  *
- * Copyright (C) 2013  Renesas Solutions Corp.
+ * Copyright (C) 2013-2014  Renesas Solutions Corp.
  * Copyright (C) 2013  Magnus Damm
+ * Copyright (C) 2014  Cogent Embedded, 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
@@ -43,6 +44,17 @@ static const struct resource ether_resou
 	DEFINE_RES_IRQ(gic_iid(359)),
 };
 
+static const struct platform_device_info ether_info __initconst = {
+	.parent		= &platform_bus,
+	.name		= "r7s72100-ether",
+	.id		= -1,
+	.res		= ether_resources,
+	.num_res	= ARRAY_SIZE(ether_resources),
+	.data		= &ether_pdata,
+	.size_data	= sizeof(ether_pdata),
+	.dma_mask	= DMA_BIT_MASK(32),
+};
+
 /* RSPI */
 #define RSPI_RESOURCE(idx, baseaddr, irq)				\
 static const struct resource rspi##idx##_resources[] __initconst = {	\
@@ -82,10 +94,7 @@ static void __init genmai_add_standard_d
 	r7s72100_clock_init();
 	r7s72100_add_dt_devices();
 
-	platform_device_register_resndata(&platform_bus, "r7s72100-ether", -1,
-					  ether_resources,
-					  ARRAY_SIZE(ether_resources),
-					  &ether_pdata, sizeof(ether_pdata));
+	platform_device_register_full(&ether_info);
 
 	r7s72100_register_rspi(0);
 	r7s72100_register_rspi(1);
Index: renesas/arch/arm/mach-shmobile/board-koelsch.c
===================================================================
--- renesas.orig/arch/arm/mach-shmobile/board-koelsch.c
+++ renesas/arch/arm/mach-shmobile/board-koelsch.c
@@ -109,6 +109,17 @@ static const struct resource ether_resou
 	DEFINE_RES_IRQ(gic_spi(162)),
 };
 
+static const struct platform_device_info ether_info __initconst = {
+	.parent		= &platform_bus,
+	.name		= "r8a7791-ether",
+	.id		= -1,
+	.res		= ether_resources,
+	.num_res	= ARRAY_SIZE(ether_resources),
+	.data		= &ether_pdata,
+	.size_data	= sizeof(ether_pdata),
+	.dma_mask	= DMA_BIT_MASK(32),
+};
+
 /* LEDS */
 static struct gpio_led koelsch_leds[] = {
 	{
@@ -297,10 +308,7 @@ static void __init koelsch_add_standard_
 				  ARRAY_SIZE(koelsch_pinctrl_map));
 	r8a7791_pinmux_init();
 	r8a7791_add_standard_devices();
-	platform_device_register_resndata(&platform_bus, "r8a7791-ether", -1,
-					  ether_resources,
-					  ARRAY_SIZE(ether_resources),
-					  &ether_pdata, sizeof(ether_pdata));
+	platform_device_register_full(&ether_info);
 	platform_device_register_data(&platform_bus, "leds-gpio", -1,
 				      &koelsch_leds_pdata,
 				      sizeof(koelsch_leds_pdata));
Index: renesas/arch/arm/mach-shmobile/board-lager.c
===================================================================
--- renesas.orig/arch/arm/mach-shmobile/board-lager.c
+++ renesas/arch/arm/mach-shmobile/board-lager.c
@@ -1,8 +1,9 @@
 /*
  * Lager board support
  *
- * Copyright (C) 2013  Renesas Solutions Corp.
+ * Copyright (C) 2013-2014  Renesas Solutions Corp.
  * Copyright (C) 2013  Magnus Damm
+ * Copyright (C) 2014  Cogent Embedded, 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
@@ -260,6 +261,17 @@ static const struct resource ether_resou
 	DEFINE_RES_IRQ(gic_spi(162)),
 };
 
+static const struct platform_device_info ether_info __initconst = {
+	.parent		= &platform_bus,
+	.name		= "r8a7790-ether",
+	.id		= -1,
+	.res		= ether_resources,
+	.num_res	= ARRAY_SIZE(ether_resources),
+	.data		= &ether_pdata,
+	.size_data	= sizeof(ether_pdata),
+	.dma_mask	= DMA_BIT_MASK(32),
+};
+
 /* SPI Flash memory (Spansion S25FL512SAGMFIG11 64Mb) */
 static struct mtd_partition spi_flash_part[] = {
 	/* Reserved for user loader program, read-only */
@@ -681,10 +693,7 @@ static void __init lager_add_standard_de
 					  mmcif1_resources, ARRAY_SIZE(mmcif1_resources),
 					  &mmcif1_pdata, sizeof(mmcif1_pdata));
 
-	platform_device_register_resndata(&platform_bus, "r8a7790-ether", -1,
-					  ether_resources,
-					  ARRAY_SIZE(ether_resources),
-					  &ether_pdata, sizeof(ether_pdata));
+	platform_device_register_full(&ether_info);
 
 	lager_add_du_device();
 

^ permalink raw reply

* [PATCH] ARM: SAMSUNG: remove unneeded s3c24xx_init_cpu()
From: Heiko Stübner @ 2014-02-12  0:20 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <3865198.Kyn1P03kbU@phil>

Am Sonntag, 12. Januar 2014, 21:34:29 schrieb Heiko St?bner:
> The function is nearly empty and samsung_cpu_rev is static so already 0
> making the function obsolete, therefore remove it.
> 
> Signed-off-by: Heiko Stuebner <heiko@sntech.de>

ping :-)


> ---
>  arch/arm/mach-s3c24xx/common.c           |    1 -
>  arch/arm/plat-samsung/cpu.c              |    7 -------
>  arch/arm/plat-samsung/include/plat/cpu.h |    1 -
>  3 files changed, 9 deletions(-)
> 
> diff --git a/arch/arm/mach-s3c24xx/common.c b/arch/arm/mach-s3c24xx/common.c
> index bf57d4c..97edd4d 100644
> --- a/arch/arm/mach-s3c24xx/common.c
> +++ b/arch/arm/mach-s3c24xx/common.c
> @@ -232,7 +232,6 @@ void __init s3c24xx_init_io(struct map_desc *mach_desc,
> int size) } else {
>  		samsung_cpu_id = s3c24xx_read_idcode_v4();
>  	}
> -	s3c24xx_init_cpu();
> 
>  	s3c_init_cpu(samsung_cpu_id, cpu_ids, ARRAY_SIZE(cpu_ids));
> 
> diff --git a/arch/arm/plat-samsung/cpu.c b/arch/arm/plat-samsung/cpu.c
> index 46b426e..364963a 100644
> --- a/arch/arm/plat-samsung/cpu.c
> +++ b/arch/arm/plat-samsung/cpu.c
> @@ -28,13 +28,6 @@ unsigned int samsung_rev(void)
>  }
>  EXPORT_SYMBOL(samsung_rev);
> 
> -void __init s3c24xx_init_cpu(void)
> -{
> -	/* nothing here yet */
> -
> -	samsung_cpu_rev = 0;
> -}
> -
>  void __init s3c64xx_init_cpu(void)
>  {
>  	samsung_cpu_id = __raw_readl(S3C_VA_SYS + 0x118);
> diff --git a/arch/arm/plat-samsung/include/plat/cpu.h
> b/arch/arm/plat-samsung/include/plat/cpu.h index 8f09488..262ef86 100644
> --- a/arch/arm/plat-samsung/include/plat/cpu.h
> +++ b/arch/arm/plat-samsung/include/plat/cpu.h
> @@ -207,7 +207,6 @@ extern void s5p_init_irq(u32 *vic, u32 num_vic);
> 
>  extern void s3c24xx_init_io(struct map_desc *mach_desc, int size);
> 
> -extern void s3c24xx_init_cpu(void);
>  extern void s3c64xx_init_cpu(void);
>  extern void s5p_init_cpu(void __iomem *cpuid_addr);

^ permalink raw reply

* [PATCH] ARM: SAMSUNG: remove obsolete tick.h
From: Heiko Stübner @ 2014-02-12  0:21 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <093801cf0ddc$6f8fe060$4eafa120$@kernel.org>

Am Freitag, 10. Januar 2014, 17:17:43 schrieb kgene at kernel.org:
> Heiko St?bner wrote:
> > Commit 48cf83dc12f2 (ARM: samsung: remove unused tick.h) removed some
> > occurences of tick.h. tick.h itself and s3c24xx_ostimer_pending was only
> > used by the old timer driver and is not used anymore.
> > 
> > Therefore remove the last 3 occurences.
> > 
> > Signed-off-by: Heiko Stuebner <heiko@sntech.de>
> > ---
> > 
> >  arch/arm/mach-s3c24xx/include/mach/tick.h |   15 --------------
> >  arch/arm/mach-s3c64xx/include/mach/tick.h |   31
> 
> -------------------------
> 
> > ----
> > 
> >  arch/arm/mach-s5pc100/include/mach/tick.h |   31
> 
> -------------------------
> 
> > ----
> > 
> >  3 files changed, 77 deletions(-)
> >  delete mode 100644 arch/arm/mach-s3c24xx/include/mach/tick.h
> >  delete mode 100644 arch/arm/mach-s3c64xx/include/mach/tick.h
> >  delete mode 100644 arch/arm/mach-s5pc100/include/mach/tick.h
> 
> Nice cleanup :-)
> 
> Applied, thanks,

did this make its way into your tree? Because as of now I can't see it in the 
linux-samsung.git.


Thanks
Heiko

^ permalink raw reply

* [PATCH] ARM: dts: imx6qdl-sabresd: Do not place regulator nodes under simple-bus
From: Fabio Estevam @ 2014-02-12  0:31 UTC (permalink / raw)
  To: linux-arm-kernel

From: Fabio Estevam <fabio.estevam@freescale.com>

According to Documentation/devicetree/bindings/regulator/regulator.txt 
regulator nodes should not be placed under 'simple-bus'.

Mark Rutland also explains about it at:
http://www.spinics.net/lists/linux-usb/msg101497.html 
 
Signed-off-by: Fabio Estevam <fabio.estevam@freescale.com>
---
Shawn,

I can convert other dts files if you are fine with this approach.

 arch/arm/boot/dts/imx6qdl-sabresd.dtsi | 51 ++++++++++++++--------------------
 1 file changed, 21 insertions(+), 30 deletions(-)

diff --git a/arch/arm/boot/dts/imx6qdl-sabresd.dtsi b/arch/arm/boot/dts/imx6qdl-sabresd.dtsi
index 0d816d3..d7df5b2 100644
--- a/arch/arm/boot/dts/imx6qdl-sabresd.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-sabresd.dtsi
@@ -18,38 +18,29 @@
 		reg = <0x10000000 0x40000000>;
 	};
 
-	regulators {
-		compatible = "simple-bus";
-		#address-cells = <1>;
-		#size-cells = <0>;
-
-		reg_usb_otg_vbus: regulator at 0 {
-			compatible = "regulator-fixed";
-			reg = <0>;
-			regulator-name = "usb_otg_vbus";
-			regulator-min-microvolt = <5000000>;
-			regulator-max-microvolt = <5000000>;
-			gpio = <&gpio3 22 0>;
-			enable-active-high;
-		};
+	reg_usb_otg_vbus: regulator at 0 {
+		compatible = "regulator-fixed";
+		regulator-name = "usb_otg_vbus";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		gpio = <&gpio3 22 0>;
+		enable-active-high;
+	};
 
-		reg_usb_h1_vbus: regulator at 1 {
-			compatible = "regulator-fixed";
-			reg = <1>;
-			regulator-name = "usb_h1_vbus";
-			regulator-min-microvolt = <5000000>;
-			regulator-max-microvolt = <5000000>;
-			gpio = <&gpio1 29 0>;
-			enable-active-high;
-		};
+	reg_usb_h1_vbus: regulator at 1 {
+		compatible = "regulator-fixed";
+		regulator-name = "usb_h1_vbus";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		gpio = <&gpio1 29 0>;
+		enable-active-high;
+	};
 
-		reg_audio: regulator at 2 {
-			compatible = "regulator-fixed";
-			reg = <2>;
-			regulator-name = "wm8962-supply";
-			gpio = <&gpio4 10 0>;
-			enable-active-high;
-		};
+	reg_audio: regulator at 2 {
+		compatible = "regulator-fixed";
+		regulator-name = "wm8962-supply";
+		gpio = <&gpio4 10 0>;
+		enable-active-high;
 	};
 
 	gpio-keys {
-- 
1.8.1.2

^ permalink raw reply related

* [PATCH 1/3] ARM: bios32: use pci_enable_resource to enable PCI resources
From: Bjorn Helgaas @ 2014-02-12  1:06 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1391532784-1953-2-git-send-email-will.deacon@arm.com>

On Tue, Feb 04, 2014 at 04:53:02PM +0000, Will Deacon wrote:
> This patch moves bios32 over to using the generic code for enabling PCI
> resources. All that's left to take care of is the case of PCI bridges,
> which need to be enabled for both IO and MEMORY, regardless of the
> resource types.
> 
> A side-effect of this change is that we no longer explicitly enable
> devices when running in PCI_PROBE_ONLY mode. This stays closer to the
> meaning of the option and prevents us from trying to enable devices
> without any assigned resources (the core code refuses to enable
> resources without parents).

Heh, I've been looking at this, too :)  I have a similar patch for ARM and
other architectures with their own versions of pcibios_enable_device().

Several of them (arm m68k tile tegra unicore32) have this special code that
enables IO and MEMORY for bridges unconditionally.  But from a PCI
perspective, I don't know why we should do this unconditionally.  If a
bridge doesn't have an enabled MEM window or MEM BAR, I don't think we
should have to enable PCI_COMMAND_MEMORY for it.

The architectures that do this only check for valid MEM BARs, i.e., they
only look at resources 0-5, and they don't look at the window resources.

The architectures that don't enable IO and MEMORY for bridges
unconditionally check *all* the resources up to PCI_NUM_RESOURCES, which
includes the BARs, bridge windows, and any IOV resources.

The generic pci_enable_resources() does check all the resources, so I
*think* it should be safe for all architectures to use that and just drop
the check for bridges.  What do you think?

Bjorn

> Signed-off-by: Will Deacon <will.deacon@arm.com>
> ---
>  arch/arm/kernel/bios32.c | 35 ++++++++++-------------------------
>  1 file changed, 10 insertions(+), 25 deletions(-)
> 
> diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c
> index 317da88ae65b..9f3c76638689 100644
> --- a/arch/arm/kernel/bios32.c
> +++ b/arch/arm/kernel/bios32.c
> @@ -608,40 +608,25 @@ resource_size_t pcibios_align_resource(void *data, const struct resource *res,
>   */
>  int pcibios_enable_device(struct pci_dev *dev, int mask)
>  {
> -	u16 cmd, old_cmd;
> -	int idx;
> -	struct resource *r;
> +	int err;
> +	u16 cmd;
>  
> -	pci_read_config_word(dev, PCI_COMMAND, &cmd);
> -	old_cmd = cmd;
> -	for (idx = 0; idx < 6; idx++) {
> -		/* Only set up the requested stuff */
> -		if (!(mask & (1 << idx)))
> -			continue;
> +	if (pci_has_flag(PCI_PROBE_ONLY))
> +		return 0;
>  
> -		r = dev->resource + idx;
> -		if (!r->start && r->end) {
> -			printk(KERN_ERR "PCI: Device %s not available because"
> -			       " of resource collisions\n", pci_name(dev));
> -			return -EINVAL;
> -		}
> -		if (r->flags & IORESOURCE_IO)
> -			cmd |= PCI_COMMAND_IO;
> -		if (r->flags & IORESOURCE_MEM)
> -			cmd |= PCI_COMMAND_MEMORY;
> -	}
> +	err = pci_enable_resources(dev, mask);
> +	if (err)
> +		return err;
>  
>  	/*
>  	 * Bridges (eg, cardbus bridges) need to be fully enabled
>  	 */
> -	if ((dev->class >> 16) == PCI_BASE_CLASS_BRIDGE)
> +	if ((dev->class >> 16) == PCI_BASE_CLASS_BRIDGE) {
> +		pci_read_config_word(dev, PCI_COMMAND, &cmd);
>  		cmd |= PCI_COMMAND_IO | PCI_COMMAND_MEMORY;
> -
> -	if (cmd != old_cmd) {
> -		printk("PCI: enabling device %s (%04x -> %04x)\n",
> -		       pci_name(dev), old_cmd, cmd);
>  		pci_write_config_word(dev, PCI_COMMAND, cmd);
>  	}
> +
>  	return 0;
>  }
>  
> -- 
> 1.8.2.2
> 

^ permalink raw reply

* [PATCH RESEND] ARM: LPC32xx: common.c: Remove unnecessary header inclusion
From: Jingoo Han @ 2014-02-12  1:17 UTC (permalink / raw)
  To: linux-arm-kernel

common.c includes some header files that are not really used.

Signed-off-by: Jingoo Han <jg1.han@samsung.com>
---
Compile-tested only.

 arch/arm/mach-lpc32xx/common.c |    6 ------
 1 file changed, 6 deletions(-)

diff --git a/arch/arm/mach-lpc32xx/common.c b/arch/arm/mach-lpc32xx/common.c
index d7aa54c..9713c8b 100644
--- a/arch/arm/mach-lpc32xx/common.c
+++ b/arch/arm/mach-lpc32xx/common.c
@@ -17,12 +17,6 @@
  */
 
 #include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/err.h>
-#include <linux/i2c.h>
-#include <linux/i2c-pnx.h>
 #include <linux/io.h>
 
 #include <asm/mach/map.h>
-- 
1.7.10.4

^ permalink raw reply related

* [RFC/PATCH 0/3] Add devicetree scanning for randomness
From: Laura Abbott @ 2014-02-12  1:33 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

This is an RFC to seed the random number pool earlier when using devicetree.
The big issue this is trying to solve is the fact that the stack canary for
ARM tends to be the same across bootups of the same device. This is because
the random number pools do not get initialized until after the canary has
been set up. The canary can be moved later, but in general there is still
no way to reliably get random numbers early for other features (e.g. vector
randomization).

The goal here is to allow devices to add to the random pools via
add_device_randomness or some other method of their chosing at FDT time.
I realize that ARCH_RANDOM is already available but this didn't work because
1) ARCH_RANDOM is not multi-platform compatible without added
infrastructure to ARM
2) There is no uniform way to generate the random numbers which
would require an additional framework (same result as #1, different
reasons)
3) Given there is no uniform way to generate the random numbers, it seems
unlikely that 'early' random numbers would work the same as 'non-early'
random number which adds another layer of complexity.

The big reason to skip ARCH_RANDOM though is that the random number generation
we have would be reasonable if only seeded earlier.

Thanks,
Laura


Laura Abbott (3):
  of: Add early randomness hooks
  arm: Add ARCH_WANT_OF_RANDOMNESS
  init: Move stack canary initialization after setup_arch

 arch/arm/Kconfig                  |    3 ++
 arch/arm/kernel/vmlinux.lds.S     |    1 +
 drivers/of/Kconfig                |    7 ++++++
 drivers/of/Makefile               |    1 +
 drivers/of/fdt.c                  |    7 ++++++
 drivers/of/of_randomness.c        |   43 +++++++++++++++++++++++++++++++++++++
 include/asm-generic/vmlinux.lds.h |    5 ++++
 include/linux/of_randomness.h     |   42 ++++++++++++++++++++++++++++++++++++
 init/main.c                       |    9 +++----
 9 files changed, 113 insertions(+), 5 deletions(-)
 create mode 100644 drivers/of/of_randomness.c
 create mode 100644 include/linux/of_randomness.h

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation

^ permalink raw reply

* [RFC/PATCH 1/3] of: Add early randomness hooks
From: Laura Abbott @ 2014-02-12  1:33 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1392168805-14200-1-git-send-email-lauraa@codeaurora.org>

Until randomness is added to the kernel's pools, random
numbers returned may not be truly 'random'. Randomness comes
from a variety of sources in the kernel but much of the
randomness comes from device related initialization. This
means that any random numbers that are needed before drivers
are initialized (e.g. stack canary) may not be truely random.
Fix this by build a list of functions that can be used to add
randomness to the kernel's pools very early. The functions are
tied to particular compatible strings of devicetree nodes. The
flattened devicetree is scanned and if the node is present the
function is called. Note that this must happen on the flattened
devicetree to ensure the randomness gets added to the pool
early enough to make a difference.

Signed-off-by: Laura Abbott <lauraa@codeaurora.org>
---
 drivers/of/Kconfig                |    7 ++++++
 drivers/of/Makefile               |    1 +
 drivers/of/fdt.c                  |    7 ++++++
 drivers/of/of_randomness.c        |   43 +++++++++++++++++++++++++++++++++++++
 include/asm-generic/vmlinux.lds.h |    5 ++++
 include/linux/of_randomness.h     |   42 ++++++++++++++++++++++++++++++++++++
 6 files changed, 105 insertions(+), 0 deletions(-)
 create mode 100644 drivers/of/of_randomness.c
 create mode 100644 include/linux/of_randomness.h

diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
index c6973f1..6ae4a38 100644
--- a/drivers/of/Kconfig
+++ b/drivers/of/Kconfig
@@ -75,4 +75,11 @@ config OF_MTD
 	depends on MTD
 	def_bool y
 
+config OF_RANDOMNESS
+	def_bool n
+	depends on OF_FLATTREE && ARCH_WANT_OF_RANDOMNESS
+        help
+	  OpenFirmware hooks to scan for device randomness
+	  via flat devicetree
+
 endmenu # OF
diff --git a/drivers/of/Makefile b/drivers/of/Makefile
index efd0510..0ce02d1 100644
--- a/drivers/of/Makefile
+++ b/drivers/of/Makefile
@@ -9,3 +9,4 @@ obj-$(CONFIG_OF_MDIO)	+= of_mdio.o
 obj-$(CONFIG_OF_PCI)	+= of_pci.o
 obj-$(CONFIG_OF_PCI_IRQ)  += of_pci_irq.o
 obj-$(CONFIG_OF_MTD)	+= of_mtd.o
+obj-$(CONFIG_OF_RANDOMNESS)	+= of_randomness.o
diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index 758b4f8..c25960e 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -15,6 +15,7 @@
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/of_fdt.h>
+#include <linux/of_randomness.h>
 #include <linux/string.h>
 #include <linux/errno.h>
 #include <linux/slab.h>
@@ -889,6 +890,12 @@ bool __init early_init_dt_scan(void *params)
 	/* Setup memory, calling early_init_dt_add_memory_arch */
 	of_scan_flat_dt(early_init_dt_scan_memory, NULL);
 
+#ifdef CONFIG_OF_RANDOMNESS
+	/* Add device randomness */
+	of_scan_flat_dt(early_init_dt_scan_early_randomness, NULL);
+#endif
+
+
 	return true;
 }
 
diff --git a/drivers/of/of_randomness.c b/drivers/of/of_randomness.c
new file mode 100644
index 0000000..9d23624
--- /dev/null
+++ b/drivers/of/of_randomness.c
@@ -0,0 +1,43 @@
+/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 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.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/random.h>
+#include <linux/string.h>
+#include <linux/of_randomness.h>
+#include <linux/of_fdt.h>
+
+int __init early_init_dt_scan_early_randomness(unsigned long node,
+					const char *uname,
+					int depth, void *data)
+{
+	struct early_random_func *f;
+	void *prop;
+	unsigned long len;
+
+	prop = of_get_flat_dt_prop(node, "compatible", &len);
+
+	if (!prop)
+		return 0;
+
+	for (f = __early_random_funcs_start;
+	     f < __early_random_funcs_end;
+	     f++) {
+		pr_debug("Check compat %s addr %p against %s\n",
+			f->compat_string, f->add_randomness, (char *)prop);
+		if (strcmp(prop, f->compat_string) == 0)
+			f->add_randomness(node);
+	}
+
+	return 0;
+}
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index bc2121f..e5b8be9 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -645,6 +645,11 @@
 		*(.security_initcall.init)				\
 		VMLINUX_SYMBOL(__security_initcall_end) = .;
 
+#define EARLY_RANDOM_FUNCS						\
+		VMLINUX_SYMBOL(__early_random_funcs_start) = .;		\
+		*(.earlyrandom.init)					\
+		VMLINUX_SYMBOL(__early_random_funcs_end) = .;
+
 #ifdef CONFIG_BLK_DEV_INITRD
 #define INIT_RAM_FS							\
 	. = ALIGN(4);							\
diff --git a/include/linux/of_randomness.h b/include/linux/of_randomness.h
new file mode 100644
index 0000000..b8b4532
--- /dev/null
+++ b/include/linux/of_randomness.h
@@ -0,0 +1,42 @@
+/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 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.
+ *
+ */
+#ifndef LINUX_OF_RANDOMNESS_H
+#define LINUX_OF_RANDOMNESS_H
+
+extern int early_init_dt_scan_early_randomness(unsigned long node,
+					  const char *uname,
+					  int depth, void *data);
+
+#ifdef CONFIG_OF_RANDOMNESS
+
+struct early_random_func {
+	char *compat_string;
+	void (*add_randomness)(unsigned long fdt_node);
+};
+
+extern struct early_random_func __early_random_funcs_start[];
+extern struct early_random_func __early_random_funcs_end[];
+
+#define EARLY_RANDOM_FUNC(c, f)    \
+static struct early_random_func __early_rand##f __used \
+	__attribute((__section__(".earlyrandom.init"))) = { \
+		.compat_string = c, \
+		.add_randomness = f\
+	} \
+
+#else
+
+#define EARLY_RANDOM_FUNC(f, e)
+#endif
+
+#endif
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation

^ permalink raw reply related

* [RFC/PATCH 2/3] arm: Add ARCH_WANT_OF_RANDOMNESS
From: Laura Abbott @ 2014-02-12  1:33 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1392168805-14200-1-git-send-email-lauraa@codeaurora.org>

The stack canary for ARM is currently the same across reboots
due to lack of randomness early enough. Add ARCH_WANT_OF_RANDOMNESS
to allow devices to add whatever randomness they need.

Signed-off-by: Laura Abbott <lauraa@codeaurora.org>
---
 arch/arm/Kconfig              |    3 +++
 arch/arm/kernel/vmlinux.lds.S |    1 +
 2 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index e254198..7ab0db1 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -222,6 +222,9 @@ config NEED_RET_TO_USER
 config ARCH_MTD_XIP
 	bool
 
+config ARCH_WANT_OF_RANDOMNESS
+	def_bool n
+
 config VECTORS_BASE
 	hex
 	default 0xffff0000 if MMU || CPU_HIGH_VECTOR
diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S
index 7bcee5c..2198258 100644
--- a/arch/arm/kernel/vmlinux.lds.S
+++ b/arch/arm/kernel/vmlinux.lds.S
@@ -202,6 +202,7 @@ SECTIONS
 		INIT_SETUP(16)
 		INIT_CALLS
 		CON_INITCALL
+		EARLY_RANDOM_FUNCS
 		SECURITY_INITCALL
 		INIT_RAM_FS
 	}
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox