diff options
Diffstat (limited to 'target/linux/sunxi/patches-4.4/143-reset-add-shared-resetcontrol-asserts.patch')
-rw-r--r-- | target/linux/sunxi/patches-4.4/143-reset-add-shared-resetcontrol-asserts.patch | 265 |
1 files changed, 0 insertions, 265 deletions
diff --git a/target/linux/sunxi/patches-4.4/143-reset-add-shared-resetcontrol-asserts.patch b/target/linux/sunxi/patches-4.4/143-reset-add-shared-resetcontrol-asserts.patch deleted file mode 100644 index e1078e9696..0000000000 --- a/target/linux/sunxi/patches-4.4/143-reset-add-shared-resetcontrol-asserts.patch +++ /dev/null @@ -1,265 +0,0 @@ -From d25cfe9b4f9663216ce4e011e3f1e7fa669ab58a Mon Sep 17 00:00:00 2001 -From: Hans de Goede <hdegoede@redhat.com> -Date: Fri, 27 Nov 2015 21:09:05 +0100 -Subject: [PATCH] reset: Add shared reset_control_[de]assert variants - -Add reset_control_deassert_shared / reset_control_assert_shared -functions which are intended for use by drivers for hw blocks which -(may) share a reset line with another driver / hw block. - -Unlike the regular reset_control_[de]assert functions these functions -keep track of how often deassert_shared / assert_shared have been called -and keep the line deasserted as long as deassert has been called more -times than assert. - -Signed-off-by: Hans de Goede <hdegoede@redhat.com> ---- -Changes in v2: --This is a new patch in v2 of this patch-set ---- - drivers/reset/core.c | 121 ++++++++++++++++++++++++++++++++++++--- - include/linux/reset-controller.h | 2 + - include/linux/reset.h | 2 + - 3 files changed, 116 insertions(+), 9 deletions(-) - ---- a/drivers/reset/core.c -+++ b/drivers/reset/core.c -@@ -22,16 +22,29 @@ static DEFINE_MUTEX(reset_controller_lis - static LIST_HEAD(reset_controller_list); - - /** -+ * struct reset_line - a reset line -+ * @list: list entry for the reset controllers reset line list -+ * @id: ID of the reset line in the reset controller device -+ * @refcnt: Number of reset_control structs referencing this device -+ * @deassert_cnt: Number of times this reset line has been deasserted -+ */ -+struct reset_line { -+ struct list_head list; -+ unsigned int id; -+ unsigned int refcnt; -+ unsigned int deassert_cnt; -+}; -+ -+/** - * 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 -+ * @line: reset line for this reset control - */ - struct reset_control { - struct reset_controller_dev *rcdev; -+ struct reset_line *line; - struct device *dev; -- unsigned int id; - }; - - /** -@@ -66,6 +79,8 @@ int reset_controller_register(struct res - rcdev->of_xlate = of_reset_simple_xlate; - } - -+ INIT_LIST_HEAD(&rcdev->reset_line_head); -+ - mutex_lock(&reset_controller_list_mutex); - list_add(&rcdev->list, &reset_controller_list); - mutex_unlock(&reset_controller_list_mutex); -@@ -93,7 +108,7 @@ EXPORT_SYMBOL_GPL(reset_controller_unreg - int reset_control_reset(struct reset_control *rstc) - { - if (rstc->rcdev->ops->reset) -- return rstc->rcdev->ops->reset(rstc->rcdev, rstc->id); -+ return rstc->rcdev->ops->reset(rstc->rcdev, rstc->line->id); - - return -ENOTSUPP; - } -@@ -106,7 +121,7 @@ EXPORT_SYMBOL_GPL(reset_control_reset); - int reset_control_assert(struct reset_control *rstc) - { - if (rstc->rcdev->ops->assert) -- return rstc->rcdev->ops->assert(rstc->rcdev, rstc->id); -+ return rstc->rcdev->ops->assert(rstc->rcdev, rstc->line->id); - - return -ENOTSUPP; - } -@@ -119,13 +134,55 @@ EXPORT_SYMBOL_GPL(reset_control_assert); - int reset_control_deassert(struct reset_control *rstc) - { - if (rstc->rcdev->ops->deassert) -- return rstc->rcdev->ops->deassert(rstc->rcdev, rstc->id); -+ return rstc->rcdev->ops->deassert(rstc->rcdev, rstc->line->id); - - return -ENOTSUPP; - } - EXPORT_SYMBOL_GPL(reset_control_deassert); - - /** -+ * reset_control_assert_shared - asserts a shared reset line -+ * @rstc: reset controller -+ * -+ * Assert a shared reset line, this functions decreases the deassert count -+ * of the line by one and asserts it if, and only if, the deassert count -+ * reaches 0. -+ */ -+int reset_control_assert_shared(struct reset_control *rstc) -+{ -+ if (!rstc->rcdev->ops->assert) -+ return -ENOTSUPP; -+ -+ rstc->line->deassert_cnt--; -+ if (rstc->line->deassert_cnt) -+ return 0; -+ -+ return rstc->rcdev->ops->assert(rstc->rcdev, rstc->line->id); -+} -+EXPORT_SYMBOL_GPL(reset_control_assert_shared); -+ -+/** -+ * reset_control_deassert_shared - deasserts a shared reset line -+ * @rstc: reset controller -+ * -+ * Assert a shared reset line, this functions increases the deassert count -+ * of the line by one and deasserts the reset line (if it was not already -+ * deasserted). -+ */ -+int reset_control_deassert_shared(struct reset_control *rstc) -+{ -+ if (!rstc->rcdev->ops->deassert) -+ return -ENOTSUPP; -+ -+ rstc->line->deassert_cnt++; -+ if (rstc->line->deassert_cnt != 1) -+ return 0; -+ -+ return rstc->rcdev->ops->deassert(rstc->rcdev, rstc->line->id); -+} -+EXPORT_SYMBOL_GPL(reset_control_deassert_shared); -+ -+/** - * reset_control_status - returns a negative errno if not supported, a - * positive value if the reset line is asserted, or zero if the reset - * line is not asserted. -@@ -134,12 +191,47 @@ EXPORT_SYMBOL_GPL(reset_control_deassert - int reset_control_status(struct reset_control *rstc) - { - if (rstc->rcdev->ops->status) -- return rstc->rcdev->ops->status(rstc->rcdev, rstc->id); -+ return rstc->rcdev->ops->status(rstc->rcdev, rstc->line->id); - - return -ENOTSUPP; - } - EXPORT_SYMBOL_GPL(reset_control_status); - -+static struct reset_line *reset_line_get(struct reset_controller_dev *rcdev, -+ unsigned int index) -+{ -+ struct reset_line *line; -+ -+ list_for_each_entry(line, &rcdev->reset_line_head, list) { -+ if (line->id == index) { -+ line->refcnt++; -+ return line; -+ } -+ } -+ -+ line = kzalloc(sizeof(*line), GFP_KERNEL); -+ if (!line) -+ return NULL; -+ -+ list_add(&line->list, &rcdev->reset_line_head); -+ line->id = index; -+ line->refcnt = 1; -+ -+ return line; -+} -+ -+static void reset_line_put(struct reset_line *line) -+{ -+ if (!line) -+ return; -+ -+ if (--line->refcnt) -+ return; -+ -+ list_del(&line->list); -+ kfree(line); -+} -+ - /** - * of_reset_control_get_by_index - Lookup and obtain a reference to a reset - * controller by index. -@@ -155,6 +247,7 @@ struct reset_control *of_reset_control_g - { - struct reset_control *rstc = ERR_PTR(-EPROBE_DEFER); - struct reset_controller_dev *r, *rcdev; -+ struct reset_line *line; - struct of_phandle_args args; - int rstc_id; - int ret; -@@ -186,16 +279,22 @@ struct reset_control *of_reset_control_g - } - - try_module_get(rcdev->owner); -+ -+ /* reset_controller_list_mutex also protects the reset_line list */ -+ line = reset_line_get(rcdev, rstc_id); -+ - mutex_unlock(&reset_controller_list_mutex); - - rstc = kzalloc(sizeof(*rstc), GFP_KERNEL); -- if (!rstc) { -+ if (!line || !rstc) { -+ kfree(rstc); -+ reset_line_put(line); - module_put(rcdev->owner); - return ERR_PTR(-ENOMEM); - } - - rstc->rcdev = rcdev; -- rstc->id = rstc_id; -+ rstc->line = line; - - return rstc; - } -@@ -259,6 +358,10 @@ void reset_control_put(struct reset_cont - if (IS_ERR(rstc)) - return; - -+ mutex_lock(&reset_controller_list_mutex); -+ reset_line_put(rstc->line); -+ mutex_unlock(&reset_controller_list_mutex); -+ - module_put(rstc->rcdev->owner); - kfree(rstc); - } ---- a/include/linux/reset-controller.h -+++ b/include/linux/reset-controller.h -@@ -31,6 +31,7 @@ struct of_phandle_args; - * @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 -+ * @reset_line_head: head of internal list of reset lines - * @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 -@@ -41,6 +42,7 @@ struct reset_controller_dev { - struct reset_control_ops *ops; - struct module *owner; - struct list_head list; -+ struct list_head reset_line_head; - struct device_node *of_node; - int of_reset_n_cells; - int (*of_xlate)(struct reset_controller_dev *rcdev, ---- a/include/linux/reset.h -+++ b/include/linux/reset.h -@@ -11,6 +11,8 @@ int reset_control_reset(struct reset_con - int reset_control_assert(struct reset_control *rstc); - int reset_control_deassert(struct reset_control *rstc); - int reset_control_status(struct reset_control *rstc); -+int reset_control_assert_shared(struct reset_control *rstc); -+int reset_control_deassert_shared(struct reset_control *rstc); - - struct reset_control *reset_control_get(struct device *dev, const char *id); - void reset_control_put(struct reset_control *rstc); |