aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/media/radio/radio-si470x.c330
1 files changed, 167 insertions, 163 deletions
diff --git a/drivers/media/radio/radio-si470x.c b/drivers/media/radio/radio-si470x.c
index d428c3aa2bf9..c72a9e7ad885 100644
--- a/drivers/media/radio/radio-si470x.c
+++ b/drivers/media/radio/radio-si470x.c
@@ -66,8 +66,21 @@
66 * Version 1.0.5 66 * Version 1.0.5
67 * - number of seek_retries changed to tune_timeout 67 * - number of seek_retries changed to tune_timeout
68 * - fixed problem with incomplete tune operations by own buffers 68 * - fixed problem with incomplete tune operations by own buffers
69 * - optimization of variables 69 * - optimization of variables and printf types
70 * - improved error logging 70 * - improved error logging
71 * 2008-01-31 Tobias Lorenz <tobias.lorenz@gmx.net>
72 * Oliver Neukum <oliver@neukum.org>
73 * Version 1.0.6
74 * - fixed coverity checker warnings in *_usb_driver_disconnect
75 * - probe()/open() race by correct ordering in probe()
76 * - DMA coherency rules by separate allocation of all buffers
77 * - use of endianness macros
78 * - abuse of spinlock, replaced by mutex
79 * - racy handling of timer in disconnect,
80 * replaced by delayed_work
81 * - racy interruptible_sleep_on(),
82 * replaced with wait_event_interruptible()
83 * - handle signals in read()
71 * 84 *
72 * ToDo: 85 * ToDo:
73 * - add seeking support 86 * - add seeking support
@@ -80,10 +93,10 @@
80/* driver definitions */ 93/* driver definitions */
81#define DRIVER_AUTHOR "Tobias Lorenz <tobias.lorenz@gmx.net>" 94#define DRIVER_AUTHOR "Tobias Lorenz <tobias.lorenz@gmx.net>"
82#define DRIVER_NAME "radio-si470x" 95#define DRIVER_NAME "radio-si470x"
83#define DRIVER_KERNEL_VERSION KERNEL_VERSION(1, 0, 5) 96#define DRIVER_KERNEL_VERSION KERNEL_VERSION(1, 0, 6)
84#define DRIVER_CARD "Silicon Labs Si470x FM Radio Receiver" 97#define DRIVER_CARD "Silicon Labs Si470x FM Radio Receiver"
85#define DRIVER_DESC "USB radio driver for Si470x FM Radio Receivers" 98#define DRIVER_DESC "USB radio driver for Si470x FM Radio Receivers"
86#define DRIVER_VERSION "1.0.5" 99#define DRIVER_VERSION "1.0.6"
87 100
88 101
89/* kernel includes */ 102/* kernel includes */
@@ -96,8 +109,10 @@
96#include <linux/hid.h> 109#include <linux/hid.h>
97#include <linux/version.h> 110#include <linux/version.h>
98#include <linux/videodev2.h> 111#include <linux/videodev2.h>
112#include <linux/mutex.h>
99#include <media/v4l2-common.h> 113#include <media/v4l2-common.h>
100#include <media/rds.h> 114#include <media/rds.h>
115#include <asm/unaligned.h>
101 116
102 117
103/* USB Device ID List */ 118/* USB Device ID List */
@@ -409,10 +424,9 @@ struct si470x_device {
409 unsigned short registers[RADIO_REGISTER_NUM]; 424 unsigned short registers[RADIO_REGISTER_NUM];
410 425
411 /* RDS receive buffer */ 426 /* RDS receive buffer */
412 struct work_struct work; 427 struct delayed_work work;
413 wait_queue_head_t read_queue; 428 wait_queue_head_t read_queue;
414 struct timer_list timer; 429 struct mutex lock; /* buffer locking */
415 spinlock_t lock; /* buffer locking */
416 unsigned char *buffer; /* size is always multiple of three */ 430 unsigned char *buffer; /* size is always multiple of three */
417 unsigned int buf_size; 431 unsigned int buf_size;
418 unsigned int rd_index; 432 unsigned int rd_index;
@@ -494,7 +508,8 @@ static int si470x_get_register(struct si470x_device *radio, int regnr)
494 retval = si470x_get_report(radio, (void *) &buf, sizeof(buf)); 508 retval = si470x_get_report(radio, (void *) &buf, sizeof(buf));
495 509
496 if (retval >= 0) 510 if (retval >= 0)
497 radio->registers[regnr] = (buf[1] << 8) | buf[2]; 511 radio->registers[regnr] = be16_to_cpu(get_unaligned(
512 (unsigned short *) &buf[1]));
498 513
499 return (retval < 0) ? -EINVAL : 0; 514 return (retval < 0) ? -EINVAL : 0;
500} 515}
@@ -509,8 +524,8 @@ static int si470x_set_register(struct si470x_device *radio, int regnr)
509 int retval; 524 int retval;
510 525
511 buf[0] = REGISTER_REPORT(regnr); 526 buf[0] = REGISTER_REPORT(regnr);
512 buf[1] = (radio->registers[regnr] & 0xff00) >> 8; 527 put_unaligned(cpu_to_be16(radio->registers[regnr]),
513 buf[2] = (radio->registers[regnr] & 0x00ff); 528 (unsigned short *) &buf[1]);
514 529
515 retval = si470x_set_report(radio, (void *) &buf, sizeof(buf)); 530 retval = si470x_set_report(radio, (void *) &buf, sizeof(buf));
516 531
@@ -533,9 +548,9 @@ static int si470x_get_all_registers(struct si470x_device *radio)
533 548
534 if (retval >= 0) 549 if (retval >= 0)
535 for (regnr = 0; regnr < RADIO_REGISTER_NUM; regnr++) 550 for (regnr = 0; regnr < RADIO_REGISTER_NUM; regnr++)
536 radio->registers[regnr] = 551 radio->registers[regnr] = be16_to_cpu(get_unaligned(
537 (buf[regnr * RADIO_REGISTER_SIZE + 1] << 8) | 552 (unsigned short *)
538 buf[regnr * RADIO_REGISTER_SIZE + 2]; 553 &buf[regnr * RADIO_REGISTER_SIZE + 1]));
539 554
540 return (retval < 0) ? -EINVAL : 0; 555 return (retval < 0) ? -EINVAL : 0;
541} 556}
@@ -558,7 +573,7 @@ static int si470x_get_rds_registers(struct si470x_device *radio)
558 (void *) &buf, sizeof(buf), &size, usb_timeout); 573 (void *) &buf, sizeof(buf), &size, usb_timeout);
559 if (size != sizeof(buf)) 574 if (size != sizeof(buf))
560 printk(KERN_WARNING DRIVER_NAME ": si470x_get_rds_register: " 575 printk(KERN_WARNING DRIVER_NAME ": si470x_get_rds_register: "
561 "return size differs: %d != %uld\n", size, sizeof(buf)); 576 "return size differs: %d != %zu\n", size, sizeof(buf));
562 if (retval < 0) 577 if (retval < 0)
563 printk(KERN_WARNING DRIVER_NAME ": si470x_get_rds_registers: " 578 printk(KERN_WARNING DRIVER_NAME ": si470x_get_rds_registers: "
564 "usb_interrupt_msg returned %d\n", retval); 579 "usb_interrupt_msg returned %d\n", retval);
@@ -566,8 +581,8 @@ static int si470x_get_rds_registers(struct si470x_device *radio)
566 if (retval >= 0) 581 if (retval >= 0)
567 for (regnr = 0; regnr < RDS_REGISTER_NUM; regnr++) 582 for (regnr = 0; regnr < RDS_REGISTER_NUM; regnr++)
568 radio->registers[STATUSRSSI + regnr] = 583 radio->registers[STATUSRSSI + regnr] =
569 (buf[regnr * RADIO_REGISTER_SIZE + 1] << 8) | 584 be16_to_cpu(get_unaligned((unsigned short *)
570 buf[regnr * RADIO_REGISTER_SIZE + 2]; 585 &buf[regnr * RADIO_REGISTER_SIZE + 1]));
571 586
572 return (retval < 0) ? -EINVAL : 0; 587 return (retval < 0) ? -EINVAL : 0;
573} 588}
@@ -600,7 +615,7 @@ static int si470x_set_chan(struct si470x_device *radio, unsigned short chan)
600 (!timed_out)); 615 (!timed_out));
601 if (timed_out) 616 if (timed_out)
602 printk(KERN_WARNING DRIVER_NAME 617 printk(KERN_WARNING DRIVER_NAME
603 ": seek does not finish after %d ms\n", tune_timeout); 618 ": seek does not finish after %u ms\n", tune_timeout);
604 619
605 /* stop tuning */ 620 /* stop tuning */
606 radio->registers[CHANNEL] &= ~CHANNEL_TUNE; 621 radio->registers[CHANNEL] &= ~CHANNEL_TUNE;
@@ -763,6 +778,11 @@ static int si470x_rds_on(struct si470x_device *radio)
763 */ 778 */
764static void si470x_rds(struct si470x_device *radio) 779static void si470x_rds(struct si470x_device *radio)
765{ 780{
781 unsigned char blocknum;
782 unsigned short bler; /* rds block errors */
783 unsigned short rds;
784 unsigned char tmpbuf[3];
785
766 /* get rds blocks */ 786 /* get rds blocks */
767 if (si470x_get_rds_registers(radio) < 0) 787 if (si470x_get_rds_registers(radio) < 0)
768 return; 788 return;
@@ -775,69 +795,58 @@ static void si470x_rds(struct si470x_device *radio)
775 return; 795 return;
776 } 796 }
777 797
778 /* copy four RDS blocks to internal buffer */ 798 /* copy all four RDS blocks to internal buffer */
779 if (spin_trylock(&radio->lock)) { 799 mutex_lock(&radio->lock);
780 unsigned char blocknum; 800 for (blocknum = 0; blocknum < 4; blocknum++) {
781 unsigned short bler; /* rds block errors */ 801 switch (blocknum) {
782 unsigned short rds; 802 default:
783 unsigned char tmpbuf[3]; 803 bler = (radio->registers[STATUSRSSI] &
784 unsigned char i; 804 STATUSRSSI_BLERA) >> 9;
785 805 rds = radio->registers[RDSA];
786 /* process each rds block */ 806 break;
787 for (blocknum = 0; blocknum < 4; blocknum++) { 807 case 1:
788 switch (blocknum) { 808 bler = (radio->registers[READCHAN] &
789 default: 809 READCHAN_BLERB) >> 14;
790 bler = (radio->registers[STATUSRSSI] & 810 rds = radio->registers[RDSB];
791 STATUSRSSI_BLERA) >> 9; 811 break;
792 rds = radio->registers[RDSA]; 812 case 2:
793 break; 813 bler = (radio->registers[READCHAN] &
794 case 1: 814 READCHAN_BLERC) >> 12;
795 bler = (radio->registers[READCHAN] & 815 rds = radio->registers[RDSC];
796 READCHAN_BLERB) >> 14; 816 break;
797 rds = radio->registers[RDSB]; 817 case 3:
798 break; 818 bler = (radio->registers[READCHAN] &
799 case 2: 819 READCHAN_BLERD) >> 10;
800 bler = (radio->registers[READCHAN] & 820 rds = radio->registers[RDSD];
801 READCHAN_BLERC) >> 12; 821 break;
802 rds = radio->registers[RDSC]; 822 };
803 break; 823
804 case 3: 824 /* Fill the V4L2 RDS buffer */
805 bler = (radio->registers[READCHAN] & 825 put_unaligned(cpu_to_le16(rds), (unsigned short *) &tmpbuf);
806 READCHAN_BLERD) >> 10; 826 tmpbuf[2] = blocknum; /* offset name */
807 rds = radio->registers[RDSD]; 827 tmpbuf[2] |= blocknum << 3; /* received offset */
808 break; 828 if (bler > max_rds_errors)
809 }; 829 tmpbuf[2] |= 0x80; /* uncorrectable errors */
810 830 else if (bler > 0)
811 /* Fill the V4L2 RDS buffer */ 831 tmpbuf[2] |= 0x40; /* corrected error(s) */
812 tmpbuf[0] = rds & 0x00ff; /* LSB */ 832
813 tmpbuf[1] = (rds & 0xff00) >> 8;/* MSB */ 833 /* copy RDS block to internal buffer */
814 tmpbuf[2] = blocknum; /* offset name */ 834 memcpy(&radio->buffer[radio->wr_index], &tmpbuf, 3);
815 tmpbuf[2] |= blocknum << 3; /* received offset */ 835 radio->wr_index += 3;
816 if (bler > max_rds_errors) 836
817 tmpbuf[2] |= 0x80; /* uncorrectable errors */ 837 /* wrap write pointer */
818 else if (bler > 0) 838 if (radio->wr_index >= radio->buf_size)
819 tmpbuf[2] |= 0x40; /* corrected error(s) */ 839 radio->wr_index = 0;
820 840
821 /* copy RDS block to internal buffer */ 841 /* check for overflow */
822 for (i = 0; i < 3; i++) { 842 if (radio->wr_index == radio->rd_index) {
823 radio->buffer[radio->wr_index] = tmpbuf[i]; 843 /* increment and wrap read pointer */
824 radio->wr_index++; 844 radio->rd_index += 3;
825 } 845 if (radio->rd_index >= radio->buf_size)
826 846 radio->rd_index = 0;
827 /* wrap write pointer */
828 if (radio->wr_index >= radio->buf_size)
829 radio->wr_index = 0;
830
831 /* check for overflow */
832 if (radio->wr_index == radio->rd_index) {
833 /* increment and wrap read pointer */
834 radio->rd_index += 3;
835 if (radio->rd_index >= radio->buf_size)
836 radio->rd_index = 0;
837 }
838 } 847 }
839 spin_unlock(&radio->lock);
840 } 848 }
849 mutex_unlock(&radio->lock);
841 850
842 /* wake up read queue */ 851 /* wake up read queue */
843 if (radio->wr_index != radio->rd_index) 852 if (radio->wr_index != radio->rd_index)
@@ -846,29 +855,18 @@ static void si470x_rds(struct si470x_device *radio)
846 855
847 856
848/* 857/*
849 * si470x_timer - rds timer function
850 */
851static void si470x_timer(unsigned long data)
852{
853 struct si470x_device *radio = (struct si470x_device *) data;
854
855 schedule_work(&radio->work);
856}
857
858
859/*
860 * si470x_work - rds work function 858 * si470x_work - rds work function
861 */ 859 */
862static void si470x_work(struct work_struct *work) 860static void si470x_work(struct work_struct *work)
863{ 861{
864 struct si470x_device *radio = container_of(work, struct si470x_device, 862 struct si470x_device *radio = container_of(work, struct si470x_device,
865 work); 863 work.work);
866 864
867 if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0) 865 if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0)
868 return; 866 return;
869 867
870 si470x_rds(radio); 868 si470x_rds(radio);
871 mod_timer(&radio->timer, jiffies + msecs_to_jiffies(rds_poll_time)); 869 schedule_delayed_work(&radio->work, msecs_to_jiffies(rds_poll_time));
872} 870}
873 871
874 872
@@ -885,49 +883,49 @@ static ssize_t si470x_fops_read(struct file *file, char __user *buf,
885{ 883{
886 struct si470x_device *radio = video_get_drvdata(video_devdata(file)); 884 struct si470x_device *radio = video_get_drvdata(video_devdata(file));
887 int retval = 0; 885 int retval = 0;
886 unsigned int block_count = 0;
888 887
889 /* switch on rds reception */ 888 /* switch on rds reception */
890 if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0) { 889 if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0) {
891 si470x_rds_on(radio); 890 si470x_rds_on(radio);
892 schedule_work(&radio->work); 891 schedule_delayed_work(&radio->work,
892 msecs_to_jiffies(rds_poll_time));
893 } 893 }
894 894
895 /* block if no new data available */ 895 /* block if no new data available */
896 while (radio->wr_index == radio->rd_index) { 896 while (radio->wr_index == radio->rd_index) {
897 if (file->f_flags & O_NONBLOCK) 897 if (file->f_flags & O_NONBLOCK)
898 return -EWOULDBLOCK; 898 return -EWOULDBLOCK;
899 interruptible_sleep_on(&radio->read_queue); 899 if (wait_event_interruptible(radio->read_queue,
900 radio->wr_index != radio->rd_index) < 0)
901 return -EINTR;
900 } 902 }
901 903
902 /* calculate block count from byte count */ 904 /* calculate block count from byte count */
903 count /= 3; 905 count /= 3;
904 906
905 /* copy RDS block out of internal buffer and to user buffer */ 907 /* copy RDS block out of internal buffer and to user buffer */
906 if (spin_trylock(&radio->lock)) { 908 mutex_lock(&radio->lock);
907 unsigned int block_count = 0; 909 while (block_count < count) {
908 while (block_count < count) { 910 if (radio->rd_index == radio->wr_index)
909 if (radio->rd_index == radio->wr_index) 911 break;
910 break;
911
912 /* always transfer rds complete blocks */
913 if (copy_to_user(buf,
914 &radio->buffer[radio->rd_index], 3))
915 /* retval = -EFAULT; */
916 break;
917 912
918 /* increment and wrap read pointer */ 913 /* always transfer rds complete blocks */
919 radio->rd_index += 3; 914 if (copy_to_user(buf, &radio->buffer[radio->rd_index], 3))
920 if (radio->rd_index >= radio->buf_size) 915 /* retval = -EFAULT; */
921 radio->rd_index = 0; 916 break;
922 917
923 /* increment counters */ 918 /* increment and wrap read pointer */
924 block_count++; 919 radio->rd_index += 3;
925 buf += 3; 920 if (radio->rd_index >= radio->buf_size)
926 retval += 3; 921 radio->rd_index = 0;
927 }
928 922
929 spin_unlock(&radio->lock); 923 /* increment counters */
924 block_count++;
925 buf += 3;
926 retval += 3;
930 } 927 }
928 mutex_unlock(&radio->lock);
931 929
932 return retval; 930 return retval;
933} 931}
@@ -944,7 +942,8 @@ static unsigned int si470x_fops_poll(struct file *file,
944 /* switch on rds reception */ 942 /* switch on rds reception */
945 if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0) { 943 if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0) {
946 si470x_rds_on(radio); 944 si470x_rds_on(radio);
947 schedule_work(&radio->work); 945 schedule_delayed_work(&radio->work,
946 msecs_to_jiffies(rds_poll_time));
948 } 947 }
949 948
950 poll_wait(file, &radio->read_queue, pts); 949 poll_wait(file, &radio->read_queue, pts);
@@ -984,8 +983,7 @@ static int si470x_fops_release(struct inode *inode, struct file *file)
984 radio->users--; 983 radio->users--;
985 if (radio->users == 0) { 984 if (radio->users == 0) {
986 /* stop rds reception */ 985 /* stop rds reception */
987 del_timer_sync(&radio->timer); 986 cancel_delayed_work_sync(&radio->work);
988 flush_scheduled_work();
989 987
990 /* cancel read processes */ 988 /* cancel read processes */
991 wake_up_interruptible(&radio->read_queue); 989 wake_up_interruptible(&radio->read_queue);
@@ -1362,73 +1360,82 @@ static int si470x_usb_driver_probe(struct usb_interface *intf,
1362 const struct usb_device_id *id) 1360 const struct usb_device_id *id)
1363{ 1361{
1364 struct si470x_device *radio; 1362 struct si470x_device *radio;
1363 int retval = -ENOMEM;
1365 1364
1366 /* memory and interface allocations */ 1365 /* private data allocation */
1367 radio = kmalloc(sizeof(struct si470x_device), GFP_KERNEL); 1366 radio = kzalloc(sizeof(struct si470x_device), GFP_KERNEL);
1368 if (!radio) 1367 if (!radio)
1369 return -ENOMEM; 1368 goto err_initial;
1369
1370 /* video device allocation */
1370 radio->videodev = video_device_alloc(); 1371 radio->videodev = video_device_alloc();
1371 if (!radio->videodev) { 1372 if (!radio->videodev)
1372 kfree(radio); 1373 goto err_radio;
1373 return -ENOMEM; 1374
1374 } 1375 /* initial configuration */
1375 memcpy(radio->videodev, &si470x_viddev_template, 1376 memcpy(radio->videodev, &si470x_viddev_template,
1376 sizeof(si470x_viddev_template)); 1377 sizeof(si470x_viddev_template));
1377 radio->users = 0; 1378 radio->users = 0;
1378 radio->usbdev = interface_to_usbdev(intf); 1379 radio->usbdev = interface_to_usbdev(intf);
1380 mutex_init(&radio->lock);
1379 video_set_drvdata(radio->videodev, radio); 1381 video_set_drvdata(radio->videodev, radio);
1380 if (video_register_device(radio->videodev, VFL_TYPE_RADIO, radio_nr)) {
1381 printk(KERN_WARNING DRIVER_NAME
1382 ": Could not register video device\n");
1383 video_device_release(radio->videodev);
1384 kfree(radio);
1385 return -EIO;
1386 }
1387 usb_set_intfdata(intf, radio);
1388 1382
1389 /* show some infos about the specific device */ 1383 /* show some infos about the specific device */
1390 if (si470x_get_all_registers(radio) < 0) { 1384 retval = -EIO;
1391 video_device_release(radio->videodev); 1385 if (si470x_get_all_registers(radio) < 0)
1392 kfree(radio); 1386 goto err_all;
1393 return -EIO; 1387 printk(KERN_INFO DRIVER_NAME ": DeviceID=0x%4.4hx ChipID=0x%4.4hx\n",
1394 }
1395 printk(KERN_INFO DRIVER_NAME ": DeviceID=0x%4.4x ChipID=0x%4.4x\n",
1396 radio->registers[DEVICEID], radio->registers[CHIPID]); 1388 radio->registers[DEVICEID], radio->registers[CHIPID]);
1397 1389
1398 /* check if firmware is current */ 1390 /* check if firmware is current */
1399 if ((radio->registers[CHIPID] & CHIPID_FIRMWARE) 1391 if ((radio->registers[CHIPID] & CHIPID_FIRMWARE)
1400 < RADIO_SW_VERSION_CURRENT) 1392 < RADIO_SW_VERSION_CURRENT) {
1393 printk(KERN_WARNING DRIVER_NAME
1394 ": This driver is known to work with "
1395 "firmware version %hu,\n", RADIO_SW_VERSION_CURRENT);
1396 printk(KERN_WARNING DRIVER_NAME
1397 ": but the device has firmware version %hu.\n",
1398 radio->registers[CHIPID] & CHIPID_FIRMWARE);
1399 printk(KERN_WARNING DRIVER_NAME
1400 ": If you have some trouble using this driver,\n");
1401 printk(KERN_WARNING DRIVER_NAME 1401 printk(KERN_WARNING DRIVER_NAME
1402 ": This driver is known to work with chip version %d, " 1402 ": please report to V4L ML at "
1403 "but the device has firmware %d.\n" 1403 "video4linux-list@redhat.com\n");
1404 DRIVER_NAME 1404 }
1405 "If you have some trouble using this driver, please "
1406 "report to V4L ML at video4linux-list@redhat.com\n",
1407 radio->registers[CHIPID] & CHIPID_FIRMWARE,
1408 RADIO_SW_VERSION_CURRENT);
1409 1405
1410 /* set initial frequency */ 1406 /* set initial frequency */
1411 si470x_set_freq(radio, 87.5 * FREQ_MUL); /* available in all regions */ 1407 si470x_set_freq(radio, 87.5 * FREQ_MUL); /* available in all regions */
1412 1408
1413 /* rds initialization */ 1409 /* rds buffer allocation */
1414 radio->buf_size = rds_buf * 3; 1410 radio->buf_size = rds_buf * 3;
1415 radio->buffer = kmalloc(radio->buf_size, GFP_KERNEL); 1411 radio->buffer = kmalloc(radio->buf_size, GFP_KERNEL);
1416 if (!radio->buffer) { 1412 if (!radio->buffer)
1417 video_device_release(radio->videodev); 1413 goto err_all;
1418 kfree(radio); 1414
1419 return -ENOMEM; 1415 /* rds buffer configuration */
1420 }
1421 radio->wr_index = 0; 1416 radio->wr_index = 0;
1422 radio->rd_index = 0; 1417 radio->rd_index = 0;
1423 init_waitqueue_head(&radio->read_queue); 1418 init_waitqueue_head(&radio->read_queue);
1424 1419
1425 /* prepare polling via eventd */ 1420 /* prepare rds work function */
1426 INIT_WORK(&radio->work, si470x_work); 1421 INIT_DELAYED_WORK(&radio->work, si470x_work);
1427 init_timer(&radio->timer); 1422
1428 radio->timer.function = si470x_timer; 1423 /* register video device */
1429 radio->timer.data = (unsigned long) radio; 1424 if (video_register_device(radio->videodev, VFL_TYPE_RADIO, radio_nr)) {
1425 printk(KERN_WARNING DRIVER_NAME
1426 ": Could not register video device\n");
1427 goto err_all;
1428 }
1429 usb_set_intfdata(intf, radio);
1430 1430
1431 return 0; 1431 return 0;
1432err_all:
1433 video_device_release(radio->videodev);
1434 kfree(radio->buffer);
1435err_radio:
1436 kfree(radio);
1437err_initial:
1438 return retval;
1432} 1439}
1433 1440
1434 1441
@@ -1439,14 +1446,11 @@ static void si470x_usb_driver_disconnect(struct usb_interface *intf)
1439{ 1446{
1440 struct si470x_device *radio = usb_get_intfdata(intf); 1447 struct si470x_device *radio = usb_get_intfdata(intf);
1441 1448
1449 cancel_delayed_work_sync(&radio->work);
1442 usb_set_intfdata(intf, NULL); 1450 usb_set_intfdata(intf, NULL);
1443 if (radio) { 1451 video_unregister_device(radio->videodev);
1444 del_timer_sync(&radio->timer); 1452 kfree(radio->buffer);
1445 flush_scheduled_work(); 1453 kfree(radio);
1446 video_unregister_device(radio->videodev);
1447 kfree(radio->buffer);
1448 kfree(radio);
1449 }
1450} 1454}
1451 1455
1452 1456