Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Maxime Ripard and committed by
Philipp Zabel
a9701376 9357b046

+27
+20
drivers/reset/reset-simple.c
··· 11 11 * Maxime Ripard <maxime.ripard@free-electrons.com> 12 12 */ 13 13 14 + #include <linux/delay.h> 14 15 #include <linux/device.h> 15 16 #include <linux/err.h> 16 17 #include <linux/io.h> ··· 64 63 return reset_simple_update(rcdev, id, false); 65 64 } 66 65 66 + static int reset_simple_reset(struct reset_controller_dev *rcdev, 67 + unsigned long id) 68 + { 69 + struct reset_simple_data *data = to_reset_simple_data(rcdev); 70 + int ret; 71 + 72 + if (!data->reset_us) 73 + return -ENOTSUPP; 74 + 75 + ret = reset_simple_assert(rcdev, id); 76 + if (ret) 77 + return ret; 78 + 79 + usleep_range(data->reset_us, data->reset_us * 2); 80 + 81 + return reset_simple_deassert(rcdev, id); 82 + } 83 + 67 84 static int reset_simple_status(struct reset_controller_dev *rcdev, 68 85 unsigned long id) 69 86 { ··· 99 80 const struct reset_control_ops reset_simple_ops = { 100 81 .assert = reset_simple_assert, 101 82 .deassert = reset_simple_deassert, 83 + .reset = reset_simple_reset, 102 84 .status = reset_simple_status, 103 85 }; 104 86 EXPORT_SYMBOL_GPL(reset_simple_ops);
+7
include/linux/reset/reset-simple.h
··· 27 27 * @status_active_low: if true, bits read back as cleared while the reset is 28 28 * asserted. Otherwise, bits read back as set while the 29 29 * reset is asserted. 30 + * @reset_us: Minimum delay in microseconds needed that needs to be 31 + * waited for between an assert and a deassert to reset the 32 + * device. If multiple consumers with different delay 33 + * requirements are connected to this controller, it must 34 + * be the largest minimum delay. 0 means that such a delay is 35 + * unknown and the reset operation is unsupported. 30 36 */ 31 37 struct reset_simple_data { 32 38 spinlock_t lock; ··· 40 34 struct reset_controller_dev rcdev; 41 35 bool active_low; 42 36 bool status_active_low; 37 + unsigned int reset_us; 43 38 }; 44 39 45 40 extern const struct reset_control_ops reset_simple_ops;