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. Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de> Signed-off-by: Maxime Ripard <maxime@cerno.tech> Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
This commit is contained in:
parent
9357b04624
commit
a9701376ed
|
@ -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,24 @@ static int reset_simple_deassert(struct reset_controller_dev *rcdev,
|
|||
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);
|
||||
|
||||
return reset_simple_deassert(rcdev, id);
|
||||
}
|
||||
|
||||
static int reset_simple_status(struct reset_controller_dev *rcdev,
|
||||
unsigned long id)
|
||||
{
|
||||
|
@ -80,6 +99,7 @@ static int reset_simple_status(struct reset_controller_dev *rcdev,
|
|||
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);
|
||||
|
|
|
@ -27,6 +27,12 @@
|
|||
* @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. 0 means that such a delay is
|
||||
* unknown and the reset operation is unsupported.
|
||||
*/
|
||||
struct reset_simple_data {
|
||||
spinlock_t lock;
|
||||
|
@ -34,6 +40,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;
|
||||
|
|
Loading…
Reference in New Issue