diff mbox

[RFC,00/16] Consolidation: move SMP local timers to driver/clocksource

Message ID 4E007CEB.6040104@arm.com (mailing list archive)
State New, archived
Headers show

Commit Message

Marc Zyngier June 21, 2011, 11:13 a.m. UTC
On 17/06/11 18:25, Rob Herring wrote:
> Also, device tree support for early platform devices would be useful for
> this.

What about the attached patch? I've used it to boot a VExpress board
with the following DT snippet (and the corresponding support in the
amp_smp_twd driver):

	localtimer@2c000600 {
		device_type = "localtimer";
		compatible = "arm,smp-twd";
		reg = <0x2c000600 0x1000>;
		interrupts = <29>;
	};

Cheers,

	M.

Comments

Rob Herring June 21, 2011, 12:51 p.m. UTC | #1
Marc,

On 06/21/2011 06:13 AM, Marc Zyngier wrote:
> On 17/06/11 18:25, Rob Herring wrote:
>> Also, device tree support for early platform devices would be useful for
>> this.
> 
> What about the attached patch? I've used it to boot a VExpress board
> with the following DT snippet (and the corresponding support in the
> amp_smp_twd driver):
> 
> 	localtimer@2c000600 {
> 		device_type = "localtimer";

My understanding is device_type is only supposed to be used for devices
with real OpenFirmware. You could just add localtimer or timer as a 2nd
compatible string. I think localtimer is a bit of a Linux name, so just
timer may be better.

Rob

> 		compatible = "arm,smp-twd";
> 		reg = <0x2c000600 0x1000>;
> 		interrupts = <29>;
> 	};
> 
> Cheers,
> 
> 	M.
Marc Zyngier June 21, 2011, 1:02 p.m. UTC | #2
On 21/06/11 13:51, Rob Herring wrote:
> Marc,
> 
> On 06/21/2011 06:13 AM, Marc Zyngier wrote:
>> On 17/06/11 18:25, Rob Herring wrote:
>>> Also, device tree support for early platform devices would be useful for
>>> this.
>>
>> What about the attached patch? I've used it to boot a VExpress board
>> with the following DT snippet (and the corresponding support in the
>> amp_smp_twd driver):
>>
>> 	localtimer@2c000600 {
>> 		device_type = "localtimer";
> 
> My understanding is device_type is only supposed to be used for devices
> with real OpenFirmware. You could just add localtimer or timer as a 2nd
> compatible string. I think localtimer is a bit of a Linux name, so just
> timer may be better.

Using "compatible" would not work. You'd have to add the same compatible
string to all drivers, and get drivers probing the wrong device. Any
other property we could use instead?

As for the "localtimer" string, this is to differentiate the per-cpu
timers versus the global timers, and they may need to be probed in a
specific order (global first, and then local).

The reason for this is that TWD needs to be calibrated, hence the need
for a global timer running. Colin's patch could help getting rid of this
restriction though.

	M.
Rob Herring June 21, 2011, 1:18 p.m. UTC | #3
On 06/21/2011 08:02 AM, Marc Zyngier wrote:
> On 21/06/11 13:51, Rob Herring wrote:
>> Marc,
>>
>> On 06/21/2011 06:13 AM, Marc Zyngier wrote:
>>> On 17/06/11 18:25, Rob Herring wrote:
>>>> Also, device tree support for early platform devices would be useful for
>>>> this.
>>>
>>> What about the attached patch? I've used it to boot a VExpress board
>>> with the following DT snippet (and the corresponding support in the
>>> amp_smp_twd driver):
>>>
>>> 	localtimer@2c000600 {
>>> 		device_type = "localtimer";
>>
>> My understanding is device_type is only supposed to be used for devices
>> with real OpenFirmware. You could just add localtimer or timer as a 2nd
>> compatible string. I think localtimer is a bit of a Linux name, so just
>> timer may be better.
> 
> Using "compatible" would not work. You'd have to add the same compatible
> string to all drivers, and get drivers probing the wrong device. Any
> other property we could use instead?

No, I'm saying you have a compatible property like this:

compatible = "arm,smp-twd", "timer";

You create the early platform device(s) based on matches with "timer",
but match the driver based on "arm,smp-twd".

> 
> As for the "localtimer" string, this is to differentiate the per-cpu
> timers versus the global timers, and they may need to be probed in a
> specific order (global first, and then local).
> 
> The reason for this is that TWD needs to be calibrated, hence the need
> for a global timer running. Colin's patch could help getting rid of this
> restriction though.

Yes, my original patch adding clock api allowed just that.

Rob

> 
> 	M.
diff mbox

Patch

From b707a3a80f51c7a5a30b97d33b8b637f318cf886 Mon Sep 17 00:00:00 2001
From: Marc Zyngier <marc.zyngier@arm.com>
Date: Tue, 21 Jun 2011 11:40:51 +0100
Subject: [PATCH] dt: early platform devices support

Add support for populating early platform devices from the device
tree, by walking the tree and adding nodes whose 'device_type'
property matches the 'class' string passed as a parameter.

This allows devices to be probed long before the whole device
insfrastructure is available.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 drivers/of/platform.c       |   31 +++++++++++++++++++++++++++++++
 include/linux/of_platform.h |    2 ++
 2 files changed, 33 insertions(+), 0 deletions(-)

diff --git a/drivers/of/platform.c b/drivers/of/platform.c
index 9b785be..976a9ea 100644
--- a/drivers/of/platform.c
+++ b/drivers/of/platform.c
@@ -326,4 +326,35 @@  int of_platform_populate(struct device_node *root,
 	of_node_put(root);
 	return rc;
 }
+
+/**
+ * of_early_platform_populate() - Populate early platform devices from DT
+ * @class: string matching the device type to register
+ *
+ * This function walks the device tree and register devices whose
+ * 'device_type' property matches the 'class' parameter.
+ *
+ * Returns 0 on success, < 0 on failure.
+ */
+int of_early_platform_populate(const char *class)
+{
+	struct platform_device *pdev;
+	struct device_node *np = NULL;
+	int id = 0, rc = 0;
+
+	while ((np = of_find_node_by_type(np, class))) {
+		pdev = kzalloc(sizeof(*pdev), GFP_KERNEL);
+		if (!pdev) {
+			of_node_put(np);
+			rc = -ENOMEM;
+			break;
+		}
+		pdev->name = np->name;
+		pdev->id = id++;
+		pdev->dev.of_node = of_node_get(np);
+		early_platform_add_devices(&pdev, 1);
+	}
+
+	return rc;
+}
 #endif /* !CONFIG_SPARC */
diff --git a/include/linux/of_platform.h b/include/linux/of_platform.h
index 43c723d..fee17f7 100644
--- a/include/linux/of_platform.h
+++ b/include/linux/of_platform.h
@@ -58,6 +58,8 @@  extern int of_platform_bus_probe(struct device_node *root,
 extern int of_platform_populate(struct device_node *root,
 				const struct of_device_id *matches,
 				struct device *parent);
+
+extern int of_early_platform_populate(const char *class);
 #endif /* !CONFIG_SPARC */
 
 #endif /* CONFIG_OF_DEVICE */
-- 
1.7.0.4