From c62801458ada07c2dd6a168f468d087dcb7fcb3c Mon Sep 17 00:00:00 2001
From: Philippe Proulx <philippe.proulx@savoirfairelinux.com>
Date: Fri, 13 Sep 2013 14:33:35 -0400
Subject: [PATCH] ARM: omap: add DT support for deasserting hardware reset
 lines

 Original author of this patch's code is:

     Matt Ranostay <mranostay@gmail.com>

     This optional binding extension allows specification of a hwmod
     and associate hardware reset line which should be deasserted for
     the device to be functional.

     The implementation works but is suboptimal. The problem is that this
     deassertion occurs before clocks are enabled and we are warned that the
     hard reset failed. Ideally the list of reset lines requested to be
     deasserted would be cached and used within the hwmod enable sequencing
     (instead of it just returning if any hardware reset line is asserted).

     This reset line deassertion step is required to use the PRU-ICSS on
     AM335x boards.
---
 Documentation/devicetree/bindings/arm/omap/omap.txt |    2 +
 arch/arm/mach-omap2/omap_device.c                   |   25 ++++++++++++++++++--
 2 files changed, 25 insertions(+), 2 deletions(-)

Index: linux-3.12.24-rt38-r7s5/Documentation/devicetree/bindings/arm/omap/omap.txt
===================================================================
--- linux-3.12.24-rt38-r7s5.orig/Documentation/devicetree/bindings/arm/omap/omap.txt
+++ linux-3.12.24-rt38-r7s5/Documentation/devicetree/bindings/arm/omap/omap.txt
@@ -21,6 +21,8 @@ Required properties:
 Optional properties:
 - ti,no_idle_on_suspend: When present, it prevents the PM to idle the module
   during suspend.
+- ti,deassert-hard-reset: list of hwmod and hardware reset line name pairs
+  (ascii strings) to be deasserted upon device instantiation.
 
 
 Example:
Index: linux-3.12.24-rt38-r7s5/arch/arm/mach-omap2/omap_device.c
===================================================================
--- linux-3.12.24-rt38-r7s5.orig/arch/arm/mach-omap2/omap_device.c
+++ linux-3.12.24-rt38-r7s5/arch/arm/mach-omap2/omap_device.c
@@ -127,8 +127,8 @@ static int omap_device_build_from_dt(str
 	struct omap_device *od;
 	struct omap_hwmod *oh;
 	struct device_node *node = pdev->dev.of_node;
-	const char *oh_name;
-	int oh_cnt, i, ret = 0;
+	const char *oh_name, *rst_name;
+	int oh_cnt, dstr_cnt, i, ret = 0;
 	bool device_active = false;
 
 	oh_cnt = of_property_count_strings(node, "ti,hwmods");
@@ -180,6 +180,27 @@ static int omap_device_build_from_dt(str
 		pm_runtime_set_active(&pdev->dev);
 	}
 
+	dstr_cnt =
+		of_property_count_strings(node, "ti,deassert-hard-reset");
+	if (dstr_cnt > 0) {
+		for (i = 0; i < dstr_cnt; i += 2) {
+			of_property_read_string_index(
+				node, "ti,deassert-hard-reset", i,
+				&oh_name);
+			of_property_read_string_index(
+				node, "ti,deassert-hard-reset", i+1,
+				&rst_name);
+			oh = omap_hwmod_lookup(oh_name);
+			if (!oh) {
+				dev_warn(&pdev->dev,
+				"Cannot parse deassert property for '%s'\n",
+				oh_name);
+				break;
+			}
+			omap_hwmod_deassert_hardreset(oh, rst_name);
+		}
+	}
+
 odbfd_exit1:
 	kfree(hwmods);
 odbfd_exit: