diff options
Diffstat (limited to 'target/linux/ramips/patches-3.8/0067-reset-Add-reset-controller-API.patch')
-rw-r--r-- | target/linux/ramips/patches-3.8/0067-reset-Add-reset-controller-API.patch | 554 |
1 files changed, 0 insertions, 554 deletions
diff --git a/target/linux/ramips/patches-3.8/0067-reset-Add-reset-controller-API.patch b/target/linux/ramips/patches-3.8/0067-reset-Add-reset-controller-API.patch deleted file mode 100644 index 55bbb56d00..0000000000 --- a/target/linux/ramips/patches-3.8/0067-reset-Add-reset-controller-API.patch +++ /dev/null @@ -1,554 +0,0 @@ -From 8951e08252c6c254d68c350468c40f88a12bcc1d Mon Sep 17 00:00:00 2001 -From: John Crispin <blogic@openwrt.org> -Date: Mon, 20 May 2013 15:42:01 +0200 -Subject: [PATCH 67/79] reset: Add reset controller API - -backport from v3.10-rc1 -61fc41317666be400802ac793f47de816ef7bd57 -6034bb22d8387708075c083385e5d2e1072a4f33 -4e11f848c65b1c87782cb232a6e3b47a9d4c1f98 - -This adds a simple API for devices to request being reset -by separate reset controller hardware and implements the -reset signal device tree binding. - -Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de> -Reviewed-by: Stephen Warren <swarren@nvidia.com> -Reviewed-by: Shawn Guo <shawn.guo@linaro.org> -Reviewed-by: Marek Vasut <marex@denx.de> -Reviewed-by: Pavel Machek <pavel@ucw.cz> ---- - Documentation/devicetree/bindings/reset/reset.txt | 75 ++++++ - drivers/Kconfig | 2 + - drivers/Makefile | 3 + - drivers/reset/Kconfig | 13 + - drivers/reset/Makefile | 1 + - drivers/reset/core.c | 297 +++++++++++++++++++++ - include/linux/reset-controller.h | 51 ++++ - include/linux/reset.h | 17 ++ - 8 files changed, 459 insertions(+) - create mode 100644 Documentation/devicetree/bindings/reset/reset.txt - create mode 100644 drivers/reset/Kconfig - create mode 100644 drivers/reset/Makefile - create mode 100644 drivers/reset/core.c - create mode 100644 include/linux/reset-controller.h - create mode 100644 include/linux/reset.h - -diff --git a/Documentation/devicetree/bindings/reset/reset.txt b/Documentation/devicetree/bindings/reset/reset.txt -new file mode 100644 -index 0000000..31db6ff ---- /dev/null -+++ b/Documentation/devicetree/bindings/reset/reset.txt -@@ -0,0 +1,75 @@ -+= Reset Signal Device Tree Bindings = -+ -+This binding is intended to represent the hardware reset signals present -+internally in most IC (SoC, FPGA, ...) designs. Reset signals for whole -+standalone chips are most likely better represented as GPIOs, although there -+are likely to be exceptions to this rule. -+ -+Hardware blocks typically receive a reset signal. This signal is generated by -+a reset provider (e.g. power management or clock module) and received by a -+reset consumer (the module being reset, or a module managing when a sub- -+ordinate module is reset). This binding exists to represent the provider and -+consumer, and provide a way to couple the two together. -+ -+A reset signal is represented by the phandle of the provider, plus a reset -+specifier - a list of DT cells that represents the reset signal within the -+provider. The length (number of cells) and semantics of the reset specifier -+are dictated by the binding of the reset provider, although common schemes -+are described below. -+ -+A word on where to place reset signal consumers in device tree: It is possible -+in hardware for a reset signal to affect multiple logically separate HW blocks -+at once. In this case, it would be unwise to represent this reset signal in -+the DT node of each affected HW block, since if activated, an unrelated block -+may be reset. Instead, reset signals should be represented in the DT node -+where it makes most sense to control it; this may be a bus node if all -+children of the bus are affected by the reset signal, or an individual HW -+block node for dedicated reset signals. The intent of this binding is to give -+appropriate software access to the reset signals in order to manage the HW, -+rather than to slavishly enumerate the reset signal that affects each HW -+block. -+ -+= Reset providers = -+ -+Required properties: -+#reset-cells: Number of cells in a reset specifier; Typically 0 for nodes -+ with a single reset output and 1 for nodes with multiple -+ reset outputs. -+ -+For example: -+ -+ rst: reset-controller { -+ #reset-cells = <1>; -+ }; -+ -+= Reset consumers = -+ -+Required properties: -+resets: List of phandle and reset specifier pairs, one pair -+ for each reset signal that affects the device, or that the -+ device manages. Note: if the reset provider specifies '0' for -+ #reset-cells, then only the phandle portion of the pair will -+ appear. -+ -+Optional properties: -+reset-names: List of reset signal name strings sorted in the same order as -+ the resets property. Consumers drivers will use reset-names to -+ match reset signal names with reset specifiers. -+ -+For example: -+ -+ device { -+ resets = <&rst 20>; -+ reset-names = "reset"; -+ }; -+ -+This represents a device with a single reset signal named "reset". -+ -+ bus { -+ resets = <&rst 10> <&rst 11> <&rst 12> <&rst 11>; -+ reset-names = "i2s1", "i2s2", "dma", "mixer"; -+ }; -+ -+This represents a bus that controls the reset signal of each of four sub- -+ordinate devices. Consider for example a bus that fails to operate unless no -+child device has reset asserted. -diff --git a/drivers/Kconfig b/drivers/Kconfig -index f5fb072..51f73ae 100644 ---- a/drivers/Kconfig -+++ b/drivers/Kconfig -@@ -158,4 +158,6 @@ source "drivers/irqchip/Kconfig" - - source "drivers/ipack/Kconfig" - -+source "drivers/reset/Kconfig" -+ - endmenu -diff --git a/drivers/Makefile b/drivers/Makefile -index 7863b9f..2819ac0 100644 ---- a/drivers/Makefile -+++ b/drivers/Makefile -@@ -37,6 +37,9 @@ obj-$(CONFIG_XEN) += xen/ - # regulators early, since some subsystems rely on them to initialize - obj-$(CONFIG_REGULATOR) += regulator/ - -+# reset controllers early, since gpu drivers might rely on them to initialize -+obj-$(CONFIG_RESET_CONTROLLER) += reset/ -+ - # tty/ comes before char/ so that the VT console is the boot-time - # default. - obj-y += tty/ -diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig -new file mode 100644 -index 0000000..c9d04f7 ---- /dev/null -+++ b/drivers/reset/Kconfig -@@ -0,0 +1,13 @@ -+config ARCH_HAS_RESET_CONTROLLER -+ bool -+ -+menuconfig RESET_CONTROLLER -+ bool "Reset Controller Support" -+ default y if ARCH_HAS_RESET_CONTROLLER -+ help -+ Generic Reset Controller support. -+ -+ This framework is designed to abstract reset handling of devices -+ via GPIOs or SoC-internal reset controller modules. -+ -+ If unsure, say no. -diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile -new file mode 100644 -index 0000000..1e2d83f ---- /dev/null -+++ b/drivers/reset/Makefile -@@ -0,0 +1 @@ -+obj-$(CONFIG_RESET_CONTROLLER) += core.o -diff --git a/drivers/reset/core.c b/drivers/reset/core.c -new file mode 100644 -index 0000000..d1b6089 ---- /dev/null -+++ b/drivers/reset/core.c -@@ -0,0 +1,297 @@ -+/* -+ * Reset Controller framework -+ * -+ * Copyright 2013 Philipp Zabel, Pengutronix -+ * -+ * 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. -+ */ -+#include <linux/device.h> -+#include <linux/err.h> -+#include <linux/export.h> -+#include <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/of.h> -+#include <linux/reset.h> -+#include <linux/reset-controller.h> -+#include <linux/slab.h> -+ -+static DEFINE_MUTEX(reset_controller_list_mutex); -+static LIST_HEAD(reset_controller_list); -+ -+/** -+ * struct reset_control - a reset control -+ * @rcdev: a pointer to the reset controller device -+ * this reset control belongs to -+ * @id: ID of the reset controller in the reset -+ * controller device -+ */ -+struct reset_control { -+ struct reset_controller_dev *rcdev; -+ struct device *dev; -+ unsigned int id; -+}; -+ -+/** -+ * of_reset_simple_xlate - translate reset_spec to the reset line number -+ * @rcdev: a pointer to the reset controller device -+ * @reset_spec: reset line specifier as found in the device tree -+ * @flags: a flags pointer to fill in (optional) -+ * -+ * This simple translation function should be used for reset controllers -+ * with 1:1 mapping, where reset lines can be indexed by number without gaps. -+ */ -+int of_reset_simple_xlate(struct reset_controller_dev *rcdev, -+ const struct of_phandle_args *reset_spec) -+{ -+ if (WARN_ON(reset_spec->args_count != rcdev->of_reset_n_cells)) -+ return -EINVAL; -+ -+ if (reset_spec->args[0] >= rcdev->nr_resets) -+ return -EINVAL; -+ -+ return reset_spec->args[0]; -+} -+EXPORT_SYMBOL_GPL(of_reset_simple_xlate); -+ -+/** -+ * reset_controller_register - register a reset controller device -+ * @rcdev: a pointer to the initialized reset controller device -+ */ -+int reset_controller_register(struct reset_controller_dev *rcdev) -+{ -+ if (!rcdev->of_xlate) { -+ rcdev->of_reset_n_cells = 1; -+ rcdev->of_xlate = of_reset_simple_xlate; -+ } -+ -+ mutex_lock(&reset_controller_list_mutex); -+ list_add(&rcdev->list, &reset_controller_list); -+ mutex_unlock(&reset_controller_list_mutex); -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(reset_controller_register); -+ -+/** -+ * reset_controller_unregister - unregister a reset controller device -+ * @rcdev: a pointer to the reset controller device -+ */ -+void reset_controller_unregister(struct reset_controller_dev *rcdev) -+{ -+ mutex_lock(&reset_controller_list_mutex); -+ list_del(&rcdev->list); -+ mutex_unlock(&reset_controller_list_mutex); -+} -+EXPORT_SYMBOL_GPL(reset_controller_unregister); -+ -+/** -+ * reset_control_reset - reset the controlled device -+ * @rstc: reset controller -+ */ -+int reset_control_reset(struct reset_control *rstc) -+{ -+ if (rstc->rcdev->ops->reset) -+ return rstc->rcdev->ops->reset(rstc->rcdev, rstc->id); -+ -+ return -ENOSYS; -+} -+EXPORT_SYMBOL_GPL(reset_control_reset); -+ -+/** -+ * reset_control_assert - asserts the reset line -+ * @rstc: reset controller -+ */ -+int reset_control_assert(struct reset_control *rstc) -+{ -+ if (rstc->rcdev->ops->assert) -+ return rstc->rcdev->ops->assert(rstc->rcdev, rstc->id); -+ -+ return -ENOSYS; -+} -+EXPORT_SYMBOL_GPL(reset_control_assert); -+ -+/** -+ * reset_control_deassert - deasserts the reset line -+ * @rstc: reset controller -+ */ -+int reset_control_deassert(struct reset_control *rstc) -+{ -+ if (rstc->rcdev->ops->deassert) -+ return rstc->rcdev->ops->deassert(rstc->rcdev, rstc->id); -+ -+ return -ENOSYS; -+} -+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 -+ * @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 = ERR_PTR(-EPROBE_DEFER); -+ struct reset_controller_dev *r, *rcdev; -+ struct of_phandle_args args; -+ int index = 0; -+ int rstc_id; -+ int ret; -+ -+ if (!dev) -+ return ERR_PTR(-EINVAL); -+ -+ if (id) -+ index = of_property_match_string(dev->of_node, -+ "reset-names", id); -+ ret = of_parse_phandle_with_args(dev->of_node, "resets", "#reset-cells", -+ index, &args); -+ if (ret) -+ return ERR_PTR(ret); -+ -+ mutex_lock(&reset_controller_list_mutex); -+ rcdev = NULL; -+ list_for_each_entry(r, &reset_controller_list, list) { -+ if (args.np == r->of_node) { -+ rcdev = r; -+ break; -+ } -+ } -+ of_node_put(args.np); -+ -+ if (!rcdev) { -+ mutex_unlock(&reset_controller_list_mutex); -+ return ERR_PTR(-ENODEV); -+ } -+ -+ rstc_id = rcdev->of_xlate(rcdev, &args); -+ if (rstc_id < 0) { -+ mutex_unlock(&reset_controller_list_mutex); -+ return ERR_PTR(rstc_id); -+ } -+ -+ try_module_get(rcdev->owner); -+ mutex_unlock(&reset_controller_list_mutex); -+ -+ rstc = kzalloc(sizeof(*rstc), GFP_KERNEL); -+ if (!rstc) { -+ module_put(rcdev->owner); -+ return ERR_PTR(-ENOMEM); -+ } -+ -+ rstc->dev = dev; -+ rstc->rcdev = rcdev; -+ rstc->id = rstc_id; -+ -+ return rstc; -+} -+EXPORT_SYMBOL_GPL(reset_control_get); -+ -+/** -+ * reset_control_put - free the reset controller -+ * @rstc: reset controller -+ */ -+ -+void reset_control_put(struct reset_control *rstc) -+{ -+ if (IS_ERR(rstc)) -+ return; -+ -+ module_put(rstc->rcdev->owner); -+ kfree(rstc); -+} -+EXPORT_SYMBOL_GPL(reset_control_put); -+ -+static void devm_reset_control_release(struct device *dev, void *res) -+{ -+ reset_control_put(*(struct reset_control **)res); -+} -+ -+/** -+ * devm_reset_control_get - resource managed reset_control_get() -+ * @dev: device to be reset by the controller -+ * @id: reset line name -+ * -+ * Managed reset_control_get(). For reset controllers returned from this -+ * function, reset_control_put() is called automatically on driver detach. -+ * See reset_control_get() for more information. -+ */ -+struct reset_control *devm_reset_control_get(struct device *dev, const char *id) -+{ -+ struct reset_control **ptr, *rstc; -+ -+ ptr = devres_alloc(devm_reset_control_release, sizeof(*ptr), -+ GFP_KERNEL); -+ if (!ptr) -+ return ERR_PTR(-ENOMEM); -+ -+ rstc = reset_control_get(dev, id); -+ if (!IS_ERR(rstc)) { -+ *ptr = rstc; -+ devres_add(dev, ptr); -+ } else { -+ devres_free(ptr); -+ } -+ -+ return rstc; -+} -+EXPORT_SYMBOL_GPL(devm_reset_control_get); -+ -+static int devm_reset_control_match(struct device *dev, void *res, void *data) -+{ -+ struct reset_control **rstc = res; -+ if (WARN_ON(!rstc || !*rstc)) -+ return 0; -+ return *rstc == data; -+} -+ -+/** -+ * devm_reset_control_put - resource managed reset_control_put() -+ * @rstc: reset controller to free -+ * -+ * Deallocate a reset control allocated withd devm_reset_control_get(). -+ * This function will not need to be called normally, as devres will take -+ * care of freeing the resource. -+ */ -+void devm_reset_control_put(struct reset_control *rstc) -+{ -+ int ret; -+ -+ ret = devres_release(rstc->dev, devm_reset_control_release, -+ devm_reset_control_match, rstc); -+ if (ret) -+ WARN_ON(ret); -+} -+EXPORT_SYMBOL_GPL(devm_reset_control_put); -+ -+/** -+ * device_reset - find reset controller associated with the device -+ * and perform reset -+ * @dev: device to be reset by the controller -+ * -+ * Convenience wrapper for reset_control_get() and reset_control_reset(). -+ * This is useful for the common case of devices with single, dedicated reset -+ * lines. -+ */ -+int device_reset(struct device *dev) -+{ -+ struct reset_control *rstc; -+ int ret; -+ -+ rstc = reset_control_get(dev, NULL); -+ if (IS_ERR(rstc)) -+ return PTR_ERR(rstc); -+ -+ ret = reset_control_reset(rstc); -+ -+ reset_control_put(rstc); -+ -+ return ret; -+} -+EXPORT_SYMBOL_GPL(device_reset); -diff --git a/include/linux/reset-controller.h b/include/linux/reset-controller.h -new file mode 100644 -index 0000000..2f61311 ---- /dev/null -+++ b/include/linux/reset-controller.h -@@ -0,0 +1,51 @@ -+#ifndef _LINUX_RESET_CONTROLLER_H_ -+#define _LINUX_RESET_CONTROLLER_H_ -+ -+#include <linux/list.h> -+ -+struct reset_controller_dev; -+ -+/** -+ * struct reset_control_ops -+ * -+ * @reset: for self-deasserting resets, does all necessary -+ * things to reset the device -+ * @assert: manually assert the reset line, if supported -+ * @deassert: manually deassert the reset line, if supported -+ */ -+struct reset_control_ops { -+ int (*reset)(struct reset_controller_dev *rcdev, unsigned long id); -+ int (*assert)(struct reset_controller_dev *rcdev, unsigned long id); -+ int (*deassert)(struct reset_controller_dev *rcdev, unsigned long id); -+}; -+ -+struct module; -+struct device_node; -+ -+/** -+ * struct reset_controller_dev - reset controller entity that might -+ * provide multiple reset controls -+ * @ops: a pointer to device specific struct reset_control_ops -+ * @owner: kernel module of the reset controller driver -+ * @list: internal list of reset controller devices -+ * @of_node: corresponding device tree node as phandle target -+ * @of_reset_n_cells: number of cells in reset line specifiers -+ * @of_xlate: translation function to translate from specifier as found in the -+ * device tree to id as given to the reset control ops -+ * @nr_resets: number of reset controls in this reset controller device -+ */ -+struct reset_controller_dev { -+ struct reset_control_ops *ops; -+ struct module *owner; -+ struct list_head list; -+ struct device_node *of_node; -+ int of_reset_n_cells; -+ int (*of_xlate)(struct reset_controller_dev *rcdev, -+ const struct of_phandle_args *reset_spec); -+ unsigned int nr_resets; -+}; -+ -+int reset_controller_register(struct reset_controller_dev *rcdev); -+void reset_controller_unregister(struct reset_controller_dev *rcdev); -+ -+#endif -diff --git a/include/linux/reset.h b/include/linux/reset.h -new file mode 100644 -index 0000000..6082247 ---- /dev/null -+++ b/include/linux/reset.h -@@ -0,0 +1,17 @@ -+#ifndef _LINUX_RESET_H_ -+#define _LINUX_RESET_H_ -+ -+struct device; -+struct reset_control; -+ -+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 *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); -+ -+int device_reset(struct device *dev); -+ -+#endif --- -1.7.10.4 - |