From 05a4e02cb8076cdca6cafabbf21450d9dd89389b Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 7 Mar 2014 13:14:31 -0300 Subject: [PATCH] upstream: [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 Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/adv7180.c | 33 +++++---------------------------- 1 file changed, 5 insertions(+), 28 deletions(-) diff --git a/drivers/media/i2c/adv7180.c b/drivers/media/i2c/adv7180.c index 98a3ff1..c750aae 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); -- 2.7.4