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

From: Prabhakar

Date: Tue Sep 29 2026 - 08:48:31 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>
---
drivers/iio/adc/rzt2h_adc.c | 26 ++++++++++++++++++++++++--
1 file changed, 24 insertions(+), 2 deletions(-)

diff --git a/drivers/iio/adc/rzt2h_adc.c b/drivers/iio/adc/rzt2h_adc.c
index f1a830da6f9b..4726f892da23 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>

#define RZT2H_ADCSR_REG 0x00
#define RZT2H_ADCSR_ADIE_MASK BIT(12)
@@ -90,6 +91,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;
@@ -706,6 +708,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;
@@ -767,10 +773,22 @@ 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);
+
+ return reset_control_assert(adc->rstc);
+}
+
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;
@@ -782,11 +800,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