PATCH/RFC [1/3]: lis302dl-fix-suspend-with-open-device.patch

Simon Kagstrom simon.kagstrom at gmail.com
Sat Nov 15 09:51:57 CET 2008


Fix resuming of the device

From: Simon Kagstrom <simon.kagstrom at gmail.com>

Suspend/Resume with the device open broke with the threshold patch. This
patch brings it to life again. When resuming with the device open, data
collection is re-enabled through scheduled work after the rest of the
resume.

I'm not sure why this is needed, but perhaps an (edge) interrupt is
missed during resume. I'd like input on this.

Signed-off-by: Simon Kagstrom <simon.kagstrom at gmail.com>
---

 drivers/input/misc/lis302dl.c |   19 +++++++++++++++++++
 include/linux/lis302dl.h      |    2 ++
 2 files changed, 21 insertions(+), 0 deletions(-)

diff --git a/drivers/input/misc/lis302dl.c b/drivers/input/misc/lis302dl.c
index f743a24..7b60e59 100644
--- a/drivers/input/misc/lis302dl.c
+++ b/drivers/input/misc/lis302dl.c
@@ -44,6 +44,7 @@
 #include <linux/lis302dl.h>
 
 /* Utility functions */
+static void restart_data_collection(struct work_struct *work);
 
 static u8 __reg_read(struct lis302dl_info *lis, u8 reg)
 {
@@ -632,6 +633,8 @@ static int __devinit lis302dl_probe(struct platform_device *pdev)
 	lis->input_dev->open = lis302dl_input_open;
 	lis->input_dev->close = lis302dl_input_close;
 
+	INIT_WORK(&lis->work, restart_data_collection);
+
 	rc = input_register_device(lis->input_dev);
 	if (rc) {
 		dev_err(lis->dev, "error %d registering input device\n", rc);
@@ -790,6 +793,18 @@ static int lis302dl_suspend(struct platform_device *pdev, pm_message_t state)
 	return 0;
 }
 
+static void restart_data_collection(struct work_struct *work)
+{
+	struct lis302dl_info *lis = container_of(work,
+			struct lis302dl_info, work);
+	unsigned long flags;
+
+	local_irq_save(flags);
+	/* Re-enable the data collection if the device is open */
+	__enable_data_collection(lis);
+	local_irq_restore(flags);
+}
+
 static int lis302dl_resume(struct platform_device *pdev)
 {
 	struct lis302dl_info *lis = dev_get_drvdata(&pdev->dev);
@@ -827,6 +842,10 @@ static int lis302dl_resume(struct platform_device *pdev)
 	local_irq_restore(flags);
 	enable_irq(lis->pdata->interrupt);
 
+	/* Re-enable the data collection if the device is open */
+	if (lis->flags & LIS302DL_F_INPUT_OPEN)
+		schedule_work(&lis->work);
+
 	return 0;
 }
 #else
diff --git a/include/linux/lis302dl.h b/include/linux/lis302dl.h
index f4121d9..723722b 100644
--- a/include/linux/lis302dl.h
+++ b/include/linux/lis302dl.h
@@ -4,6 +4,7 @@
 #include <linux/types.h>
 #include <linux/spi/spi.h>
 #include <linux/input.h>
+#include <linux/workqueue.h>
 
 
 struct lis302dl_info;
@@ -38,6 +39,7 @@ struct lis302dl_info {
 		int active;
 	} wakeup;
 	u_int8_t regs[0x40];
+	struct work_struct work;
 };
 
 enum lis302dl_reg {



More information about the openmoko-kernel mailing list