Openwrt/target/linux/bcm27xx/patches-5.4/950-0528-reset-simple-Add-reset-callback.patch
Álvaro Fernández Rojas f07e572f64 bcm27xx: import latest patches from the RPi foundation
bcm2708: boot tested on RPi B+ v1.2
bcm2709: boot tested on RPi 3B v1.2 and RPi 4B v1.1 4G
bcm2710: boot tested on RPi 3B v1.2
bcm2711: boot tested on RPi 4B v1.1 4G

Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
2021-02-18 23:42:32 +01:00

86 lines
2.7 KiB
Diff

From 66deff85fee24ecd7b0ffa2901711aa8f026fcfa Mon Sep 17 00:00:00 2001
From: Maxime Ripard <maxime@cerno.tech>
Date: Tue, 28 Jan 2020 16:22:20 +0100
Subject: [PATCH] reset: simple: Add reset callback
The reset-simple code lacks a reset callback that is still pretty easy to
implement. The only real thing to consider is the delay needed for a device
to be reset, so let's expose that as part of the reset-simple driver data.
Cc: Philipp Zabel <p.zabel@pengutronix.de>
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
drivers/reset/reset-simple.c | 24 ++++++++++++++++++++++++
include/linux/reset/reset-simple.h | 6 ++++++
2 files changed, 30 insertions(+)
--- a/drivers/reset/reset-simple.c
+++ b/drivers/reset/reset-simple.c
@@ -11,6 +11,7 @@
* Maxime Ripard <maxime.ripard@free-electrons.com>
*/
+#include <linux/delay.h>
#include <linux/device.h>
#include <linux/err.h>
#include <linux/io.h>
@@ -63,6 +64,28 @@ static int reset_simple_deassert(struct
return reset_simple_update(rcdev, id, false);
}
+static int reset_simple_reset(struct reset_controller_dev *rcdev,
+ unsigned long id)
+{
+ struct reset_simple_data *data = to_reset_simple_data(rcdev);
+ int ret;
+
+ if (!data->reset_us)
+ return -ENOTSUPP;
+
+ ret = reset_simple_assert(rcdev, id);
+ if (ret)
+ return ret;
+
+ usleep_range(data->reset_us, data->reset_us * 2);
+
+ ret = reset_simple_deassert(rcdev, id);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
static int reset_simple_status(struct reset_controller_dev *rcdev,
unsigned long id)
{
@@ -80,6 +103,7 @@ static int reset_simple_status(struct re
const struct reset_control_ops reset_simple_ops = {
.assert = reset_simple_assert,
.deassert = reset_simple_deassert,
+ .reset = reset_simple_reset,
.status = reset_simple_status,
};
EXPORT_SYMBOL_GPL(reset_simple_ops);
--- a/include/linux/reset/reset-simple.h
+++ b/include/linux/reset/reset-simple.h
@@ -27,6 +27,11 @@
* @status_active_low: if true, bits read back as cleared while the reset is
* asserted. Otherwise, bits read back as set while the
* reset is asserted.
+ * @reset_us: Minimum delay in microseconds needed that needs to be
+ * waited for between an assert and a deassert to reset the
+ * device. If multiple consumers with different delay
+ * requirements are connected to this controller, it must
+ * be the largest minimum delay.
*/
struct reset_simple_data {
spinlock_t lock;
@@ -34,6 +39,7 @@ struct reset_simple_data {
struct reset_controller_dev rcdev;
bool active_low;
bool status_active_low;
+ unsigned int reset_us;
};
extern const struct reset_control_ops reset_simple_ops;