f07e572f64
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>
86 lines
2.7 KiB
Diff
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;
|