**************************************************************************/
/*
- * si470x_i2c_interrupt_work - rds processing function
+ * si470x_i2c_interrupt - interrupt handler
*/
-static void si470x_i2c_interrupt_work(struct work_struct *work)
+static irqreturn_t si470x_i2c_interrupt(int irq, void *dev_id)
{
- struct si470x_device *radio = container_of(work,
- struct si470x_device, radio_work);
+ struct si470x_device *radio = dev_id;
unsigned char regnr;
unsigned char blocknum;
unsigned short bler; /* rds block errors */
/* check Seek/Tune Complete */
retval = si470x_get_register(radio, STATUSRSSI);
if (retval < 0)
- return;
+ goto end;
if (radio->registers[STATUSRSSI] & STATUSRSSI_STC)
complete(&radio->completion);
/* safety checks */
if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0)
- return;
+ goto end;
/* Update RDS registers */
for (regnr = 1; regnr < RDS_REGISTER_NUM; regnr++) {
retval = si470x_get_register(radio, STATUSRSSI + regnr);
if (retval < 0)
- return;
+ goto end;
}
/* get rds blocks */
if ((radio->registers[STATUSRSSI] & STATUSRSSI_RDSR) == 0)
/* No RDS group ready, better luck next time */
- return;
+ goto end;
for (blocknum = 0; blocknum < 4; blocknum++) {
switch (blocknum) {
if (radio->wr_index != radio->rd_index)
wake_up_interruptible(&radio->read_queue);
-}
-
-
-/*
- * si470x_i2c_interrupt - interrupt handler
- */
-static irqreturn_t si470x_i2c_interrupt(int irq, void *dev_id)
-{
- struct si470x_device *radio = dev_id;
-
- if (!work_pending(&radio->radio_work))
- schedule_work(&radio->radio_work);
+end:
return IRQ_HANDLED;
}
goto err_initial;
}
- INIT_WORK(&radio->radio_work, si470x_i2c_interrupt_work);
radio->users = 0;
radio->client = client;
mutex_init(&radio->lock);
radio->stci_enabled = true;
init_completion(&radio->completion);
- retval = request_irq(client->irq, si470x_i2c_interrupt,
+ retval = request_threaded_irq(client->irq, NULL, si470x_i2c_interrupt,
IRQF_TRIGGER_FALLING, DRIVER_NAME, radio);
if (retval) {
dev_err(&client->dev, "Failed to register interrupt\n");
struct si470x_device *radio = i2c_get_clientdata(client);
free_irq(client->irq, radio);
- cancel_work_sync(&radio->radio_work);
video_unregister_device(radio->videodev);
kfree(radio);