From: Andy Green <[EMAIL PROTECTED]>

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 <[EMAIL PROTECTED]>
---

 drivers/i2c/chips/pcf50606.c |   29 ++++++++---------------------
 1 files changed, 8 insertions(+), 21 deletions(-)


diff --git a/drivers/i2c/chips/pcf50606.c b/drivers/i2c/chips/pcf50606.c
index e6eb036..def2d35 100644
--- a/drivers/i2c/chips/pcf50606.c
+++ b/drivers/i2c/chips/pcf50606.c
@@ -102,6 +102,7 @@ struct pcf50606_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;
@@ -564,6 +565,7 @@ static void pcf50606_work(struct work_struct *work)
                        container_of(work, struct pcf50606_data, work);
        u_int8_t int1, int2, int3;
 
+       mutex_lock(&pcf->working_lock);
        pcf->working = 1;
 
        int1 = __reg_read(pcf, PCF50606_REG_INT1);
@@ -742,32 +744,18 @@ static void pcf50606_work(struct work_struct *work)
        pcf->working = 0;
        input_sync(pcf->input_dev);
        put_device(&pcf->client.dev);
-
-       enable_irq(pcf->irq);
-}
-
-static void pcf50606_schedule_work(struct pcf50606_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");
+       mutex_unlock(&pcf->working_lock);
 }
 
-
 static irqreturn_t pcf50606_irq(int irq, void *_pcf)
 {
        struct pcf50606_data *pcf = _pcf;
 
        dev_dbg(&pcf->client.dev, "entering(irq=%u, pcf=%p): scheduling work\n",
                irq, _pcf);
-       pcf50606_schedule_work(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;
 }
@@ -1593,6 +1581,7 @@ static int pcf50606_detect(struct i2c_adapter *adapter, 
int address, int kind)
                return -ENOMEM;
 
        mutex_init(&data->lock);
+       mutex_init(&data->working_lock);
        INIT_WORK(&data->work, pcf50606_work);
        data->irq = irq;
        data->working = 0;
@@ -1654,13 +1643,11 @@ static int pcf50606_detect(struct i2c_adapter *adapter, 
int address, int kind)
        reg_write(data, PCF50606_REG_INT2M, 0x00);
        reg_write(data, PCF50606_REG_INT3M, PCF50606_INT3_TSCPRES);
 
-       err = request_irq(irq, pcf50606_irq, IRQF_DISABLED,
+       err = request_irq(irq, pcf50606_irq, IRQF_TRIGGER_FALLING,
                          "pcf50606", 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);


Reply via email to