[PATCH 01/10] fix-pcf50633-set-irq-type.patch

warmcat andy at openmoko.com
Mon Feb 11 17:34:24 CET 2008


From: Andy Green <andy at openmoko.com>

Remove set_irq_type and use IRQF_FALLING with interrupt enabled all the time.
Use a mutex to stop any reentrancy

Signed-off-by: Andy Green <andy at openmoko.com>
---

 drivers/i2c/chips/pcf50633.c |   31 +++++++++----------------------
 1 files changed, 9 insertions(+), 22 deletions(-)


diff --git a/drivers/i2c/chips/pcf50633.c b/drivers/i2c/chips/pcf50633.c
index b7114d7..e68b712 100644
--- a/drivers/i2c/chips/pcf50633.c
+++ b/drivers/i2c/chips/pcf50633.c
@@ -101,6 +101,7 @@ struct pcf50633_data {
 	struct mutex lock;
 	unsigned int flags;
 	unsigned int working;
+	struct mutex working_lock;
 	struct work_struct work;
 	struct rtc_device *rtc;
 	struct input_dev *input_dev;
@@ -490,6 +491,7 @@ static void pcf50633_work(struct work_struct *work)
 			container_of(work, struct pcf50633_data, work);
 	u_int8_t int1, int2, int3, int4, int5;
 
+	mutex_lock(&pcf->working_lock);
 	pcf->working = 1;
 
 	/* FIXME: read in one i2c transaction */
@@ -665,32 +667,18 @@ static void pcf50633_work(struct work_struct *work)
 	pcf->working = 0;
 	input_sync(pcf->input_dev);
 	put_device(&pcf->client.dev);
-
-	enable_irq(pcf->irq);
+	mutex_unlock(&pcf->working_lock);
 }
 
-static void pcf50633_schedule_work(struct pcf50633_data *pcf)
-{
-	int status;
-
-	get_device(&pcf->client.dev);
-	status = schedule_work(&pcf->work);
-	if (!status && !pcf->working)
-		dev_dbg(&pcf->client.dev, "work item may be lost\n");
-}
-
-
 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);
-	pcf50633_schedule_work(pcf);
+	DEBUGP("entering(irq=%u, pcf=%p): scheduling work\n", irq, _pcf);
 
-	/* Disable any further interrupts until we have processed
-	 * the current one */
-	disable_irq(irq);
+	get_device(&pcf->client.dev);
+	if (!schedule_work(&pcf->work) && !pcf->working)
+		dev_dbg(&pcf->client.dev, "work item may be lost\n");
 
 	return IRQ_HANDLED;
 }
@@ -1435,6 +1423,7 @@ static int pcf50633_detect(struct i2c_adapter *adapter, int address, int kind)
 		return -ENOMEM;
 
 	mutex_init(&data->lock);
+	mutex_init(&data->working_lock);
 	INIT_WORK(&data->work, pcf50633_work);
 	data->irq = irq;
 	data->working = 0;
@@ -1498,13 +1487,11 @@ static int pcf50633_detect(struct i2c_adapter *adapter, int address, int kind)
 	reg_write(data, PCF50633_REG_INT4M, 0x00);
 	reg_write(data, PCF50633_REG_INT5M, 0x00);
 
-	err = request_irq(irq, pcf50633_irq, IRQF_DISABLED,
+	err = request_irq(irq, pcf50633_irq, IRQF_TRIGGER_FALLING,
 			  "pcf50633", data);
 	if (err < 0)
 		goto exit_input;
 
-	set_irq_type(irq, IRQT_FALLING);
-
 	if (enable_irq_wake(irq) < 0)
 		dev_err(&new_client->dev, "IRQ %u cannot be enabled as wake-up"
 		        "source in this hardware revision!", irq);





More information about the openmoko-kernel mailing list