[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