kernel: bump 5.4 to 5.4.48
[oweals/openwrt.git] / target / linux / bcm27xx / patches-5.4 / 950-0534-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;