mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/chenhuacai/linux-loongson
synced 2025-09-06 21:14:18 +00:00
iio: adc: rzg2l_adc: Simplify the runtime PM code
All Renesas SoCs using the rzg2l_adc driver manage ADC clocks through PM domains. Calling pm_runtime_{resume_and_get, put_sync}() implicitly sets the state of the clocks. As a result, the code in the rzg2l_adc driver that explicitly manages ADC clocks can be removed, leading to simpler and cleaner implementation. Additionally, replace the use of rzg2l_adc_set_power() with direct PM runtime API calls to further simplify and clean up the code. Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com> Reviewed-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com> Link: https://patch.msgid.link/20241206111337.726244-5-claudiu.beznea.uj@bp.renesas.com Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
This commit is contained in:
parent
b010b10467
commit
89ee8174e8
@ -8,7 +8,6 @@
|
||||
*/
|
||||
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/completion.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/iio/iio.h>
|
||||
@ -69,8 +68,6 @@ struct rzg2l_adc_data {
|
||||
|
||||
struct rzg2l_adc {
|
||||
void __iomem *base;
|
||||
struct clk *pclk;
|
||||
struct clk *adclk;
|
||||
struct reset_control *presetn;
|
||||
struct reset_control *adrstn;
|
||||
struct completion completion;
|
||||
@ -188,29 +185,18 @@ static int rzg2l_adc_conversion_setup(struct rzg2l_adc *adc, u8 ch)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rzg2l_adc_set_power(struct iio_dev *indio_dev, bool on)
|
||||
{
|
||||
struct device *dev = indio_dev->dev.parent;
|
||||
|
||||
if (on)
|
||||
return pm_runtime_resume_and_get(dev);
|
||||
|
||||
return pm_runtime_put_sync(dev);
|
||||
}
|
||||
|
||||
static int rzg2l_adc_conversion(struct iio_dev *indio_dev, struct rzg2l_adc *adc, u8 ch)
|
||||
{
|
||||
struct device *dev = indio_dev->dev.parent;
|
||||
int ret;
|
||||
|
||||
ret = rzg2l_adc_set_power(indio_dev, true);
|
||||
ret = pm_runtime_resume_and_get(dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = rzg2l_adc_conversion_setup(adc, ch);
|
||||
if (ret) {
|
||||
rzg2l_adc_set_power(indio_dev, false);
|
||||
return ret;
|
||||
}
|
||||
if (ret)
|
||||
goto rpm_put;
|
||||
|
||||
reinit_completion(&adc->completion);
|
||||
|
||||
@ -219,12 +205,14 @@ static int rzg2l_adc_conversion(struct iio_dev *indio_dev, struct rzg2l_adc *adc
|
||||
if (!wait_for_completion_timeout(&adc->completion, RZG2L_ADC_TIMEOUT)) {
|
||||
rzg2l_adc_writel(adc, RZG2L_ADINT,
|
||||
rzg2l_adc_readl(adc, RZG2L_ADINT) & ~RZG2L_ADINT_INTEN_MASK);
|
||||
rzg2l_adc_start_stop(adc, false);
|
||||
rzg2l_adc_set_power(indio_dev, false);
|
||||
return -ETIMEDOUT;
|
||||
ret = -ETIMEDOUT;
|
||||
}
|
||||
|
||||
return rzg2l_adc_set_power(indio_dev, false);
|
||||
rzg2l_adc_start_stop(adc, false);
|
||||
|
||||
rpm_put:
|
||||
pm_runtime_put_sync(dev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int rzg2l_adc_read_raw(struct iio_dev *indio_dev,
|
||||
@ -349,13 +337,13 @@ static int rzg2l_adc_parse_properties(struct platform_device *pdev, struct rzg2l
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rzg2l_adc_hw_init(struct rzg2l_adc *adc)
|
||||
static int rzg2l_adc_hw_init(struct device *dev, struct rzg2l_adc *adc)
|
||||
{
|
||||
int timeout = 5;
|
||||
u32 reg;
|
||||
int ret;
|
||||
|
||||
ret = clk_prepare_enable(adc->pclk);
|
||||
ret = pm_runtime_resume_and_get(dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@ -393,25 +381,10 @@ static int rzg2l_adc_hw_init(struct rzg2l_adc *adc)
|
||||
rzg2l_adc_writel(adc, RZG2L_ADM(3), reg);
|
||||
|
||||
exit_hw_init:
|
||||
clk_disable_unprepare(adc->pclk);
|
||||
|
||||
pm_runtime_put_sync(dev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void rzg2l_adc_pm_runtime_disable(void *data)
|
||||
{
|
||||
struct device *dev = data;
|
||||
|
||||
pm_runtime_disable(dev->parent);
|
||||
}
|
||||
|
||||
static void rzg2l_adc_pm_runtime_set_suspended(void *data)
|
||||
{
|
||||
struct device *dev = data;
|
||||
|
||||
pm_runtime_set_suspended(dev->parent);
|
||||
}
|
||||
|
||||
static int rzg2l_adc_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
@ -436,16 +409,6 @@ static int rzg2l_adc_probe(struct platform_device *pdev)
|
||||
if (IS_ERR(adc->base))
|
||||
return PTR_ERR(adc->base);
|
||||
|
||||
adc->pclk = devm_clk_get(dev, "pclk");
|
||||
if (IS_ERR(adc->pclk))
|
||||
return dev_err_probe(dev, PTR_ERR(adc->pclk),
|
||||
"Failed to get pclk");
|
||||
|
||||
adc->adclk = devm_clk_get(dev, "adclk");
|
||||
if (IS_ERR(adc->adclk))
|
||||
return dev_err_probe(dev, PTR_ERR(adc->adclk),
|
||||
"Failed to get adclk");
|
||||
|
||||
adc->adrstn = devm_reset_control_get_exclusive_deasserted(dev, "adrst-n");
|
||||
if (IS_ERR(adc->adrstn))
|
||||
return dev_err_probe(dev, PTR_ERR(adc->adrstn),
|
||||
@ -456,7 +419,13 @@ static int rzg2l_adc_probe(struct platform_device *pdev)
|
||||
return dev_err_probe(dev, PTR_ERR(adc->presetn),
|
||||
"failed to get/deassert presetn\n");
|
||||
|
||||
ret = rzg2l_adc_hw_init(adc);
|
||||
ret = devm_pm_runtime_enable(dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
platform_set_drvdata(pdev, indio_dev);
|
||||
|
||||
ret = rzg2l_adc_hw_init(dev, adc);
|
||||
if (ret)
|
||||
return dev_err_probe(&pdev->dev, ret,
|
||||
"failed to initialize ADC HW\n");
|
||||
@ -472,26 +441,12 @@ static int rzg2l_adc_probe(struct platform_device *pdev)
|
||||
|
||||
init_completion(&adc->completion);
|
||||
|
||||
platform_set_drvdata(pdev, indio_dev);
|
||||
|
||||
indio_dev->name = DRIVER_NAME;
|
||||
indio_dev->info = &rzg2l_adc_iio_info;
|
||||
indio_dev->modes = INDIO_DIRECT_MODE;
|
||||
indio_dev->channels = adc->data->channels;
|
||||
indio_dev->num_channels = adc->data->num_channels;
|
||||
|
||||
pm_runtime_set_suspended(dev);
|
||||
ret = devm_add_action_or_reset(&pdev->dev,
|
||||
rzg2l_adc_pm_runtime_set_suspended, &indio_dev->dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
pm_runtime_enable(dev);
|
||||
ret = devm_add_action_or_reset(&pdev->dev,
|
||||
rzg2l_adc_pm_runtime_disable, &indio_dev->dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return devm_iio_device_register(dev, indio_dev);
|
||||
}
|
||||
|
||||
@ -507,8 +462,6 @@ static int __maybe_unused rzg2l_adc_pm_runtime_suspend(struct device *dev)
|
||||
struct rzg2l_adc *adc = iio_priv(indio_dev);
|
||||
|
||||
rzg2l_adc_pwr(adc, false);
|
||||
clk_disable_unprepare(adc->adclk);
|
||||
clk_disable_unprepare(adc->pclk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -517,17 +470,6 @@ static int __maybe_unused rzg2l_adc_pm_runtime_resume(struct device *dev)
|
||||
{
|
||||
struct iio_dev *indio_dev = dev_get_drvdata(dev);
|
||||
struct rzg2l_adc *adc = iio_priv(indio_dev);
|
||||
int ret;
|
||||
|
||||
ret = clk_prepare_enable(adc->pclk);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = clk_prepare_enable(adc->adclk);
|
||||
if (ret) {
|
||||
clk_disable_unprepare(adc->pclk);
|
||||
return ret;
|
||||
}
|
||||
|
||||
rzg2l_adc_pwr(adc, true);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user