summaryrefslogtreecommitdiff
path: root/target/linux/s3c24xx/patches-2.6.24/1185-fix-pcf50633-interrupt-work-enforce-wait-on-resume-c.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/s3c24xx/patches-2.6.24/1185-fix-pcf50633-interrupt-work-enforce-wait-on-resume-c.patch')
-rw-r--r--target/linux/s3c24xx/patches-2.6.24/1185-fix-pcf50633-interrupt-work-enforce-wait-on-resume-c.patch134
1 files changed, 0 insertions, 134 deletions
diff --git a/target/linux/s3c24xx/patches-2.6.24/1185-fix-pcf50633-interrupt-work-enforce-wait-on-resume-c.patch b/target/linux/s3c24xx/patches-2.6.24/1185-fix-pcf50633-interrupt-work-enforce-wait-on-resume-c.patch
deleted file mode 100644
index be03e13..0000000
--- a/target/linux/s3c24xx/patches-2.6.24/1185-fix-pcf50633-interrupt-work-enforce-wait-on-resume-c.patch
+++ /dev/null
@@ -1,134 +0,0 @@
-From ac949375c7ef5882e8d3ea4f4a165b2fce943f21 Mon Sep 17 00:00:00 2001
-From: Andy Green <andy@openmoko.com>
-Date: Wed, 2 Jul 2008 22:39:56 +0100
-Subject: [PATCH] fix-pcf50633-interrupt-work-enforce-wait-on-resume-completion.patch
-
-Improve pcf50633 interrupt service scheduling to enforce only servicing
-when resume action is completed
-
-Signed-off-by: Andy Green <andy@openmoko.com>
----
- drivers/i2c/chips/pcf50633.c | 67 ++++++++++++++++++++++++++++++------------
- 1 files changed, 48 insertions(+), 19 deletions(-)
-
-diff --git a/drivers/i2c/chips/pcf50633.c b/drivers/i2c/chips/pcf50633.c
-index 4d92c84..33e2eaf 100644
---- a/drivers/i2c/chips/pcf50633.c
-+++ b/drivers/i2c/chips/pcf50633.c
-@@ -656,6 +656,26 @@ static void pcf50633_work(struct work_struct *work)
-
- mutex_lock(&pcf->working_lock);
- pcf->working = 1;
-+
-+ dev_info(&pcf->client.dev, "pcf50633_work called with suspended = %d\n",
-+ pcf->have_been_suspended);
-+
-+ /*
-+ * If we are inside suspend -> resume completion time we don't attempt
-+ * service until we have fully resumed. Although we could talk to the
-+ * device as soon as I2C is up, the regs in the device which we might
-+ * choose to modify as part of the service action have not been
-+ * reloaded with their pre-suspend states yet. Therefore we will
-+ * defer our service if we are called like that until our resume has
-+ * completed.
-+ */
-+
-+ if (pcf->have_been_suspended && (pcf->have_been_suspended < 2)) {
-+ dev_info(&pcf->client.dev, "rescheduling, suspended = %d\n",
-+ pcf->have_been_suspended);
-+ goto reschedule;
-+ }
-+
- /*
- * datasheet says we have to read the five IRQ
- * status regs in one transaction
-@@ -663,30 +683,25 @@ static void pcf50633_work(struct work_struct *work)
- ret = i2c_smbus_read_i2c_block_data(&pcf->client, PCF50633_REG_INT1, 5,
- pcfirq);
- if (ret != 5) {
-- DEBUGP("Oh crap PMU IRQ register read failed -- "
-- "retrying later %d\n", ret);
-+ dev_info(&pcf->client.dev,
-+ "Oh crap PMU IRQ register read failed -- "
-+ "retrying later %d\n", ret);
- /*
-- * this situation can happen during resume, just defer
-- * handling the interrupt until enough I2C is up we can
-- * actually talk to the PMU. We can't just ignore this
-- * because we are on a falling edge interrupt and our
-- * PMU interrupt source does not clear until we read these
-- * interrupt source registers.
-+ * it shouldn't fail, we no longer attempt to use I2C while
-+ * it can be suspended. But we don't have much option but to
-+ * retry if if it ever did fail, because if we don't service
-+ * the interrupt to clear it, we will never see another PMU
-+ * interrupt edge.
- */
-- if (!schedule_work(&pcf->work) && !pcf->working)
-- dev_dbg(&pcf->client.dev, "work item may be lost\n");
--
-- /* we don't put the device here, hold it for next time */
-- mutex_unlock(&pcf->working_lock);
-- /* don't spew, delaying whatever else is happening */
-- msleep(1);
-- return;
-+ goto reschedule;
- }
-
- /* hey did we just resume? */
-
- if (pcf->have_been_suspended) {
-+ /* resume is officially over now then */
- pcf->have_been_suspended = 0;
-+
- /*
- * grab a copy of resume interrupt reasons
- * from pcf50633 POV
-@@ -1045,6 +1060,19 @@ static void pcf50633_work(struct work_struct *work)
- input_sync(pcf->input_dev);
- put_device(&pcf->client.dev);
- mutex_unlock(&pcf->working_lock);
-+
-+ return;
-+
-+reschedule:
-+ /* don't spew, delaying whatever else is happening */
-+ msleep(100);
-+
-+ dev_info(&pcf->client.dev, "rescheduling interrupt service\n");
-+ if (!schedule_work(&pcf->work))
-+ dev_err(&pcf->client.dev, "int service reschedule failed\n");
-+
-+ /* we don't put the device here, hold it for next time */
-+ mutex_unlock(&pcf->working_lock);
- }
-
- static irqreturn_t pcf50633_irq(int irq, void *_pcf)
-@@ -1052,10 +1080,11 @@ static irqreturn_t pcf50633_irq(int irq, void *_pcf)
- struct pcf50633_data *pcf = _pcf;
-
- DEBUGP("entering(irq=%u, pcf=%p): scheduling work\n", irq, _pcf);
-+ dev_info(&pcf->client.dev, "pcf50633_irq scheduling work\n");
-
- get_device(&pcf->client.dev);
- if (!schedule_work(&pcf->work) && !pcf->working)
-- dev_dbg(&pcf->client.dev, "work item may be lost\n");
-+ dev_err(&pcf->client.dev, "work item may be lost\n");
-
- return IRQ_HANDLED;
- }
-@@ -2244,9 +2273,9 @@ static int pcf50633_suspend(struct device *dev, pm_message_t state)
- int pcf50633_ready(struct pcf50633_data *pcf)
- {
- if (!pcf)
-- return -EBUSY;
-+ return -EACCES;
-
-- if (pcf->have_been_suspended)
-+ if (pcf->have_been_suspended && (pcf->have_been_suspended < 3))
- return -EBUSY;
-
- return 0;
---
-1.5.6.5
-