firmware-utils: bump to git HEAD
[openwrt/openwrt.git] / target / linux / bcm27xx / patches-5.4 / 950-0528-reset-simple-Add-reset-callback.patch
1 From 66deff85fee24ecd7b0ffa2901711aa8f026fcfa Mon Sep 17 00:00:00 2001
2 From: Maxime Ripard <maxime@cerno.tech>
3 Date: Tue, 28 Jan 2020 16:22:20 +0100
4 Subject: [PATCH] reset: simple: Add reset callback
5
6 The reset-simple code lacks a reset callback that is still pretty easy to
7 implement. The only real thing to consider is the delay needed for a device
8 to be reset, so let's expose that as part of the reset-simple driver data.
9
10 Cc: Philipp Zabel <p.zabel@pengutronix.de>
11 Signed-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;