sunxi: initial 3.14 patchset
[openwrt/openwrt.git] / target / linux / sunxi / patches-3.14 / 175-reset-add-of_reset_control_get.patch
diff --git a/target/linux/sunxi/patches-3.14/175-reset-add-of_reset_control_get.patch b/target/linux/sunxi/patches-3.14/175-reset-add-of_reset_control_get.patch
new file mode 100644 (file)
index 0000000..7bf9511
--- /dev/null
@@ -0,0 +1,119 @@
+From bfea2b9be28b20e076d5df8863c25e966f413fa3 Mon Sep 17 00:00:00 2001
+From: Maxime Ripard <maxime.ripard@free-electrons.com>
+Date: Fri, 20 Dec 2013 22:41:07 +0100
+Subject: [PATCH] reset: Add of_reset_control_get
+
+In some cases, you might need to deassert from reset an hardware block that
+doesn't associated to a struct device (CPUs, timers, etc.).
+
+Add a small helper to retrieve the reset controller from the device tree
+without the need to pass a struct device.
+
+Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
+---
+ drivers/reset/core.c  | 39 ++++++++++++++++++++++++++++++---------
+ include/linux/reset.h |  4 ++++
+ 2 files changed, 34 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/reset/core.c b/drivers/reset/core.c
+index d1b6089..4f3dda7 100644
+--- a/drivers/reset/core.c
++++ b/drivers/reset/core.c
+@@ -127,15 +127,16 @@ int reset_control_deassert(struct reset_control *rstc)
+ EXPORT_SYMBOL_GPL(reset_control_deassert);
+ /**
+- * reset_control_get - Lookup and obtain a reference to a reset controller.
+- * @dev: device to be reset by the controller
++ * of_reset_control_get - Lookup and obtain a reference to a reset controller.
++ * @node: device to be reset by the controller
+  * @id: reset line name
+  *
+  * Returns a struct reset_control or IS_ERR() condition containing errno.
+  *
+  * Use of id names is optional.
+  */
+-struct reset_control *reset_control_get(struct device *dev, const char *id)
++struct reset_control *of_reset_control_get(struct device_node *node,
++                                         const char *id)
+ {
+       struct reset_control *rstc = ERR_PTR(-EPROBE_DEFER);
+       struct reset_controller_dev *r, *rcdev;
+@@ -144,13 +145,10 @@ struct reset_control *reset_control_get(struct device *dev, const char *id)
+       int rstc_id;
+       int ret;
+-      if (!dev)
+-              return ERR_PTR(-EINVAL);
+-
+       if (id)
+-              index = of_property_match_string(dev->of_node,
++              index = of_property_match_string(node,
+                                                "reset-names", id);
+-      ret = of_parse_phandle_with_args(dev->of_node, "resets", "#reset-cells",
++      ret = of_parse_phandle_with_args(node, "resets", "#reset-cells",
+                                        index, &args);
+       if (ret)
+               return ERR_PTR(ret);
+@@ -185,12 +183,35 @@ struct reset_control *reset_control_get(struct device *dev, const char *id)
+               return ERR_PTR(-ENOMEM);
+       }
+-      rstc->dev = dev;
+       rstc->rcdev = rcdev;
+       rstc->id = rstc_id;
+       return rstc;
+ }
++EXPORT_SYMBOL_GPL(of_reset_control_get);
++
++/**
++ * reset_control_get - Lookup and obtain a reference to a reset controller.
++ * @dev: device to be reset by the controller
++ * @id: reset line name
++ *
++ * Returns a struct reset_control or IS_ERR() condition containing errno.
++ *
++ * Use of id names is optional.
++ */
++struct reset_control *reset_control_get(struct device *dev, const char *id)
++{
++      struct reset_control *rstc;
++
++      if (!dev)
++              return ERR_PTR(-EINVAL);
++
++      rstc = of_reset_control_get(dev->of_node, id);
++      if (!IS_ERR(rstc))
++              rstc->dev = dev;
++
++      return rstc;
++}
+ EXPORT_SYMBOL_GPL(reset_control_get);
+ /**
+diff --git a/include/linux/reset.h b/include/linux/reset.h
+index 6082247..a398025 100644
+--- a/include/linux/reset.h
++++ b/include/linux/reset.h
+@@ -1,6 +1,8 @@
+ #ifndef _LINUX_RESET_H_
+ #define _LINUX_RESET_H_
++#include <linux/of.h>
++
+ struct device;
+ struct reset_control;
+@@ -8,6 +10,8 @@ int reset_control_reset(struct reset_control *rstc);
+ int reset_control_assert(struct reset_control *rstc);
+ int reset_control_deassert(struct reset_control *rstc);
++struct reset_control *of_reset_control_get(struct device_node *node,
++                                         const char *id);
+ struct reset_control *reset_control_get(struct device *dev, const char *id);
+ void reset_control_put(struct reset_control *rstc);
+ struct reset_control *devm_reset_control_get(struct device *dev, const char *id);
+-- 
+2.0.3
+