From bb4024cac6fb38570fc1f8b7ba6db233c1903595 Mon Sep 17 00:00:00 2001 From: Rama Krishna Phani A Date: Wed, 13 Feb 2019 20:24:50 +0530 Subject: [PATCH] drivers: iio: adc: Add support for suspend to disk Add support to adc driver for suspend to disk feature. Free interrupts during hibernation and re-register them during resume. Change-Id: I71d2aed51f0697e712db59dcc1ef4af0fa98aae4 Signed-off-by: Rama Krishna Phani A Signed-off-by: Veera Vegivada [quic_subbaram@quicinc.com: Fixed merge conflict] Signed-off-by: Subbaraman Narayanamurthy --- drivers/iio/adc/qcom-spmi-adc5.c | 44 +++++++++++++++++++++++++++----- 1 file changed, 38 insertions(+), 6 deletions(-) diff --git a/drivers/iio/adc/qcom-spmi-adc5.c b/drivers/iio/adc/qcom-spmi-adc5.c index 0f2b983bdbce..ad435c2be706 100644 --- a/drivers/iio/adc/qcom-spmi-adc5.c +++ b/drivers/iio/adc/qcom-spmi-adc5.c @@ -154,6 +154,7 @@ struct adc5_chip { struct completion complete; struct mutex lock; const struct adc5_data *data; + int irq_eoc; }; static int adc5_read(struct adc5_chip *adc, u16 offset, u8 *data, int len) @@ -961,7 +962,7 @@ static int adc5_probe(struct platform_device *pdev) struct adc5_chip *adc; struct regmap *regmap; const char *irq_name; - int ret, irq_eoc; + int ret; u32 reg; regmap = dev_get_regmap(dev->parent, NULL); @@ -981,6 +982,8 @@ static int adc5_probe(struct platform_device *pdev) adc->dev = dev; adc->base = reg; + dev_set_drvdata(&pdev->dev, adc); + init_completion(&adc->complete); mutex_init(&adc->lock); @@ -990,17 +993,17 @@ static int adc5_probe(struct platform_device *pdev) return ret; } - irq_eoc = platform_get_irq(pdev, 0); - if (irq_eoc < 0) { - if (irq_eoc == -EPROBE_DEFER || irq_eoc == -EINVAL) - return irq_eoc; + adc->irq_eoc = platform_get_irq(pdev, 0); + if (adc->irq_eoc < 0) { + if (adc->irq_eoc == -EPROBE_DEFER || adc->irq_eoc == -EINVAL) + return adc->irq_eoc; adc->poll_eoc = true; } else { irq_name = "pm-adc5"; if (adc->data->name) irq_name = adc->data->name; - ret = devm_request_irq(dev, irq_eoc, adc5_isr, 0, + ret = devm_request_irq(dev, adc->irq_eoc, adc5_isr, 0, irq_name, adc); if (ret) return ret; @@ -1015,10 +1018,39 @@ static int adc5_probe(struct platform_device *pdev) return devm_iio_device_register(dev, indio_dev); } +static int adc_restore(struct device *dev) +{ + int ret = 0; + struct adc5_chip *adc = dev_get_drvdata(dev); + + if (adc->irq_eoc > 0) + ret = devm_request_irq(dev, adc->irq_eoc, adc5_isr, 0, + "pm-adc5", adc); + + return ret; +} + +static int adc_freeze(struct device *dev) +{ + struct adc5_chip *adc = dev_get_drvdata(dev); + + if (adc->irq_eoc > 0) + devm_free_irq(dev, adc->irq_eoc, adc); + + return 0; +} + +static const struct dev_pm_ops adc_pm_ops = { + .freeze = adc_freeze, + .thaw = adc_restore, + .restore = adc_restore, +}; + static struct platform_driver adc5_driver = { .driver = { .name = "qcom-spmi-adc5", .of_match_table = adc5_match_table, + .pm = &adc_pm_ops, }, .probe = adc5_probe, };