diff mbox

[v4,5/5] MFD: ti_tscadc: add suspend/resume functionality

Message ID 1348636814-14129-6-git-send-email-rachna@ti.com (mailing list archive)
State New, archived
Headers show

Commit Message

Patil, Rachna Sept. 26, 2012, 5:20 a.m. UTC
This patch adds support for suspend/resume of
TSC/ADC MFDevice.

Signed-off-by: Patil, Rachna <rachna@ti.com>
---
Changes in v2:
	Added this patch newly in this patch series.

Changes in v3:
	No changes.

Changes in v4:
	Replaced suspend/resume callbacks with dev_pm_ops.

 drivers/iio/adc/ti_am335x_adc.c           |   42 +++++++++++++++++++++++++++++
 drivers/input/touchscreen/ti_am335x_tsc.c |   42 +++++++++++++++++++++++++++++
 drivers/mfd/ti_am335x_tscadc.c            |   41 +++++++++++++++++++++++++++-
 include/linux/mfd/ti_am335x_tscadc.h      |    3 ++
 4 files changed, 127 insertions(+), 1 deletions(-)

Comments

Shubhrajyoti Datta Sept. 26, 2012, 6:40 a.m. UTC | #1
On Wednesday 26 September 2012 10:50 AM, Patil, Rachna wrote:
> This patch adds support for suspend/resume of
> TSC/ADC MFDevice.
this should be merged with the patch adding support else
we may end up in a case where patch a does the runtime calls
and the call back  handlers added later.
>
> Signed-off-by: Patil, Rachna <rachna@ti.com>
> ---
> Changes in v2:
> 	Added this patch newly in this patch series.
>
> Changes in v3:
> 	No changes.
>
> Changes in v4:
> 	Replaced suspend/resume callbacks with dev_pm_ops.
>
>  drivers/iio/adc/ti_am335x_adc.c           |   42 +++++++++++++++++++++++++++++
>  drivers/input/touchscreen/ti_am335x_tsc.c |   42 +++++++++++++++++++++++++++++
>  drivers/mfd/ti_am335x_tscadc.c            |   41 +++++++++++++++++++++++++++-
>  include/linux/mfd/ti_am335x_tscadc.h      |    3 ++
>  4 files changed, 127 insertions(+), 1 deletions(-)
>
> diff --git a/drivers/iio/adc/ti_am335x_adc.c b/drivers/iio/adc/ti_am335x_adc.c
> index 9e1b3ac..b16f944 100644
> --- a/drivers/iio/adc/ti_am335x_adc.c
> +++ b/drivers/iio/adc/ti_am335x_adc.c
> @@ -200,10 +200,52 @@ static int __devexit tiadc_remove(struct platform_device *pdev)
>  	return 0;
>  }
>  
> +#ifdef CONFIG_PM
> +static int tiadc_suspend(struct device *dev)
> +{
> +	struct iio_dev *indio_dev = dev_get_drvdata(dev);
> +	struct tiadc_device *adc_dev = iio_priv(indio_dev);
> +	struct ti_tscadc_dev *tscadc_dev = dev->platform_data;
> +	unsigned int idle;
> +
> +	if (!device_may_wakeup(tscadc_dev->dev)) {
> +		idle = adc_readl(adc_dev, REG_CTRL);
> +		idle &= ~(CNTRLREG_TSCSSENB);
> +		adc_writel(adc_dev, REG_CTRL, (idle |
> +				CNTRLREG_POWERDOWN));
> +	}
> +	return 0;
> +}
> +
> +static int tiadc_resume(struct device *dev)
> +{
> +	struct iio_dev *indio_dev = dev_get_drvdata(dev);
> +	struct tiadc_device *adc_dev = iio_priv(indio_dev);
> +	unsigned int restore;
> +
> +	/* Make sure ADC is powered up */
> +	restore = adc_readl(adc_dev, REG_CTRL);
> +	restore &= ~(CNTRLREG_POWERDOWN);
> +	adc_writel(adc_dev, REG_CTRL, restore);
> +
> +	adc_step_config(adc_dev);
> +	return 0;
> +}
> +
> +static const struct dev_pm_ops tiadc_pm_ops = {
> +	.suspend = tiadc_suspend,
> +	.resume = tiadc_resume,
> +};
> +#define TIADC_PM_OPS (&tiadc_pm_ops)
> +#else
> +#define TIADC_PM_OPS NULL
> +#endif
> +
>  static struct platform_driver tiadc_driver = {
>  	.driver = {
>  		.name   = "tiadc",
>  		.owner = THIS_MODULE,
> +		.pm	= TIADC_PM_OPS,
>  	},
>  	.probe	= tiadc_probe,
>  	.remove	= __devexit_p(tiadc_remove),
> diff --git a/drivers/input/touchscreen/ti_am335x_tsc.c b/drivers/input/touchscreen/ti_am335x_tsc.c
> index 2d9dec1..b17dbe4 100644
> --- a/drivers/input/touchscreen/ti_am335x_tsc.c
> +++ b/drivers/input/touchscreen/ti_am335x_tsc.c
> @@ -338,12 +338,54 @@ static int __devexit tscadc_remove(struct platform_device *pdev)
>  	return 0;
>  }
>  
> +#ifdef CONFIG_PM
> +static int titsc_suspend(struct device *dev)
> +{
> +	struct ti_tscadc_dev *tscadc_dev = dev->platform_data;
> +	struct tscadc *ts_dev = tscadc_dev->tsc;
> +	unsigned int idle;
> +
> +	if (device_may_wakeup(tscadc_dev->dev)) {
> +		idle = tscadc_readl(ts_dev, REG_IRQENABLE);
> +		tscadc_writel(ts_dev, REG_IRQENABLE,
> +				(idle | IRQENB_HW_PEN));
> +		tscadc_writel(ts_dev, REG_IRQWAKEUP, IRQWKUP_ENB);
> +	}
> +	return 0;
> +}
> +
> +static int titsc_resume(struct device *dev)
> +{
> +	struct ti_tscadc_dev *tscadc_dev = dev->platform_data;
> +	struct tscadc *ts_dev = tscadc_dev->tsc;
> +
> +	if (device_may_wakeup(tscadc_dev->dev)) {
> +		tscadc_writel(ts_dev, REG_IRQWAKEUP,
> +				0x00);
> +		tscadc_writel(ts_dev, REG_IRQCLR, IRQENB_HW_PEN);
> +	}
> +	tscadc_step_config(ts_dev);
> +	tscadc_writel(ts_dev, REG_FIFO0THR,
> +			ts_dev->steps_to_configure);
> +	return 0;
> +}
> +
> +static const struct dev_pm_ops titsc_pm_ops = {
> +	.suspend = titsc_suspend,
> +	.resume  = titsc_resume,
> +};
> +#define TITSC_PM_OPS (&titsc_pm_ops)
> +#else
> +#define TITSC_PM_OPS NULL
> +#endif
> +
>  static struct platform_driver ti_tsc_driver = {
>  	.probe	= tscadc_probe,
>  	.remove	= __devexit_p(tscadc_remove),
>  	.driver	= {
>  		.name   = "tsc",
>  		.owner	= THIS_MODULE,
> +		.pm	= TITSC_PM_OPS,
>  	},
>  };
>  module_platform_driver(ti_tsc_driver);
> diff --git a/drivers/mfd/ti_am335x_tscadc.c b/drivers/mfd/ti_am335x_tscadc.c
> index 45d66e5..7e949e8 100644
> --- a/drivers/mfd/ti_am335x_tscadc.c
> +++ b/drivers/mfd/ti_am335x_tscadc.c
> @@ -170,6 +170,7 @@ static	int __devinit ti_tscadc_probe(struct platform_device *pdev)
>  	if (err < 0)
>  		goto err_disable_clk;
>  
> +	device_init_wakeup(&pdev->dev, true);
>  	platform_set_drvdata(pdev, tscadc);
>  	return 0;
>  
> @@ -203,14 +204,52 @@ static int __devexit ti_tscadc_remove(struct platform_device *pdev)
>  	return 0;
>  }
>  
> +#ifdef CONFIG_PM
> +static int tscadc_suspend(struct device *dev)
> +{
> +	struct ti_tscadc_dev	*tscadc_dev = dev_get_drvdata(dev);
> +
> +	tscadc_writel(tscadc_dev, REG_SE, 0x00);
> +	pm_runtime_put_sync(dev);
> +	return 0;
> +}
> +
> +static int tscadc_resume(struct device *dev)
> +{
> +	struct ti_tscadc_dev	*tscadc_dev = dev_get_drvdata(dev);
> +	unsigned int restore, ctrl;
> +
> +	pm_runtime_get_sync(dev);
> +
> +	/* context restore */
> +	ctrl = CNTRLREG_STEPCONFIGWRT | CNTRLREG_TSCENB |
> +			CNTRLREG_STEPID | CNTRLREG_4WIRE;
> +	tscadc_writel(tscadc_dev, REG_CTRL, ctrl);
> +	tscadc_idle_config(tscadc_dev);
> +	tscadc_writel(tscadc_dev, REG_SE, STPENB_STEPENB);
> +	restore = tscadc_readl(tscadc_dev, REG_CTRL);
> +	tscadc_writel(tscadc_dev, REG_CTRL,
> +			(restore | CNTRLREG_TSCSSENB));
> +	return 0;
> +}
> +
> +static const struct dev_pm_ops tscadc_pm_ops = {
> +	.suspend = tscadc_suspend,
> +	.resume = tscadc_resume,
> +};
> +#define TSCADC_PM_OPS (&tscadc_pm_ops)
> +#else
> +#define TSCADC_PM_OPS NULL
> +#endif
> +
>  static struct platform_driver ti_tscadc_driver = {
>  	.driver = {
>  		.name   = "ti_tscadc",
>  		.owner	= THIS_MODULE,
> +		.pm	= TSCADC_PM_OPS,
>  	},
>  	.probe	= ti_tscadc_probe,
>  	.remove	= __devexit_p(ti_tscadc_remove),
> -
>  };
>  
>  module_platform_driver(ti_tscadc_driver);
> diff --git a/include/linux/mfd/ti_am335x_tscadc.h b/include/linux/mfd/ti_am335x_tscadc.h
> index bd9fe1d..c7facdc 100644
> --- a/include/linux/mfd/ti_am335x_tscadc.h
> +++ b/include/linux/mfd/ti_am335x_tscadc.h
> @@ -40,6 +40,9 @@
>  #define REG_FIFO1		0x200
>  
>  /*	Register Bitfields	*/
> +/* IRQ wakeup enable */
> +#define IRQWKUP_ENB		BIT(0)
> +
>  /* Step Enable */
>  #define STEPENB_MASK		(0x1FFFF << 0)
>  #define STEPENB(val)		((val) << 0)

--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Patil, Rachna Sept. 26, 2012, 10:09 a.m. UTC | #2
Hi Shubhrajyoti,

On Wed, Sep 26, 2012 at 12:10:51, Datta, Shubhrajyoti wrote:
> On Wednesday 26 September 2012 10:50 AM, Patil, Rachna wrote:
> > This patch adds support for suspend/resume of
> > TSC/ADC MFDevice.
> this should be merged with the patch adding support else
> we may end up in a case where patch a does the runtime calls
> and the call back  handlers added later.

I am adding both the runtime calls and the handlers in this patch.
I think maintaining this as a separate patch in better in terms
of readability as well.

Regards,
Rachna

> >
> > Signed-off-by: Patil, Rachna <rachna@ti.com>
> > ---
> > Changes in v2:
> > 	Added this patch newly in this patch series.
> >
> > Changes in v3:
> > 	No changes.
> >
> > Changes in v4:
> > 	Replaced suspend/resume callbacks with dev_pm_ops.
> >
> >  drivers/iio/adc/ti_am335x_adc.c           |   42 +++++++++++++++++++++++++++++
> >  drivers/input/touchscreen/ti_am335x_tsc.c |   42 +++++++++++++++++++++++++++++
> >  drivers/mfd/ti_am335x_tscadc.c            |   41 +++++++++++++++++++++++++++-
> >  include/linux/mfd/ti_am335x_tscadc.h      |    3 ++
> >  4 files changed, 127 insertions(+), 1 deletions(-)
> >
> > diff --git a/drivers/iio/adc/ti_am335x_adc.c b/drivers/iio/adc/ti_am335x_adc.c
> > index 9e1b3ac..b16f944 100644
> > --- a/drivers/iio/adc/ti_am335x_adc.c
> > +++ b/drivers/iio/adc/ti_am335x_adc.c
> > @@ -200,10 +200,52 @@ static int __devexit tiadc_remove(struct platform_device *pdev)
> >  	return 0;
> >  }
> >  
> > +#ifdef CONFIG_PM
> > +static int tiadc_suspend(struct device *dev)
> > +{
> > +	struct iio_dev *indio_dev = dev_get_drvdata(dev);
> > +	struct tiadc_device *adc_dev = iio_priv(indio_dev);
> > +	struct ti_tscadc_dev *tscadc_dev = dev->platform_data;
> > +	unsigned int idle;
> > +
> > +	if (!device_may_wakeup(tscadc_dev->dev)) {
> > +		idle = adc_readl(adc_dev, REG_CTRL);
> > +		idle &= ~(CNTRLREG_TSCSSENB);
> > +		adc_writel(adc_dev, REG_CTRL, (idle |
> > +				CNTRLREG_POWERDOWN));
> > +	}
> > +	return 0;
> > +}
> > +
> > +static int tiadc_resume(struct device *dev)
> > +{
> > +	struct iio_dev *indio_dev = dev_get_drvdata(dev);
> > +	struct tiadc_device *adc_dev = iio_priv(indio_dev);
> > +	unsigned int restore;
> > +
> > +	/* Make sure ADC is powered up */
> > +	restore = adc_readl(adc_dev, REG_CTRL);
> > +	restore &= ~(CNTRLREG_POWERDOWN);
> > +	adc_writel(adc_dev, REG_CTRL, restore);
> > +
> > +	adc_step_config(adc_dev);
> > +	return 0;
> > +}
> > +
> > +static const struct dev_pm_ops tiadc_pm_ops = {
> > +	.suspend = tiadc_suspend,
> > +	.resume = tiadc_resume,
> > +};
> > +#define TIADC_PM_OPS (&tiadc_pm_ops)
> > +#else
> > +#define TIADC_PM_OPS NULL
> > +#endif
> > +
> >  static struct platform_driver tiadc_driver = {
> >  	.driver = {
> >  		.name   = "tiadc",
> >  		.owner = THIS_MODULE,
> > +		.pm	= TIADC_PM_OPS,
> >  	},
> >  	.probe	= tiadc_probe,
> >  	.remove	= __devexit_p(tiadc_remove),
> > diff --git a/drivers/input/touchscreen/ti_am335x_tsc.c b/drivers/input/touchscreen/ti_am335x_tsc.c
> > index 2d9dec1..b17dbe4 100644
> > --- a/drivers/input/touchscreen/ti_am335x_tsc.c
> > +++ b/drivers/input/touchscreen/ti_am335x_tsc.c
> > @@ -338,12 +338,54 @@ static int __devexit tscadc_remove(struct platform_device *pdev)
> >  	return 0;
> >  }
> >  
> > +#ifdef CONFIG_PM
> > +static int titsc_suspend(struct device *dev)
> > +{
> > +	struct ti_tscadc_dev *tscadc_dev = dev->platform_data;
> > +	struct tscadc *ts_dev = tscadc_dev->tsc;
> > +	unsigned int idle;
> > +
> > +	if (device_may_wakeup(tscadc_dev->dev)) {
> > +		idle = tscadc_readl(ts_dev, REG_IRQENABLE);
> > +		tscadc_writel(ts_dev, REG_IRQENABLE,
> > +				(idle | IRQENB_HW_PEN));
> > +		tscadc_writel(ts_dev, REG_IRQWAKEUP, IRQWKUP_ENB);
> > +	}
> > +	return 0;
> > +}
> > +
> > +static int titsc_resume(struct device *dev)
> > +{
> > +	struct ti_tscadc_dev *tscadc_dev = dev->platform_data;
> > +	struct tscadc *ts_dev = tscadc_dev->tsc;
> > +
> > +	if (device_may_wakeup(tscadc_dev->dev)) {
> > +		tscadc_writel(ts_dev, REG_IRQWAKEUP,
> > +				0x00);
> > +		tscadc_writel(ts_dev, REG_IRQCLR, IRQENB_HW_PEN);
> > +	}
> > +	tscadc_step_config(ts_dev);
> > +	tscadc_writel(ts_dev, REG_FIFO0THR,
> > +			ts_dev->steps_to_configure);
> > +	return 0;
> > +}
> > +
> > +static const struct dev_pm_ops titsc_pm_ops = {
> > +	.suspend = titsc_suspend,
> > +	.resume  = titsc_resume,
> > +};
> > +#define TITSC_PM_OPS (&titsc_pm_ops)
> > +#else
> > +#define TITSC_PM_OPS NULL
> > +#endif
> > +
> >  static struct platform_driver ti_tsc_driver = {
> >  	.probe	= tscadc_probe,
> >  	.remove	= __devexit_p(tscadc_remove),
> >  	.driver	= {
> >  		.name   = "tsc",
> >  		.owner	= THIS_MODULE,
> > +		.pm	= TITSC_PM_OPS,
> >  	},
> >  };
> >  module_platform_driver(ti_tsc_driver);
> > diff --git a/drivers/mfd/ti_am335x_tscadc.c b/drivers/mfd/ti_am335x_tscadc.c
> > index 45d66e5..7e949e8 100644
> > --- a/drivers/mfd/ti_am335x_tscadc.c
> > +++ b/drivers/mfd/ti_am335x_tscadc.c
> > @@ -170,6 +170,7 @@ static	int __devinit ti_tscadc_probe(struct platform_device *pdev)
> >  	if (err < 0)
> >  		goto err_disable_clk;
> >  
> > +	device_init_wakeup(&pdev->dev, true);
> >  	platform_set_drvdata(pdev, tscadc);
> >  	return 0;
> >  
> > @@ -203,14 +204,52 @@ static int __devexit ti_tscadc_remove(struct platform_device *pdev)
> >  	return 0;
> >  }
> >  
> > +#ifdef CONFIG_PM
> > +static int tscadc_suspend(struct device *dev)
> > +{
> > +	struct ti_tscadc_dev	*tscadc_dev = dev_get_drvdata(dev);
> > +
> > +	tscadc_writel(tscadc_dev, REG_SE, 0x00);
> > +	pm_runtime_put_sync(dev);
> > +	return 0;
> > +}
> > +
> > +static int tscadc_resume(struct device *dev)
> > +{
> > +	struct ti_tscadc_dev	*tscadc_dev = dev_get_drvdata(dev);
> > +	unsigned int restore, ctrl;
> > +
> > +	pm_runtime_get_sync(dev);
> > +
> > +	/* context restore */
> > +	ctrl = CNTRLREG_STEPCONFIGWRT | CNTRLREG_TSCENB |
> > +			CNTRLREG_STEPID | CNTRLREG_4WIRE;
> > +	tscadc_writel(tscadc_dev, REG_CTRL, ctrl);
> > +	tscadc_idle_config(tscadc_dev);
> > +	tscadc_writel(tscadc_dev, REG_SE, STPENB_STEPENB);
> > +	restore = tscadc_readl(tscadc_dev, REG_CTRL);
> > +	tscadc_writel(tscadc_dev, REG_CTRL,
> > +			(restore | CNTRLREG_TSCSSENB));
> > +	return 0;
> > +}
> > +
> > +static const struct dev_pm_ops tscadc_pm_ops = {
> > +	.suspend = tscadc_suspend,
> > +	.resume = tscadc_resume,
> > +};
> > +#define TSCADC_PM_OPS (&tscadc_pm_ops)
> > +#else
> > +#define TSCADC_PM_OPS NULL
> > +#endif
> > +
> >  static struct platform_driver ti_tscadc_driver = {
> >  	.driver = {
> >  		.name   = "ti_tscadc",
> >  		.owner	= THIS_MODULE,
> > +		.pm	= TSCADC_PM_OPS,
> >  	},
> >  	.probe	= ti_tscadc_probe,
> >  	.remove	= __devexit_p(ti_tscadc_remove),
> > -
> >  };
> >  
> >  module_platform_driver(ti_tscadc_driver);
> > diff --git a/include/linux/mfd/ti_am335x_tscadc.h b/include/linux/mfd/ti_am335x_tscadc.h
> > index bd9fe1d..c7facdc 100644
> > --- a/include/linux/mfd/ti_am335x_tscadc.h
> > +++ b/include/linux/mfd/ti_am335x_tscadc.h
> > @@ -40,6 +40,9 @@
> >  #define REG_FIFO1		0x200
> >  
> >  /*	Register Bitfields	*/
> > +/* IRQ wakeup enable */
> > +#define IRQWKUP_ENB		BIT(0)
> > +
> >  /* Step Enable */
> >  #define STEPENB_MASK		(0x1FFFF << 0)
> >  #define STEPENB(val)		((val) << 0)
> 
> 

--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Jonathan Cameron Sept. 29, 2012, 9:50 a.m. UTC | #3
On 09/26/2012 11:09 AM, Patil, Rachna wrote:
> Hi Shubhrajyoti,
> 
> On Wed, Sep 26, 2012 at 12:10:51, Datta, Shubhrajyoti wrote:
>> On Wednesday 26 September 2012 10:50 AM, Patil, Rachna wrote:
>>> This patch adds support for suspend/resume of
>>> TSC/ADC MFDevice.
>> this should be merged with the patch adding support else
>> we may end up in a case where patch a does the runtime calls
>> and the call back  handlers added later.
> 
> I am adding both the runtime calls and the handlers in this patch.
> I think maintaining this as a separate patch in better in terms
> of readability as well.
I would prefer this merged into patch 4 as it's a simple addition to
a driver that should arguably have been there in the first place.

Anyhow I don't actually care that much!
> 
> Regards,
> Rachna
> 
>>>
>>> Signed-off-by: Patil, Rachna <rachna@ti.com>
Acked-by: Jonathan Cameron <jic23@kernel.org>
(if someone else is picking this series up). I'll happily
take it through IIO post merge window.

Sorry Rachna, I know this was ready a week ago, but that's still
cutting it fine for the end of the cycle.

Now if someone else wants to take it I'll not mind ;)
>>> ---
>>> Changes in v2:
>>> 	Added this patch newly in this patch series.
>>>
>>> Changes in v3:
>>> 	No changes.
>>>
>>> Changes in v4:
>>> 	Replaced suspend/resume callbacks with dev_pm_ops.
>>>
>>>  drivers/iio/adc/ti_am335x_adc.c           |   42 +++++++++++++++++++++++++++++
>>>  drivers/input/touchscreen/ti_am335x_tsc.c |   42 +++++++++++++++++++++++++++++
>>>  drivers/mfd/ti_am335x_tscadc.c            |   41 +++++++++++++++++++++++++++-
>>>  include/linux/mfd/ti_am335x_tscadc.h      |    3 ++
>>>  4 files changed, 127 insertions(+), 1 deletions(-)
>>>
>>> diff --git a/drivers/iio/adc/ti_am335x_adc.c b/drivers/iio/adc/ti_am335x_adc.c
>>> index 9e1b3ac..b16f944 100644
>>> --- a/drivers/iio/adc/ti_am335x_adc.c
>>> +++ b/drivers/iio/adc/ti_am335x_adc.c
>>> @@ -200,10 +200,52 @@ static int __devexit tiadc_remove(struct platform_device *pdev)
>>>  	return 0;
>>>  }
>>>  
>>> +#ifdef CONFIG_PM
>>> +static int tiadc_suspend(struct device *dev)
>>> +{
>>> +	struct iio_dev *indio_dev = dev_get_drvdata(dev);
>>> +	struct tiadc_device *adc_dev = iio_priv(indio_dev);
>>> +	struct ti_tscadc_dev *tscadc_dev = dev->platform_data;
>>> +	unsigned int idle;
>>> +
>>> +	if (!device_may_wakeup(tscadc_dev->dev)) {
>>> +		idle = adc_readl(adc_dev, REG_CTRL);
>>> +		idle &= ~(CNTRLREG_TSCSSENB);
>>> +		adc_writel(adc_dev, REG_CTRL, (idle |
>>> +				CNTRLREG_POWERDOWN));
>>> +	}
>>> +	return 0;
>>> +}
>>> +
>>> +static int tiadc_resume(struct device *dev)
>>> +{
>>> +	struct iio_dev *indio_dev = dev_get_drvdata(dev);
>>> +	struct tiadc_device *adc_dev = iio_priv(indio_dev);
>>> +	unsigned int restore;
>>> +
>>> +	/* Make sure ADC is powered up */
>>> +	restore = adc_readl(adc_dev, REG_CTRL);
>>> +	restore &= ~(CNTRLREG_POWERDOWN);
>>> +	adc_writel(adc_dev, REG_CTRL, restore);
>>> +
>>> +	adc_step_config(adc_dev);
>>> +	return 0;
>>> +}
>>> +
>>> +static const struct dev_pm_ops tiadc_pm_ops = {
>>> +	.suspend = tiadc_suspend,
>>> +	.resume = tiadc_resume,
>>> +};
>>> +#define TIADC_PM_OPS (&tiadc_pm_ops)
>>> +#else
>>> +#define TIADC_PM_OPS NULL
>>> +#endif
>>> +
>>>  static struct platform_driver tiadc_driver = {
>>>  	.driver = {
>>>  		.name   = "tiadc",
>>>  		.owner = THIS_MODULE,
>>> +		.pm	= TIADC_PM_OPS,
>>>  	},
>>>  	.probe	= tiadc_probe,
>>>  	.remove	= __devexit_p(tiadc_remove),
>>> diff --git a/drivers/input/touchscreen/ti_am335x_tsc.c b/drivers/input/touchscreen/ti_am335x_tsc.c
>>> index 2d9dec1..b17dbe4 100644
>>> --- a/drivers/input/touchscreen/ti_am335x_tsc.c
>>> +++ b/drivers/input/touchscreen/ti_am335x_tsc.c
>>> @@ -338,12 +338,54 @@ static int __devexit tscadc_remove(struct platform_device *pdev)
>>>  	return 0;
>>>  }
>>>  
>>> +#ifdef CONFIG_PM
>>> +static int titsc_suspend(struct device *dev)
>>> +{
>>> +	struct ti_tscadc_dev *tscadc_dev = dev->platform_data;
>>> +	struct tscadc *ts_dev = tscadc_dev->tsc;
>>> +	unsigned int idle;
>>> +
>>> +	if (device_may_wakeup(tscadc_dev->dev)) {
>>> +		idle = tscadc_readl(ts_dev, REG_IRQENABLE);
>>> +		tscadc_writel(ts_dev, REG_IRQENABLE,
>>> +				(idle | IRQENB_HW_PEN));
>>> +		tscadc_writel(ts_dev, REG_IRQWAKEUP, IRQWKUP_ENB);
>>> +	}
>>> +	return 0;
>>> +}
>>> +
>>> +static int titsc_resume(struct device *dev)
>>> +{
>>> +	struct ti_tscadc_dev *tscadc_dev = dev->platform_data;
>>> +	struct tscadc *ts_dev = tscadc_dev->tsc;
>>> +
>>> +	if (device_may_wakeup(tscadc_dev->dev)) {
>>> +		tscadc_writel(ts_dev, REG_IRQWAKEUP,
>>> +				0x00);
>>> +		tscadc_writel(ts_dev, REG_IRQCLR, IRQENB_HW_PEN);
>>> +	}
>>> +	tscadc_step_config(ts_dev);
>>> +	tscadc_writel(ts_dev, REG_FIFO0THR,
>>> +			ts_dev->steps_to_configure);
>>> +	return 0;
>>> +}
>>> +
>>> +static const struct dev_pm_ops titsc_pm_ops = {
>>> +	.suspend = titsc_suspend,
>>> +	.resume  = titsc_resume,
>>> +};
>>> +#define TITSC_PM_OPS (&titsc_pm_ops)
>>> +#else
>>> +#define TITSC_PM_OPS NULL
>>> +#endif
>>> +
>>>  static struct platform_driver ti_tsc_driver = {
>>>  	.probe	= tscadc_probe,
>>>  	.remove	= __devexit_p(tscadc_remove),
>>>  	.driver	= {
>>>  		.name   = "tsc",
>>>  		.owner	= THIS_MODULE,
>>> +		.pm	= TITSC_PM_OPS,
>>>  	},
>>>  };
>>>  module_platform_driver(ti_tsc_driver);
>>> diff --git a/drivers/mfd/ti_am335x_tscadc.c b/drivers/mfd/ti_am335x_tscadc.c
>>> index 45d66e5..7e949e8 100644
>>> --- a/drivers/mfd/ti_am335x_tscadc.c
>>> +++ b/drivers/mfd/ti_am335x_tscadc.c
>>> @@ -170,6 +170,7 @@ static	int __devinit ti_tscadc_probe(struct platform_device *pdev)
>>>  	if (err < 0)
>>>  		goto err_disable_clk;
>>>  
>>> +	device_init_wakeup(&pdev->dev, true);
>>>  	platform_set_drvdata(pdev, tscadc);
>>>  	return 0;
>>>  
>>> @@ -203,14 +204,52 @@ static int __devexit ti_tscadc_remove(struct platform_device *pdev)
>>>  	return 0;
>>>  }
>>>  
>>> +#ifdef CONFIG_PM
>>> +static int tscadc_suspend(struct device *dev)
>>> +{
>>> +	struct ti_tscadc_dev	*tscadc_dev = dev_get_drvdata(dev);
>>> +
>>> +	tscadc_writel(tscadc_dev, REG_SE, 0x00);
>>> +	pm_runtime_put_sync(dev);
>>> +	return 0;
>>> +}
>>> +
>>> +static int tscadc_resume(struct device *dev)
>>> +{
>>> +	struct ti_tscadc_dev	*tscadc_dev = dev_get_drvdata(dev);
>>> +	unsigned int restore, ctrl;
>>> +
>>> +	pm_runtime_get_sync(dev);
>>> +
>>> +	/* context restore */
>>> +	ctrl = CNTRLREG_STEPCONFIGWRT | CNTRLREG_TSCENB |
>>> +			CNTRLREG_STEPID | CNTRLREG_4WIRE;
>>> +	tscadc_writel(tscadc_dev, REG_CTRL, ctrl);
>>> +	tscadc_idle_config(tscadc_dev);
>>> +	tscadc_writel(tscadc_dev, REG_SE, STPENB_STEPENB);
>>> +	restore = tscadc_readl(tscadc_dev, REG_CTRL);
>>> +	tscadc_writel(tscadc_dev, REG_CTRL,
>>> +			(restore | CNTRLREG_TSCSSENB));
>>> +	return 0;
>>> +}
>>> +
>>> +static const struct dev_pm_ops tscadc_pm_ops = {
>>> +	.suspend = tscadc_suspend,
>>> +	.resume = tscadc_resume,
>>> +};
>>> +#define TSCADC_PM_OPS (&tscadc_pm_ops)
>>> +#else
>>> +#define TSCADC_PM_OPS NULL
>>> +#endif
>>> +
>>>  static struct platform_driver ti_tscadc_driver = {
>>>  	.driver = {
>>>  		.name   = "ti_tscadc",
>>>  		.owner	= THIS_MODULE,
>>> +		.pm	= TSCADC_PM_OPS,
>>>  	},
>>>  	.probe	= ti_tscadc_probe,
>>>  	.remove	= __devexit_p(ti_tscadc_remove),
>>> -
>>>  };
>>>  
>>>  module_platform_driver(ti_tscadc_driver);
>>> diff --git a/include/linux/mfd/ti_am335x_tscadc.h b/include/linux/mfd/ti_am335x_tscadc.h
>>> index bd9fe1d..c7facdc 100644
>>> --- a/include/linux/mfd/ti_am335x_tscadc.h
>>> +++ b/include/linux/mfd/ti_am335x_tscadc.h
>>> @@ -40,6 +40,9 @@
>>>  #define REG_FIFO1		0x200
>>>  
>>>  /*	Register Bitfields	*/
>>> +/* IRQ wakeup enable */
>>> +#define IRQWKUP_ENB		BIT(0)
>>> +
>>>  /* Step Enable */
>>>  #define STEPENB_MASK		(0x1FFFF << 0)
>>>  #define STEPENB(val)		((val) << 0)
>>
>>
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-iio" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Samuel Ortiz Sept. 30, 2012, 11:22 p.m. UTC | #4
Hi Jonathan,

On Sat, Sep 29, 2012 at 10:50:19AM +0100, Jonathan Cameron wrote:
> On 09/26/2012 11:09 AM, Patil, Rachna wrote:
> > Hi Shubhrajyoti,
> > 
> > On Wed, Sep 26, 2012 at 12:10:51, Datta, Shubhrajyoti wrote:
> >> On Wednesday 26 September 2012 10:50 AM, Patil, Rachna wrote:
> >>> This patch adds support for suspend/resume of
> >>> TSC/ADC MFDevice.
> >> this should be merged with the patch adding support else
> >> we may end up in a case where patch a does the runtime calls
> >> and the call back  handlers added later.
> > 
> > I am adding both the runtime calls and the handlers in this patch.
> > I think maintaining this as a separate patch in better in terms
> > of readability as well.
> I would prefer this merged into patch 4 as it's a simple addition to
> a driver that should arguably have been there in the first place.
I agree. And I would even go as far as saying that having all the MFD parts
from this patchset merged into patch #2 would make sense.
Rachna, could you please re-work this patchset in such way, and adress my
comments on patch #2 ? I could then take the MFD parts and then Jonathan and
Dmitry take their parts. There are build time dependencies, but neither the
input nor the ADC driver could be actually built as long as the MFD one is not
merged (provided that the subdevices driver comes with the right Kconfig
dependecy).

Cheers,
Samuel.
Patil, Rachna Oct. 3, 2012, 6:49 a.m. UTC | #5
Hi Samuel,

Hi On Mon, Oct 01, 2012 at 04:52:02, Samuel Ortiz wrote:
> Hi Jonathan,
> 
> On Sat, Sep 29, 2012 at 10:50:19AM +0100, Jonathan Cameron wrote:
> > On 09/26/2012 11:09 AM, Patil, Rachna wrote:
> > > Hi Shubhrajyoti,
> > > 
> > > On Wed, Sep 26, 2012 at 12:10:51, Datta, Shubhrajyoti wrote:
> > >> On Wednesday 26 September 2012 10:50 AM, Patil, Rachna wrote:
> > >>> This patch adds support for suspend/resume of TSC/ADC MFDevice.
> > >> this should be merged with the patch adding support else we may end 
> > >> up in a case where patch a does the runtime calls and the call back  
> > >> handlers added later.
> > > 
> > > I am adding both the runtime calls and the handlers in this patch.
> > > I think maintaining this as a separate patch in better in terms of 
> > > readability as well.
> > I would prefer this merged into patch 4 as it's a simple addition to a 
> > driver that should arguably have been there in the first place.
> I agree. And I would even go as far as saying that having all the MFD parts from this patchset merged into patch #2 would make sense.
> Rachna, could you please re-work this patchset in such way, and adress my comments on patch #2 ? I could then take the MFD parts and then Jonathan and Dmitry take their parts. There are build time dependencies, but neither the input nor the ADC driver could be actually built as long as the MFD one is not merged (provided that the subdevices driver comes with the right Kconfig dependecy).

I will re-work the patchset and address all the review comments accordingly.

Thanks & Regards,
Rachna

> 
> Cheers,
> Samuel.
> 
> --
> Intel Open Source Technology Centre
> http://oss.intel.com/
> 

--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/drivers/iio/adc/ti_am335x_adc.c b/drivers/iio/adc/ti_am335x_adc.c
index 9e1b3ac..b16f944 100644
--- a/drivers/iio/adc/ti_am335x_adc.c
+++ b/drivers/iio/adc/ti_am335x_adc.c
@@ -200,10 +200,52 @@  static int __devexit tiadc_remove(struct platform_device *pdev)
 	return 0;
 }
 
+#ifdef CONFIG_PM
+static int tiadc_suspend(struct device *dev)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct tiadc_device *adc_dev = iio_priv(indio_dev);
+	struct ti_tscadc_dev *tscadc_dev = dev->platform_data;
+	unsigned int idle;
+
+	if (!device_may_wakeup(tscadc_dev->dev)) {
+		idle = adc_readl(adc_dev, REG_CTRL);
+		idle &= ~(CNTRLREG_TSCSSENB);
+		adc_writel(adc_dev, REG_CTRL, (idle |
+				CNTRLREG_POWERDOWN));
+	}
+	return 0;
+}
+
+static int tiadc_resume(struct device *dev)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct tiadc_device *adc_dev = iio_priv(indio_dev);
+	unsigned int restore;
+
+	/* Make sure ADC is powered up */
+	restore = adc_readl(adc_dev, REG_CTRL);
+	restore &= ~(CNTRLREG_POWERDOWN);
+	adc_writel(adc_dev, REG_CTRL, restore);
+
+	adc_step_config(adc_dev);
+	return 0;
+}
+
+static const struct dev_pm_ops tiadc_pm_ops = {
+	.suspend = tiadc_suspend,
+	.resume = tiadc_resume,
+};
+#define TIADC_PM_OPS (&tiadc_pm_ops)
+#else
+#define TIADC_PM_OPS NULL
+#endif
+
 static struct platform_driver tiadc_driver = {
 	.driver = {
 		.name   = "tiadc",
 		.owner = THIS_MODULE,
+		.pm	= TIADC_PM_OPS,
 	},
 	.probe	= tiadc_probe,
 	.remove	= __devexit_p(tiadc_remove),
diff --git a/drivers/input/touchscreen/ti_am335x_tsc.c b/drivers/input/touchscreen/ti_am335x_tsc.c
index 2d9dec1..b17dbe4 100644
--- a/drivers/input/touchscreen/ti_am335x_tsc.c
+++ b/drivers/input/touchscreen/ti_am335x_tsc.c
@@ -338,12 +338,54 @@  static int __devexit tscadc_remove(struct platform_device *pdev)
 	return 0;
 }
 
+#ifdef CONFIG_PM
+static int titsc_suspend(struct device *dev)
+{
+	struct ti_tscadc_dev *tscadc_dev = dev->platform_data;
+	struct tscadc *ts_dev = tscadc_dev->tsc;
+	unsigned int idle;
+
+	if (device_may_wakeup(tscadc_dev->dev)) {
+		idle = tscadc_readl(ts_dev, REG_IRQENABLE);
+		tscadc_writel(ts_dev, REG_IRQENABLE,
+				(idle | IRQENB_HW_PEN));
+		tscadc_writel(ts_dev, REG_IRQWAKEUP, IRQWKUP_ENB);
+	}
+	return 0;
+}
+
+static int titsc_resume(struct device *dev)
+{
+	struct ti_tscadc_dev *tscadc_dev = dev->platform_data;
+	struct tscadc *ts_dev = tscadc_dev->tsc;
+
+	if (device_may_wakeup(tscadc_dev->dev)) {
+		tscadc_writel(ts_dev, REG_IRQWAKEUP,
+				0x00);
+		tscadc_writel(ts_dev, REG_IRQCLR, IRQENB_HW_PEN);
+	}
+	tscadc_step_config(ts_dev);
+	tscadc_writel(ts_dev, REG_FIFO0THR,
+			ts_dev->steps_to_configure);
+	return 0;
+}
+
+static const struct dev_pm_ops titsc_pm_ops = {
+	.suspend = titsc_suspend,
+	.resume  = titsc_resume,
+};
+#define TITSC_PM_OPS (&titsc_pm_ops)
+#else
+#define TITSC_PM_OPS NULL
+#endif
+
 static struct platform_driver ti_tsc_driver = {
 	.probe	= tscadc_probe,
 	.remove	= __devexit_p(tscadc_remove),
 	.driver	= {
 		.name   = "tsc",
 		.owner	= THIS_MODULE,
+		.pm	= TITSC_PM_OPS,
 	},
 };
 module_platform_driver(ti_tsc_driver);
diff --git a/drivers/mfd/ti_am335x_tscadc.c b/drivers/mfd/ti_am335x_tscadc.c
index 45d66e5..7e949e8 100644
--- a/drivers/mfd/ti_am335x_tscadc.c
+++ b/drivers/mfd/ti_am335x_tscadc.c
@@ -170,6 +170,7 @@  static	int __devinit ti_tscadc_probe(struct platform_device *pdev)
 	if (err < 0)
 		goto err_disable_clk;
 
+	device_init_wakeup(&pdev->dev, true);
 	platform_set_drvdata(pdev, tscadc);
 	return 0;
 
@@ -203,14 +204,52 @@  static int __devexit ti_tscadc_remove(struct platform_device *pdev)
 	return 0;
 }
 
+#ifdef CONFIG_PM
+static int tscadc_suspend(struct device *dev)
+{
+	struct ti_tscadc_dev	*tscadc_dev = dev_get_drvdata(dev);
+
+	tscadc_writel(tscadc_dev, REG_SE, 0x00);
+	pm_runtime_put_sync(dev);
+	return 0;
+}
+
+static int tscadc_resume(struct device *dev)
+{
+	struct ti_tscadc_dev	*tscadc_dev = dev_get_drvdata(dev);
+	unsigned int restore, ctrl;
+
+	pm_runtime_get_sync(dev);
+
+	/* context restore */
+	ctrl = CNTRLREG_STEPCONFIGWRT | CNTRLREG_TSCENB |
+			CNTRLREG_STEPID | CNTRLREG_4WIRE;
+	tscadc_writel(tscadc_dev, REG_CTRL, ctrl);
+	tscadc_idle_config(tscadc_dev);
+	tscadc_writel(tscadc_dev, REG_SE, STPENB_STEPENB);
+	restore = tscadc_readl(tscadc_dev, REG_CTRL);
+	tscadc_writel(tscadc_dev, REG_CTRL,
+			(restore | CNTRLREG_TSCSSENB));
+	return 0;
+}
+
+static const struct dev_pm_ops tscadc_pm_ops = {
+	.suspend = tscadc_suspend,
+	.resume = tscadc_resume,
+};
+#define TSCADC_PM_OPS (&tscadc_pm_ops)
+#else
+#define TSCADC_PM_OPS NULL
+#endif
+
 static struct platform_driver ti_tscadc_driver = {
 	.driver = {
 		.name   = "ti_tscadc",
 		.owner	= THIS_MODULE,
+		.pm	= TSCADC_PM_OPS,
 	},
 	.probe	= ti_tscadc_probe,
 	.remove	= __devexit_p(ti_tscadc_remove),
-
 };
 
 module_platform_driver(ti_tscadc_driver);
diff --git a/include/linux/mfd/ti_am335x_tscadc.h b/include/linux/mfd/ti_am335x_tscadc.h
index bd9fe1d..c7facdc 100644
--- a/include/linux/mfd/ti_am335x_tscadc.h
+++ b/include/linux/mfd/ti_am335x_tscadc.h
@@ -40,6 +40,9 @@ 
 #define REG_FIFO1		0x200
 
 /*	Register Bitfields	*/
+/* IRQ wakeup enable */
+#define IRQWKUP_ENB		BIT(0)
+
 /* Step Enable */
 #define STEPENB_MASK		(0x1FFFF << 0)
 #define STEPENB(val)		((val) << 0)