Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
[pandora-kernel.git] / drivers / input / touchscreen / eeti_ts.c
index 204b8a1..75f8b73 100644 (file)
@@ -124,14 +124,25 @@ static irqreturn_t eeti_ts_isr(int irq, void *dev_id)
        return IRQ_HANDLED;
 }
 
-static int eeti_ts_open(struct input_dev *dev)
+static void eeti_ts_start(struct eeti_ts_priv *priv)
 {
-       struct eeti_ts_priv *priv = input_get_drvdata(dev);
-
        enable_irq(priv->irq);
 
        /* Read the events once to arm the IRQ */
        eeti_ts_read(&priv->work);
+}
+
+static void eeti_ts_stop(struct eeti_ts_priv *priv)
+{
+       disable_irq(priv->irq);
+       cancel_work_sync(&priv->work);
+}
+
+static int eeti_ts_open(struct input_dev *dev)
+{
+       struct eeti_ts_priv *priv = input_get_drvdata(dev);
+
+       eeti_ts_start(priv);
 
        return 0;
 }
@@ -140,8 +151,7 @@ static void eeti_ts_close(struct input_dev *dev)
 {
        struct eeti_ts_priv *priv = input_get_drvdata(dev);
 
-       disable_irq(priv->irq);
-       cancel_work_sync(&priv->work);
+       eeti_ts_stop(priv);
 }
 
 static int __devinit eeti_ts_probe(struct i2c_client *client,
@@ -153,10 +163,12 @@ static int __devinit eeti_ts_probe(struct i2c_client *client,
        unsigned int irq_flags;
        int err = -ENOMEM;
 
-       /* In contrast to what's described in the datasheet, there seems
+       /*
+        * In contrast to what's described in the datasheet, there seems
         * to be no way of probing the presence of that device using I2C
         * commands. So we need to blindly believe it is there, and wait
-        * for interrupts to occur. */
+        * for interrupts to occur.
+        */
 
        priv = kzalloc(sizeof(*priv), GFP_KERNEL);
        if (!priv) {
@@ -212,9 +224,11 @@ static int __devinit eeti_ts_probe(struct i2c_client *client,
                goto err2;
        }
 
-       /* Disable the irq for now. It will be enabled once the input device
-        * is opened. */
-       disable_irq(priv->irq);
+       /*
+        * Disable the device for now. It will be enabled once the
+        * input device is opened.
+        */
+       eeti_ts_stop(priv);
 
        device_init_wakeup(&client->dev, 0);
        return 0;
@@ -235,6 +249,12 @@ static int __devexit eeti_ts_remove(struct i2c_client *client)
        struct eeti_ts_priv *priv = i2c_get_clientdata(client);
 
        free_irq(priv->irq, priv);
+       /*
+        * eeti_ts_stop() leaves IRQ disabled. We need to re-enable it
+        * so that device still works if we reload the driver.
+        */
+       enable_irq(priv->irq);
+
        input_unregister_device(priv->input);
        i2c_set_clientdata(client, NULL);
        kfree(priv);
@@ -246,6 +266,14 @@ static int __devexit eeti_ts_remove(struct i2c_client *client)
 static int eeti_ts_suspend(struct i2c_client *client, pm_message_t mesg)
 {
        struct eeti_ts_priv *priv = i2c_get_clientdata(client);
+       struct input_dev *input_dev = priv->input;
+
+       mutex_lock(&input_dev->mutex);
+
+       if (input_dev->users)
+               eeti_ts_stop(priv);
+
+       mutex_unlock(&input_dev->mutex);
 
        if (device_may_wakeup(&client->dev))
                enable_irq_wake(priv->irq);
@@ -256,10 +284,18 @@ static int eeti_ts_suspend(struct i2c_client *client, pm_message_t mesg)
 static int eeti_ts_resume(struct i2c_client *client)
 {
        struct eeti_ts_priv *priv = i2c_get_clientdata(client);
+       struct input_dev *input_dev = priv->input;
 
        if (device_may_wakeup(&client->dev))
                disable_irq_wake(priv->irq);
 
+       mutex_lock(&input_dev->mutex);
+
+       if (input_dev->users)
+               eeti_ts_start(priv);
+
+       mutex_unlock(&input_dev->mutex);
+
        return 0;
 }
 #else