blob: 035c9d6aa0ae53c2eea8c4644d67080c49516b2b [file] [log] [blame]
b.liue9582032025-04-17 19:18:16 +08001From 66deff85fee24ecd7b0ffa2901711aa8f026fcfa Mon Sep 17 00:00:00 2001
2From: Maxime Ripard <maxime@cerno.tech>
3Date: Tue, 28 Jan 2020 16:22:20 +0100
4Subject: [PATCH] reset: simple: Add reset callback
5
6The reset-simple code lacks a reset callback that is still pretty easy to
7implement. The only real thing to consider is the delay needed for a device
8to be reset, so let's expose that as part of the reset-simple driver data.
9
10Cc: Philipp Zabel <p.zabel@pengutronix.de>
11Signed-off-by: Maxime Ripard <maxime@cerno.tech>
12---
13 drivers/reset/reset-simple.c | 24 ++++++++++++++++++++++++
14 include/linux/reset/reset-simple.h | 6 ++++++
15 2 files changed, 30 insertions(+)
16
17--- a/drivers/reset/reset-simple.c
18+++ b/drivers/reset/reset-simple.c
19@@ -11,6 +11,7 @@
20 * Maxime Ripard <maxime.ripard@free-electrons.com>
21 */
22
23+#include <linux/delay.h>
24 #include <linux/device.h>
25 #include <linux/err.h>
26 #include <linux/io.h>
27@@ -63,6 +64,28 @@ static int reset_simple_deassert(struct
28 return reset_simple_update(rcdev, id, false);
29 }
30
31+static int reset_simple_reset(struct reset_controller_dev *rcdev,
32+ unsigned long id)
33+{
34+ struct reset_simple_data *data = to_reset_simple_data(rcdev);
35+ int ret;
36+
37+ if (!data->reset_us)
38+ return -ENOTSUPP;
39+
40+ ret = reset_simple_assert(rcdev, id);
41+ if (ret)
42+ return ret;
43+
44+ usleep_range(data->reset_us, data->reset_us * 2);
45+
46+ ret = reset_simple_deassert(rcdev, id);
47+ if (ret)
48+ return ret;
49+
50+ return 0;
51+}
52+
53 static int reset_simple_status(struct reset_controller_dev *rcdev,
54 unsigned long id)
55 {
56@@ -80,6 +103,7 @@ static int reset_simple_status(struct re
57 const struct reset_control_ops reset_simple_ops = {
58 .assert = reset_simple_assert,
59 .deassert = reset_simple_deassert,
60+ .reset = reset_simple_reset,
61 .status = reset_simple_status,
62 };
63 EXPORT_SYMBOL_GPL(reset_simple_ops);
64--- a/include/linux/reset/reset-simple.h
65+++ b/include/linux/reset/reset-simple.h
66@@ -27,6 +27,11 @@
67 * @status_active_low: if true, bits read back as cleared while the reset is
68 * asserted. Otherwise, bits read back as set while the
69 * reset is asserted.
70+ * @reset_us: Minimum delay in microseconds needed that needs to be
71+ * waited for between an assert and a deassert to reset the
72+ * device. If multiple consumers with different delay
73+ * requirements are connected to this controller, it must
74+ * be the largest minimum delay.
75 */
76 struct reset_simple_data {
77 spinlock_t lock;
78@@ -34,6 +39,7 @@ struct reset_simple_data {
79 struct reset_controller_dev rcdev;
80 bool active_low;
81 bool status_active_low;
82+ unsigned int reset_us;
83 };
84
85 extern const struct reset_control_ops reset_simple_ops;