diff options
Diffstat (limited to 'drivers/input/touchscreen/eeti_ts.c')
| -rw-r--r-- | drivers/input/touchscreen/eeti_ts.c | 56 |
1 files changed, 46 insertions, 10 deletions
diff --git a/drivers/input/touchscreen/eeti_ts.c b/drivers/input/touchscreen/eeti_ts.c index 204b8a1a601c..75f8b73010fa 100644 --- a/drivers/input/touchscreen/eeti_ts.c +++ b/drivers/input/touchscreen/eeti_ts.c | |||
| @@ -124,14 +124,25 @@ static irqreturn_t eeti_ts_isr(int irq, void *dev_id) | |||
| 124 | return IRQ_HANDLED; | 124 | return IRQ_HANDLED; |
| 125 | } | 125 | } |
| 126 | 126 | ||
| 127 | static int eeti_ts_open(struct input_dev *dev) | 127 | static void eeti_ts_start(struct eeti_ts_priv *priv) |
| 128 | { | 128 | { |
| 129 | struct eeti_ts_priv *priv = input_get_drvdata(dev); | ||
| 130 | |||
| 131 | enable_irq(priv->irq); | 129 | enable_irq(priv->irq); |
| 132 | 130 | ||
| 133 | /* Read the events once to arm the IRQ */ | 131 | /* Read the events once to arm the IRQ */ |
| 134 | eeti_ts_read(&priv->work); | 132 | eeti_ts_read(&priv->work); |
| 133 | } | ||
| 134 | |||
| 135 | static void eeti_ts_stop(struct eeti_ts_priv *priv) | ||
| 136 | { | ||
| 137 | disable_irq(priv->irq); | ||
| 138 | cancel_work_sync(&priv->work); | ||
| 139 | } | ||
| 140 | |||
| 141 | static int eeti_ts_open(struct input_dev *dev) | ||
| 142 | { | ||
| 143 | struct eeti_ts_priv *priv = input_get_drvdata(dev); | ||
| 144 | |||
| 145 | eeti_ts_start(priv); | ||
| 135 | 146 | ||
| 136 | return 0; | 147 | return 0; |
| 137 | } | 148 | } |
| @@ -140,8 +151,7 @@ static void eeti_ts_close(struct input_dev *dev) | |||
| 140 | { | 151 | { |
| 141 | struct eeti_ts_priv *priv = input_get_drvdata(dev); | 152 | struct eeti_ts_priv *priv = input_get_drvdata(dev); |
| 142 | 153 | ||
| 143 | disable_irq(priv->irq); | 154 | eeti_ts_stop(priv); |
| 144 | cancel_work_sync(&priv->work); | ||
| 145 | } | 155 | } |
| 146 | 156 | ||
| 147 | static int __devinit eeti_ts_probe(struct i2c_client *client, | 157 | static int __devinit eeti_ts_probe(struct i2c_client *client, |
| @@ -153,10 +163,12 @@ static int __devinit eeti_ts_probe(struct i2c_client *client, | |||
| 153 | unsigned int irq_flags; | 163 | unsigned int irq_flags; |
| 154 | int err = -ENOMEM; | 164 | int err = -ENOMEM; |
| 155 | 165 | ||
| 156 | /* In contrast to what's described in the datasheet, there seems | 166 | /* |
| 167 | * In contrast to what's described in the datasheet, there seems | ||
| 157 | * to be no way of probing the presence of that device using I2C | 168 | * to be no way of probing the presence of that device using I2C |
| 158 | * commands. So we need to blindly believe it is there, and wait | 169 | * commands. So we need to blindly believe it is there, and wait |
| 159 | * for interrupts to occur. */ | 170 | * for interrupts to occur. |
| 171 | */ | ||
| 160 | 172 | ||
| 161 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); | 173 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); |
| 162 | if (!priv) { | 174 | if (!priv) { |
| @@ -212,9 +224,11 @@ static int __devinit eeti_ts_probe(struct i2c_client *client, | |||
| 212 | goto err2; | 224 | goto err2; |
| 213 | } | 225 | } |
| 214 | 226 | ||
| 215 | /* Disable the irq for now. It will be enabled once the input device | 227 | /* |
| 216 | * is opened. */ | 228 | * Disable the device for now. It will be enabled once the |
| 217 | disable_irq(priv->irq); | 229 | * input device is opened. |
| 230 | */ | ||
| 231 | eeti_ts_stop(priv); | ||
| 218 | 232 | ||
| 219 | device_init_wakeup(&client->dev, 0); | 233 | device_init_wakeup(&client->dev, 0); |
| 220 | return 0; | 234 | return 0; |
| @@ -235,6 +249,12 @@ static int __devexit eeti_ts_remove(struct i2c_client *client) | |||
| 235 | struct eeti_ts_priv *priv = i2c_get_clientdata(client); | 249 | struct eeti_ts_priv *priv = i2c_get_clientdata(client); |
| 236 | 250 | ||
| 237 | free_irq(priv->irq, priv); | 251 | free_irq(priv->irq, priv); |
| 252 | /* | ||
| 253 | * eeti_ts_stop() leaves IRQ disabled. We need to re-enable it | ||
| 254 | * so that device still works if we reload the driver. | ||
| 255 | */ | ||
| 256 | enable_irq(priv->irq); | ||
| 257 | |||
| 238 | input_unregister_device(priv->input); | 258 | input_unregister_device(priv->input); |
| 239 | i2c_set_clientdata(client, NULL); | 259 | i2c_set_clientdata(client, NULL); |
| 240 | kfree(priv); | 260 | kfree(priv); |
| @@ -246,6 +266,14 @@ static int __devexit eeti_ts_remove(struct i2c_client *client) | |||
| 246 | static int eeti_ts_suspend(struct i2c_client *client, pm_message_t mesg) | 266 | static int eeti_ts_suspend(struct i2c_client *client, pm_message_t mesg) |
| 247 | { | 267 | { |
| 248 | struct eeti_ts_priv *priv = i2c_get_clientdata(client); | 268 | struct eeti_ts_priv *priv = i2c_get_clientdata(client); |
| 269 | struct input_dev *input_dev = priv->input; | ||
| 270 | |||
| 271 | mutex_lock(&input_dev->mutex); | ||
| 272 | |||
| 273 | if (input_dev->users) | ||
| 274 | eeti_ts_stop(priv); | ||
| 275 | |||
| 276 | mutex_unlock(&input_dev->mutex); | ||
| 249 | 277 | ||
| 250 | if (device_may_wakeup(&client->dev)) | 278 | if (device_may_wakeup(&client->dev)) |
| 251 | enable_irq_wake(priv->irq); | 279 | enable_irq_wake(priv->irq); |
| @@ -256,10 +284,18 @@ static int eeti_ts_suspend(struct i2c_client *client, pm_message_t mesg) | |||
| 256 | static int eeti_ts_resume(struct i2c_client *client) | 284 | static int eeti_ts_resume(struct i2c_client *client) |
| 257 | { | 285 | { |
| 258 | struct eeti_ts_priv *priv = i2c_get_clientdata(client); | 286 | struct eeti_ts_priv *priv = i2c_get_clientdata(client); |
| 287 | struct input_dev *input_dev = priv->input; | ||
| 259 | 288 | ||
| 260 | if (device_may_wakeup(&client->dev)) | 289 | if (device_may_wakeup(&client->dev)) |
| 261 | disable_irq_wake(priv->irq); | 290 | disable_irq_wake(priv->irq); |
| 262 | 291 | ||
| 292 | mutex_lock(&input_dev->mutex); | ||
| 293 | |||
| 294 | if (input_dev->users) | ||
| 295 | eeti_ts_start(priv); | ||
| 296 | |||
| 297 | mutex_unlock(&input_dev->mutex); | ||
| 298 | |||
| 263 | return 0; | 299 | return 0; |
| 264 | } | 300 | } |
| 265 | #else | 301 | #else |
