diff options
author | Lars-Peter Clausen <lars@metafoo.de> | 2014-03-07 13:14:31 -0300 |
---|---|---|
committer | Mauro Carvalho Chehab <m.chehab@samsung.com> | 2014-03-11 10:25:58 -0300 |
commit | 0c25534d456535a879aba482dc14795213312514 (patch) | |
tree | 53d2cf797041a04c6916fec27743e922dcc985c6 /drivers/media/i2c | |
parent | 7933c177fa5235f250203ccfe9d8402b11129144 (diff) | |
download | linux-0c25534d456535a879aba482dc14795213312514.tar.gz linux-0c25534d456535a879aba482dc14795213312514.tar.bz2 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')
-rw-r--r-- | drivers/media/i2c/adv7180.c | 33 |
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); |