From a7ac4fced215c7c371c42effcfddf7ed7121b6fb Mon Sep 17 00:00:00 2001 From: Todd Poynor Date: Wed, 4 Aug 2010 20:25:59 -0700 Subject: [PATCH] cpcap: suspend/resume Disable cpcap interrupts at suspend and re-enable at resume, to avoid processing interrupts while the SPI controller is suspended. Change-Id: I26676b8ce8983bf5477f169a15d811c474c6f5a4 Signed-off-by: Todd Poynor --- drivers/mfd/cpcap-core.c | 27 +++++++++++++++++++++++++++ drivers/mfd/cpcap-irq.c | 18 ++++++++++++++++++ include/linux/spi/cpcap.h | 6 ++++++ 3 files changed, 51 insertions(+) diff --git a/drivers/mfd/cpcap-core.c b/drivers/mfd/cpcap-core.c index 78b4fbb9efc3..5015e390b77f 100644 --- a/drivers/mfd/cpcap-core.c +++ b/drivers/mfd/cpcap-core.c @@ -27,6 +27,7 @@ #include #include #include +#include struct cpcap_driver_info { struct list_head list; @@ -38,6 +39,11 @@ static int ioctl(struct inode *inode, static int __devinit cpcap_probe(struct spi_device *spi); static int __devexit cpcap_remove(struct spi_device *spi); +#ifdef CONFIG_PM +static int cpcap_suspend(struct spi_device *spi, pm_message_t mesg); +static int cpcap_resume(struct spi_device *spi); +#endif + const static struct file_operations cpcap_fops = { .owner = THIS_MODULE, .ioctl = ioctl, @@ -57,6 +63,10 @@ static struct spi_driver cpcap_driver = { }, .probe = cpcap_probe, .remove = __devexit_p(cpcap_remove), +#ifdef CONFIG_PM + .suspend = cpcap_suspend, + .resume = cpcap_resume, +#endif }; static struct platform_device cpcap_adc_device = { @@ -455,6 +465,23 @@ static void cpcap_shutdown(void) spi_unregister_driver(&cpcap_driver); } +#ifdef CONFIG_PM +static int cpcap_suspend(struct spi_device *spi, pm_message_t mesg) +{ + + struct cpcap_device *cpcap = spi_get_drvdata(spi); + + return cpcap_irq_suspend(cpcap); +} + +static int cpcap_resume(struct spi_device *spi) +{ + struct cpcap_device *cpcap = spi_get_drvdata(spi); + + return cpcap_irq_resume(cpcap); +} +#endif + subsys_initcall(cpcap_init); module_exit(cpcap_shutdown); diff --git a/drivers/mfd/cpcap-irq.c b/drivers/mfd/cpcap-irq.c index 9c133be68126..397caaae20a7 100644 --- a/drivers/mfd/cpcap-irq.c +++ b/drivers/mfd/cpcap-irq.c @@ -630,3 +630,21 @@ int cpcap_irq_sense(struct cpcap_device *cpcap, return ((val & EVENT_MASK(irq)) != 0) ? 1 : 0; } EXPORT_SYMBOL_GPL(cpcap_irq_sense); + +#ifdef CONFIG_PM +int cpcap_irq_suspend(struct cpcap_device *cpcap) +{ + struct spi_device *spi = cpcap->spi; + + disable_irq(spi->irq); + return 0; +} + +int cpcap_irq_resume(struct cpcap_device *cpcap) +{ + struct spi_device *spi = cpcap->spi; + + enable_irq(spi->irq); + return 0; +} +#endif diff --git a/include/linux/spi/cpcap.h b/include/linux/spi/cpcap.h index d0d82c4291ba..b2d9fcf303dd 100644 --- a/include/linux/spi/cpcap.h +++ b/include/linux/spi/cpcap.h @@ -717,6 +717,12 @@ int cpcap_irq_mask_get(struct cpcap_device *cpcap, enum cpcap_irqs int_event); int cpcap_irq_sense(struct cpcap_device *cpcap, enum cpcap_irqs int_event, unsigned char clear); +#ifdef CONFIG_PM +int cpcap_irq_suspend(struct cpcap_device *cpcap); + +int cpcap_irq_resume(struct cpcap_device *cpcap); +#endif + int cpcap_adc_sync_read(struct cpcap_device *cpcap, struct cpcap_adc_request *request); -- 2.34.1