[PATCH v3 4/8] iio: adc: rzt2h: Add optional reset support

From: Prabhakar

Date: Fri Oct 23 2026 - 14:02:43 EST


From: Lad Prabhakar <prabhakar.mahadev-lad.rj@xxxxxxxxxxxxxx>

Prepare the driver for RZ/V2H(P), where the ADC has a module reset line
that is not present on RZ/T2H.

Assert the optional reset when the ADC is runtime-suspended and deassert it
on runtime resume before performing calibration. Assert the reset again if
calibration fails.

Use a shared reset control to support SoCs such as RZ/V2N where the reset
line is shared between multiple ADC instances.

Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@xxxxxxxxxxxxxx>
---
v2->v3:
- rzt2h_adc_pm_runtime_suspend() checks the return value of
reset_control_assert() and returns it if non-zero. This is to
avoid churn in future patch.

v1->v2:
- No change
---
drivers/iio/adc/rzt2h_adc.c | 31 +++++++++++++++++++++++++++++--
1 file changed, 29 insertions(+), 2 deletions(-)

diff --git a/drivers/iio/adc/rzt2h_adc.c b/drivers/iio/adc/rzt2h_adc.c
index 2ada8ecb2603..51a976f85ae7 100644
--- a/drivers/iio/adc/rzt2h_adc.c
+++ b/drivers/iio/adc/rzt2h_adc.c
@@ -20,6 +20,7 @@
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/property.h>
+#include <linux/reset.h>
#include <linux/time64.h>

#define RZT2H_ADCSR_REG 0x00
@@ -91,6 +92,7 @@ struct rzt2h_adc {
void __iomem *base;
struct device *dev;
const struct rzt2h_adc_chip_info *chip_info;
+ struct reset_control *rstc;

phys_addr_t phys_base;
struct rzt2h_adc_dma dma;
@@ -709,6 +711,10 @@ static int rzt2h_adc_probe(struct platform_device *pdev)

platform_set_drvdata(pdev, adc);

+ adc->rstc = devm_reset_control_get_optional_shared(dev, NULL);
+ if (IS_ERR(adc->rstc))
+ return PTR_ERR(adc->rstc);
+
ret = rzt2h_adc_parse_properties(adc);
if (ret)
return ret;
@@ -770,10 +776,27 @@ static const struct of_device_id rzt2h_adc_match[] = {
};
MODULE_DEVICE_TABLE(of, rzt2h_adc_match);

+static int rzt2h_adc_pm_runtime_suspend(struct device *dev)
+{
+ struct rzt2h_adc *adc = dev_get_drvdata(dev);
+ int ret;
+
+ ret = reset_control_assert(adc->rstc);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
static int rzt2h_adc_pm_runtime_resume(struct device *dev)
{
struct rzt2h_adc *adc = dev_get_drvdata(dev);
const struct rzt2h_adc_chip_info *chip_info = adc->chip_info;
+ int ret;
+
+ ret = reset_control_deassert(adc->rstc);
+ if (ret)
+ return ret;

if (!(chip_info->features & RZT2H_ADC_FEATURE_CALIBRATION))
return 0;
@@ -785,11 +808,15 @@ static int rzt2h_adc_pm_runtime_resume(struct device *dev)
*/
fsleep(1);

- return rzt2h_adc_calibrate(adc);
+ ret = rzt2h_adc_calibrate(adc);
+ if (ret)
+ reset_control_assert(adc->rstc);
+
+ return ret;
}

static const struct dev_pm_ops rzt2h_adc_pm_ops = {
- RUNTIME_PM_OPS(NULL, rzt2h_adc_pm_runtime_resume, NULL)
+ RUNTIME_PM_OPS(rzt2h_adc_pm_runtime_suspend, rzt2h_adc_pm_runtime_resume, NULL)
};

static struct platform_driver rzt2h_adc_driver = {
--
2.55.0