summaryrefslogtreecommitdiffstats
path: root/drivers/media/i2c/adv7180.c
diff options
context:
space:
mode:
authorLars-Peter Clausen2014-03-07 17:14:31 +0100
committerMauro Carvalho Chehab2014-03-11 14:25:58 +0100
commit0c25534d456535a879aba482dc14795213312514 (patch)
tree53d2cf797041a04c6916fec27743e922dcc985c6 /drivers/media/i2c/adv7180.c
parent[media] adv7180: Remove duplicated probe error message (diff)
downloadkernel-qcow2-linux-0c25534d456535a879aba482dc14795213312514.tar.gz
kernel-qcow2-linux-0c25534d456535a879aba482dc14795213312514.tar.xz
kernel-qcow2-linux-0c25534d456535a879aba482dc14795213312514.zip
[media] adv7180: Use threaded IRQ instead of IRQ + workqueue
The proper way to handle IRQs that need to be able to sleep in their IRQ handler is to use a threaded IRQ. Signed-off-by: Lars-Peter Clausen <lars@metafoo.de> Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
Diffstat (limited to 'drivers/media/i2c/adv7180.c')
-rw-r--r--drivers/media/i2c/adv7180.c33
1 files changed, 5 insertions, 28 deletions
diff --git a/drivers/media/i2c/adv7180.c b/drivers/media/i2c/adv7180.c
index 98a3ff1f535d..c750aaee74e1 100644
--- a/drivers/media/i2c/adv7180.c
+++ b/drivers/media/i2c/adv7180.c
@@ -123,7 +123,6 @@
struct adv7180_state {
struct v4l2_ctrl_handler ctrl_hdl;
struct v4l2_subdev sd;
- struct work_struct work;
struct mutex mutex; /* mutual excl. when accessing chip */
int irq;
v4l2_std_id curr_norm;
@@ -449,10 +448,9 @@ static const struct v4l2_subdev_ops adv7180_ops = {
.video = &adv7180_video_ops,
};
-static void adv7180_work(struct work_struct *work)
+static irqreturn_t adv7180_irq(int irq, void *devid)
{
- struct adv7180_state *state = container_of(work, struct adv7180_state,
- work);
+ struct adv7180_state *state = devid;
struct i2c_client *client = v4l2_get_subdevdata(&state->sd);
u8 isr3;
@@ -468,17 +466,6 @@ static void adv7180_work(struct work_struct *work)
__adv7180_status(client, NULL, &state->curr_norm);
mutex_unlock(&state->mutex);
- enable_irq(state->irq);
-}
-
-static irqreturn_t adv7180_irq(int irq, void *devid)
-{
- struct adv7180_state *state = devid;
-
- schedule_work(&state->work);
-
- disable_irq_nosync(state->irq);
-
return IRQ_HANDLED;
}
@@ -533,8 +520,8 @@ static int init_device(struct i2c_client *client, struct adv7180_state *state)
/* register for interrupts */
if (state->irq > 0) {
- ret = request_irq(state->irq, adv7180_irq, 0, KBUILD_MODNAME,
- state);
+ ret = request_threaded_irq(state->irq, NULL, adv7180_irq,
+ IRQF_ONESHOT, KBUILD_MODNAME, state);
if (ret)
return ret;
@@ -598,7 +585,6 @@ static int adv7180_probe(struct i2c_client *client,
}
state->irq = client->irq;
- INIT_WORK(&state->work, adv7180_work);
mutex_init(&state->mutex);
state->autodetect = true;
state->input = 0;
@@ -626,17 +612,8 @@ static int adv7180_remove(struct i2c_client *client)
struct v4l2_subdev *sd = i2c_get_clientdata(client);
struct adv7180_state *state = to_state(sd);
- if (state->irq > 0) {
+ if (state->irq > 0)
free_irq(client->irq, state);
- if (cancel_work_sync(&state->work)) {
- /*
- * Work was pending, therefore we need to enable
- * IRQ here to balance the disable_irq() done in the
- * interrupt handler.
- */
- enable_irq(state->irq);
- }
- }
v4l2_device_unregister_subdev(sd);
adv7180_exit_controls(state);