Merge branch 'for-2.6.38' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/wq
authorLinus Torvalds <torvalds@linux-foundation.org>
Sat, 8 Jan 2011 00:58:04 +0000 (16:58 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sat, 8 Jan 2011 00:58:04 +0000 (16:58 -0800)
* 'for-2.6.38' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/wq: (33 commits)
  usb: don't use flush_scheduled_work()
  speedtch: don't abuse struct delayed_work
  media/video: don't use flush_scheduled_work()
  media/video: explicitly flush request_module work
  ioc4: use static work_struct for ioc4_load_modules()
  init: don't call flush_scheduled_work() from do_initcalls()
  s390: don't use flush_scheduled_work()
  rtc: don't use flush_scheduled_work()
  mmc: update workqueue usages
  mfd: update workqueue usages
  dvb: don't use flush_scheduled_work()
  leds-wm8350: don't use flush_scheduled_work()
  mISDN: don't use flush_scheduled_work()
  macintosh/ams: don't use flush_scheduled_work()
  vmwgfx: don't use flush_scheduled_work()
  tpm: don't use flush_scheduled_work()
  sonypi: don't use flush_scheduled_work()
  hvsi: don't use flush_scheduled_work()
  xen: don't use flush_scheduled_work()
  gdrom: don't use flush_scheduled_work()
  ...

Fixed up trivial conflict in drivers/media/video/bt8xx/bttv-input.c
as per Tejun.

28 files changed:
1  2 
Documentation/feature-removal-schedule.txt
drivers/ata/libata-core.c
drivers/ata/libata-sff.c
drivers/block/xen-blkfront.c
drivers/media/dvb/dvb-usb/dvb-usb-remote.c
drivers/media/video/bt8xx/bttv-driver.c
drivers/media/video/bt8xx/bttv-input.c
drivers/media/video/cx18/cx18-driver.c
drivers/media/video/cx231xx/cx231xx-cards.c
drivers/media/video/cx23885/cx23885-input.c
drivers/media/video/em28xx/em28xx-cards.c
drivers/media/video/em28xx/em28xx-input.c
drivers/media/video/saa7134/saa7134-core.c
drivers/mmc/core/core.c
drivers/mmc/host/omap_hsmmc.c
drivers/net/ibm_newemac/core.c
drivers/staging/pohmelfs/inode.c
drivers/usb/gadget/u_ether.c
drivers/usb/host/ohci-hcd.c
fs/ncpfs/inode.c
fs/ocfs2/cluster/heartbeat.c
include/linux/workqueue.h
init/main.c
mm/slab.c
mm/vmstat.c
net/atm/lec.c
net/core/netpoll.c
net/netfilter/ipvs/ip_vs_ctl.c

@@@ -97,38 -97,36 +97,38 @@@ Who:       Pavel Machek <pavel@ucw.cz
  
  ---------------------------
  
 -What: Video4Linux API 1 ioctls and from Video devices.
 -When: kernel 2.6.38
 -Files:        include/linux/videodev.h
 -Check:        include/linux/videodev.h
 -Why:  V4L1 AP1 was replaced by V4L2 API during migration from 2.4 to 2.6
 -      series. The old API have lots of drawbacks and don't provide enough
 -      means to work with all video and audio standards. The newer API is
 -      already available on the main drivers and should be used instead.
 -      Newer drivers should use v4l_compat_translate_ioctl function to handle
 -      old calls, replacing to newer ones.
 -      Decoder iocts are using internally to allow video drivers to
 -      communicate with video decoders. This should also be improved to allow
 -      V4L2 calls being translated into compatible internal ioctls.
 -      Compatibility ioctls will be provided, for a while, via 
 -      v4l1-compat module. 
 -Who:  Mauro Carvalho Chehab <mchehab@infradead.org>
 -
 ----------------------------
 -
  What: Video4Linux obsolete drivers using V4L1 API
 -When: kernel 2.6.38
 -Files:        drivers/staging/cpia/* drivers/staging/stradis/*
 -Check:        drivers/staging/cpia/cpia.c drivers/staging/stradis/stradis.c
 +When: kernel 2.6.39
 +Files:        drivers/staging/se401/* drivers/staging/usbvideo/*
 +Check:        drivers/staging/se401/se401.c drivers/staging/usbvideo/usbvideo.c
  Why:  There are some drivers still using V4L1 API, despite all efforts we've done
        to migrate. Those drivers are for obsolete hardware that the old maintainer
        didn't care (or not have the hardware anymore), and that no other developer
        could find any hardware to buy. They probably have no practical usage today,
        and people with such old hardware could probably keep using an older version
 -      of the kernel. Those drivers will be moved to staging on 2.6.37 and, if nobody
 -      care enough to port and test them with V4L2 API, they'll be removed on 2.6.38.
 +      of the kernel. Those drivers will be moved to staging on 2.6.38 and, if nobody
 +      cares enough to port and test them with V4L2 API, they'll be removed on 2.6.39.
 +Who:  Mauro Carvalho Chehab <mchehab@infradead.org>
 +
 +---------------------------
 +
 +What: Video4Linux: Remove obsolete ioctl's
 +When: kernel 2.6.39
 +Files:        include/media/videodev2.h
 +Why:  Some ioctl's were defined wrong on 2.6.2 and 2.6.6, using the wrong
 +      type of R/W arguments. They were fixed, but the old ioctl names are
 +      still there, maintained to avoid breaking binary compatibility:
 +        #define VIDIOC_OVERLAY_OLD    _IOWR('V', 14, int)
 +        #define VIDIOC_S_PARM_OLD     _IOW('V', 22, struct v4l2_streamparm)
 +        #define VIDIOC_S_CTRL_OLD     _IOW('V', 28, struct v4l2_control)
 +        #define VIDIOC_G_AUDIO_OLD    _IOWR('V', 33, struct v4l2_audio)
 +        #define VIDIOC_G_AUDOUT_OLD   _IOWR('V', 49, struct v4l2_audioout)
 +        #define VIDIOC_CROPCAP_OLD    _IOR('V', 58, struct v4l2_cropcap)
 +      There's no sense on preserving those forever, as it is very doubtful
 +      that someone would try to use a such old binary with a modern kernel.
 +      Removing them will allow us to remove some magic done at the V4L ioctl
 +      handler.
 +
  Who:  Mauro Carvalho Chehab <mchehab@infradead.org>
  
  ---------------------------
@@@ -566,3 -564,13 +566,13 @@@ Why:     This field is deprecated. I2C devi
  Who:  Jean Delvare <khali@linux-fr.org>
  
  ----------------------------
+ What: cancel_rearming_delayed_work[queue]()
+ When: 2.6.39
+ Why:  The functions have been superceded by cancel_delayed_work_sync()
+       quite some time ago.  The conversion is trivial and there is no
+       in-kernel user left.
+ Who:  Tejun Heo <tj@kernel.org>
+ ----------------------------
@@@ -4807,6 -4807,9 +4807,6 @@@ static void ata_verify_xfer(struct ata_
  {
        struct ata_device *dev = qc->dev;
  
 -      if (ata_tag_internal(qc->tag))
 -              return;
 -
        if (ata_is_nodata(qc->tf.protocol))
                return;
  
@@@ -4855,23 -4858,14 +4855,23 @@@ void ata_qc_complete(struct ata_queued_
                if (unlikely(qc->err_mask))
                        qc->flags |= ATA_QCFLAG_FAILED;
  
 -              if (unlikely(qc->flags & ATA_QCFLAG_FAILED)) {
 -                      /* always fill result TF for failed qc */
 +              /*
 +               * Finish internal commands without any further processing
 +               * and always with the result TF filled.
 +               */
 +              if (unlikely(ata_tag_internal(qc->tag))) {
                        fill_result_tf(qc);
 +                      __ata_qc_complete(qc);
 +                      return;
 +              }
  
 -                      if (!ata_tag_internal(qc->tag))
 -                              ata_qc_schedule_eh(qc);
 -                      else
 -                              __ata_qc_complete(qc);
 +              /*
 +               * Non-internal qc has failed.  Fill the result TF and
 +               * summon EH.
 +               */
 +              if (unlikely(qc->flags & ATA_QCFLAG_FAILED)) {
 +                      fill_result_tf(qc);
 +                      ata_qc_schedule_eh(qc);
                        return;
                }
  
@@@ -6128,7 -6122,7 +6128,7 @@@ static void ata_port_detach(struct ata_
        /* it better be dead now */
        WARN_ON(!(ap->pflags & ATA_PFLAG_UNLOADED));
  
-       cancel_rearming_delayed_work(&ap->hotplug_task);
+       cancel_delayed_work_sync(&ap->hotplug_task);
  
   skip_eh:
        if (ap->pmp_link) {
diff --combined drivers/ata/libata-sff.c
@@@ -1320,7 -1320,7 +1320,7 @@@ void ata_sff_flush_pio_task(struct ata_
  {
        DPRINTK("ENTER\n");
  
-       cancel_rearming_delayed_work(&ap->sff_pio_task);
+       cancel_delayed_work_sync(&ap->sff_pio_task);
        ap->hsm_task_state = HSM_ST_IDLE;
  
        if (ata_msg_ctl(ap))
@@@ -1532,10 -1532,11 +1532,10 @@@ static unsigned int __ata_sff_port_intr
                if (!(qc->dev->flags & ATA_DFLAG_CDB_INTR))
                        return ata_sff_idle_irq(ap);
                break;
 -      case HSM_ST:
 -      case HSM_ST_LAST:
 -              break;
 -      default:
 +      case HSM_ST_IDLE:
                return ata_sff_idle_irq(ap);
 +      default:
 +              break;
        }
  
        /* check main status, clearing INTRQ if needed */
@@@ -65,14 -65,14 +65,14 @@@ enum blkif_state 
  
  struct blk_shadow {
        struct blkif_request req;
 -      unsigned long request;
 +      struct request *request;
        unsigned long frame[BLKIF_MAX_SEGMENTS_PER_REQUEST];
  };
  
  static DEFINE_MUTEX(blkfront_mutex);
  static const struct block_device_operations xlvbd_block_fops;
  
 -#define BLK_RING_SIZE __RING_SIZE((struct blkif_sring *)0, PAGE_SIZE)
 +#define BLK_RING_SIZE __CONST_RING_SIZE(blkif, PAGE_SIZE)
  
  /*
   * We have one of these per vbd, whether ide, scsi or 'other'.  They
@@@ -136,7 -136,7 +136,7 @@@ static void add_id_to_freelist(struct b
                               unsigned long id)
  {
        info->shadow[id].req.id  = info->shadow_free;
 -      info->shadow[id].request = 0;
 +      info->shadow[id].request = NULL;
        info->shadow_free = id;
  }
  
@@@ -245,11 -245,14 +245,11 @@@ static int blkif_ioctl(struct block_dev
  }
  
  /*
 - * blkif_queue_request
 + * Generate a Xen blkfront IO request from a blk layer request.  Reads
 + * and writes are handled as expected.  Since we lack a loose flush
 + * request, we map flushes into a full ordered barrier.
   *
 - * request block io
 - *
 - * id: for guest use only.
 - * operation: BLKIF_OP_{READ,WRITE,PROBE}
 - * buffer: buffer to read/write into. this should be a
 - *   virtual address in the guest os.
 + * @req: a request struct
   */
  static int blkif_queue_request(struct request *req)
  {
        /* Fill out a communications ring structure. */
        ring_req = RING_GET_REQUEST(&info->ring, info->ring.req_prod_pvt);
        id = get_id_from_freelist(info);
 -      info->shadow[id].request = (unsigned long)req;
 +      info->shadow[id].request = req;
  
        ring_req->id = id;
        ring_req->sector_number = (blkif_sector_t)blk_rq_pos(req);
        ring_req->operation = rq_data_dir(req) ?
                BLKIF_OP_WRITE : BLKIF_OP_READ;
  
 +      if (req->cmd_flags & (REQ_FLUSH | REQ_FUA)) {
 +              /*
 +               * Ideally we could just do an unordered
 +               * flush-to-disk, but all we have is a full write
 +               * barrier at the moment.  However, a barrier write is
 +               * a superset of FUA, so we can implement it the same
 +               * way.  (It's also a FLUSH+FUA, since it is
 +               * guaranteed ordered WRT previous writes.)
 +               */
 +              ring_req->operation = BLKIF_OP_WRITE_BARRIER;
 +      }
 +
        ring_req->nr_segments = blk_rq_map_sg(req->q, req, info->sg);
        BUG_ON(ring_req->nr_segments > BLKIF_MAX_SEGMENTS_PER_REQUEST);
  
@@@ -547,7 -538,7 +547,7 @@@ static void xlvbd_release_gendisk(struc
        spin_unlock_irqrestore(&blkif_io_lock, flags);
  
        /* Flush gnttab callback work. Must be done with no locks held. */
-       flush_scheduled_work();
+       flush_work_sync(&info->work);
  
        del_gendisk(info->gd);
  
@@@ -596,7 -587,7 +596,7 @@@ static void blkif_free(struct blkfront_
        spin_unlock_irq(&blkif_io_lock);
  
        /* Flush gnttab callback work. Must be done with no locks held. */
-       flush_scheduled_work();
+       flush_work_sync(&info->work);
  
        /* Free resources associated with old device channel. */
        if (info->ring_ref != GRANT_INVALID_REF) {
@@@ -643,7 -634,7 +643,7 @@@ static irqreturn_t blkif_interrupt(int 
  
                bret = RING_GET_RESPONSE(&info->ring, i);
                id   = bret->id;
 -              req  = (struct request *)info->shadow[id].request;
 +              req  = info->shadow[id].request;
  
                blkif_completion(&info->shadow[id]);
  
                                printk(KERN_WARNING "blkfront: %s: write barrier op failed\n",
                                       info->gd->disk_name);
                                error = -EOPNOTSUPP;
 +                      }
 +                      if (unlikely(bret->status == BLKIF_RSP_ERROR &&
 +                                   info->shadow[id].req.nr_segments == 0)) {
 +                              printk(KERN_WARNING "blkfront: %s: empty write barrier op failed\n",
 +                                     info->gd->disk_name);
 +                              error = -EOPNOTSUPP;
 +                      }
 +                      if (unlikely(error)) {
 +                              if (error == -EOPNOTSUPP)
 +                                      error = 0;
                                info->feature_flush = 0;
                                xlvbd_flush(info);
                        }
@@@ -918,7 -899,7 +918,7 @@@ static int blkif_recover(struct blkfron
        /* Stage 3: Find pending requests and requeue them. */
        for (i = 0; i < BLK_RING_SIZE; i++) {
                /* Not in use? */
 -              if (copy[i].request == 0)
 +              if (!copy[i].request)
                        continue;
  
                /* Grab a request slot and copy shadow state into it. */
                                req->seg[j].gref,
                                info->xbdev->otherend_id,
                                pfn_to_mfn(info->shadow[req->id].frame[j]),
 -                              rq_data_dir(
 -                                      (struct request *)
 -                                      info->shadow[req->id].request));
 +                              rq_data_dir(info->shadow[req->id].request));
                info->shadow[req->id].req = *req;
  
                info->ring.req_prod_pvt++;
@@@ -1084,8 -1067,14 +1084,8 @@@ static void blkfront_connect(struct blk
         */
        info->feature_flush = 0;
  
 -      /*
 -       * The driver doesn't properly handled empty flushes, so
 -       * lets disable barrier support for now.
 -       */
 -#if 0
        if (!err && barrier)
 -              info->feature_flush = REQ_FLUSH;
 -#endif
 +              info->feature_flush = REQ_FLUSH | REQ_FUA;
  
        err = xlvbd_alloc_gendisk(sectors, info, binfo, sector_size);
        if (err) {
@@@ -13,11 -13,11 +13,11 @@@ static int legacy_dvb_usb_getkeycode(st
  {
        struct dvb_usb_device *d = input_get_drvdata(dev);
  
 -      struct ir_scancode *keymap = d->props.rc.legacy.rc_key_map;
 +      struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table;
        int i;
  
        /* See if we can match the raw key code. */
 -      for (i = 0; i < d->props.rc.legacy.rc_key_map_size; i++)
 +      for (i = 0; i < d->props.rc.legacy.rc_map_size; i++)
                if (keymap[i].scancode == scancode) {
                        *keycode = keymap[i].keycode;
                        return 0;
@@@ -28,7 -28,7 +28,7 @@@
         * otherwise, input core won't let legacy_dvb_usb_setkeycode
         * to work
         */
 -      for (i = 0; i < d->props.rc.legacy.rc_key_map_size; i++)
 +      for (i = 0; i < d->props.rc.legacy.rc_map_size; i++)
                if (keymap[i].keycode == KEY_RESERVED ||
                    keymap[i].keycode == KEY_UNKNOWN) {
                        *keycode = KEY_RESERVED;
@@@ -43,18 -43,18 +43,18 @@@ static int legacy_dvb_usb_setkeycode(st
  {
        struct dvb_usb_device *d = input_get_drvdata(dev);
  
 -      struct ir_scancode *keymap = d->props.rc.legacy.rc_key_map;
 +      struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table;
        int i;
  
        /* Search if it is replacing an existing keycode */
 -      for (i = 0; i < d->props.rc.legacy.rc_key_map_size; i++)
 +      for (i = 0; i < d->props.rc.legacy.rc_map_size; i++)
                if (keymap[i].scancode == scancode) {
                        keymap[i].keycode = keycode;
                        return 0;
                }
  
        /* Search if is there a clean entry. If so, use it */
 -      for (i = 0; i < d->props.rc.legacy.rc_key_map_size; i++)
 +      for (i = 0; i < d->props.rc.legacy.rc_map_size; i++)
                if (keymap[i].keycode == KEY_RESERVED ||
                    keymap[i].keycode == KEY_UNKNOWN) {
                        keymap[i].scancode = scancode;
@@@ -106,10 -106,10 +106,10 @@@ static void legacy_dvb_usb_read_remote_
                        d->last_event = event;
                case REMOTE_KEY_REPEAT:
                        deb_rc("key repeated\n");
 -                      input_event(d->rc_input_dev, EV_KEY, event, 1);
 -                      input_sync(d->rc_input_dev);
 -                      input_event(d->rc_input_dev, EV_KEY, d->last_event, 0);
 -                      input_sync(d->rc_input_dev);
 +                      input_event(d->input_dev, EV_KEY, event, 1);
 +                      input_sync(d->input_dev);
 +                      input_event(d->input_dev, EV_KEY, d->last_event, 0);
 +                      input_sync(d->input_dev);
                        break;
                default:
                        break;
@@@ -154,32 -154,20 +154,32 @@@ schedule
        schedule_delayed_work(&d->rc_query_work,msecs_to_jiffies(d->props.rc.legacy.rc_interval));
  }
  
 -static int legacy_dvb_usb_remote_init(struct dvb_usb_device *d,
 -                                    struct input_dev *input_dev)
 +static int legacy_dvb_usb_remote_init(struct dvb_usb_device *d)
  {
        int i, err, rc_interval;
 +      struct input_dev *input_dev;
 +
 +      input_dev = input_allocate_device();
 +      if (!input_dev)
 +              return -ENOMEM;
 +
 +      input_dev->evbit[0] = BIT_MASK(EV_KEY);
 +      input_dev->name = "IR-receiver inside an USB DVB receiver";
 +      input_dev->phys = d->rc_phys;
 +      usb_to_input_id(d->udev, &input_dev->id);
 +      input_dev->dev.parent = &d->udev->dev;
 +      d->input_dev = input_dev;
 +      d->rc_dev = NULL;
  
        input_dev->getkeycode = legacy_dvb_usb_getkeycode;
        input_dev->setkeycode = legacy_dvb_usb_setkeycode;
  
        /* set the bits for the keys */
 -      deb_rc("key map size: %d\n", d->props.rc.legacy.rc_key_map_size);
 -      for (i = 0; i < d->props.rc.legacy.rc_key_map_size; i++) {
 +      deb_rc("key map size: %d\n", d->props.rc.legacy.rc_map_size);
 +      for (i = 0; i < d->props.rc.legacy.rc_map_size; i++) {
                deb_rc("setting bit for event %d item %d\n",
 -                      d->props.rc.legacy.rc_key_map[i].keycode, i);
 -              set_bit(d->props.rc.legacy.rc_key_map[i].keycode, input_dev->keybit);
 +                      d->props.rc.legacy.rc_map_table[i].keycode, i);
 +              set_bit(d->props.rc.legacy.rc_map_table[i].keycode, input_dev->keybit);
        }
  
        /* setting these two values to non-zero, we have to manage key repeats */
@@@ -233,34 -221,18 +233,34 @@@ static void dvb_usb_read_remote_control
                              msecs_to_jiffies(d->props.rc.core.rc_interval));
  }
  
 -static int rc_core_dvb_usb_remote_init(struct dvb_usb_device *d,
 -                                     struct input_dev *input_dev)
 +static int rc_core_dvb_usb_remote_init(struct dvb_usb_device *d)
  {
        int err, rc_interval;
 +      struct rc_dev *dev;
 +
 +      dev = rc_allocate_device();
 +      if (!dev)
 +              return -ENOMEM;
  
 -      d->props.rc.core.rc_props.priv = d;
 -      err = ir_input_register(input_dev,
 -                               d->props.rc.core.rc_codes,
 -                               &d->props.rc.core.rc_props,
 -                               d->props.rc.core.module_name);
 -      if (err < 0)
 +      dev->driver_name = d->props.rc.core.module_name;
 +      dev->map_name = d->props.rc.core.rc_codes;
 +      dev->change_protocol = d->props.rc.core.change_protocol;
 +      dev->allowed_protos = d->props.rc.core.allowed_protos;
 +      dev->driver_type = RC_DRIVER_SCANCODE;
 +      usb_to_input_id(d->udev, &dev->input_id);
 +      dev->input_name = "IR-receiver inside an USB DVB receiver";
 +      dev->input_phys = d->rc_phys;
 +      dev->dev.parent = &d->udev->dev;
 +      dev->priv = d;
 +
 +      err = rc_register_device(dev);
 +      if (err < 0) {
 +              rc_free_device(dev);
                return err;
 +      }
 +
 +      d->input_dev = NULL;
 +      d->rc_dev = dev;
  
        if (!d->props.rc.core.rc_query || d->props.rc.core.bulk_mode)
                return 0;
  
  int dvb_usb_remote_init(struct dvb_usb_device *d)
  {
 -      struct input_dev *input_dev;
        int err;
  
        if (dvb_usb_disable_rc_polling)
                return 0;
  
 -      if (d->props.rc.legacy.rc_key_map && d->props.rc.legacy.rc_query)
 +      if (d->props.rc.legacy.rc_map_table && d->props.rc.legacy.rc_query)
                d->props.rc.mode = DVB_RC_LEGACY;
        else if (d->props.rc.core.rc_codes)
                d->props.rc.mode = DVB_RC_CORE;
        usb_make_path(d->udev, d->rc_phys, sizeof(d->rc_phys));
        strlcat(d->rc_phys, "/ir0", sizeof(d->rc_phys));
  
 -      input_dev = input_allocate_device();
 -      if (!input_dev)
 -              return -ENOMEM;
 -
 -      input_dev->evbit[0] = BIT_MASK(EV_KEY);
 -      input_dev->name = "IR-receiver inside an USB DVB receiver";
 -      input_dev->phys = d->rc_phys;
 -      usb_to_input_id(d->udev, &input_dev->id);
 -      input_dev->dev.parent = &d->udev->dev;
 -
        /* Start the remote-control polling. */
        if (d->props.rc.legacy.rc_interval < 40)
                d->props.rc.legacy.rc_interval = 100; /* default */
  
 -      d->rc_input_dev = input_dev;
 -
        if (d->props.rc.mode == DVB_RC_LEGACY)
 -              err = legacy_dvb_usb_remote_init(d, input_dev);
 +              err = legacy_dvb_usb_remote_init(d);
        else
 -              err = rc_core_dvb_usb_remote_init(d, input_dev);
 +              err = rc_core_dvb_usb_remote_init(d);
        if (err)
                return err;
  
  int dvb_usb_remote_exit(struct dvb_usb_device *d)
  {
        if (d->state & DVB_USB_STATE_REMOTE) {
-               cancel_rearming_delayed_work(&d->rc_query_work);
-               flush_scheduled_work();
+               cancel_delayed_work_sync(&d->rc_query_work);
                if (d->props.rc.mode == DVB_RC_LEGACY)
 -                      input_unregister_device(d->rc_input_dev);
 +                      input_unregister_device(d->input_dev);
                else
 -                      ir_input_unregister(d->rc_input_dev);
 +                      rc_unregister_device(d->rc_dev);
        }
        d->state &= ~DVB_USB_STATE_REMOTE;
        return 0;
@@@ -331,7 -315,7 +330,7 @@@ int dvb_usb_nec_rc_key_to_event(struct 
                u8 keybuf[5], u32 *event, int *state)
  {
        int i;
 -      struct ir_scancode *keymap = d->props.rc.legacy.rc_key_map;
 +      struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table;
        *event = 0;
        *state = REMOTE_NO_KEY_PRESSED;
        switch (keybuf[0]) {
                                break;
                        }
                        /* See if we can match the raw key code. */
 -                      for (i = 0; i < d->props.rc.legacy.rc_key_map_size; i++)
 +                      for (i = 0; i < d->props.rc.legacy.rc_map_size; i++)
                                if (rc5_custom(&keymap[i]) == keybuf[1] &&
                                        rc5_data(&keymap[i]) == keybuf[3]) {
                                        *event = keymap[i].keycode;
@@@ -55,7 -55,7 +55,7 @@@
  #include <asm/io.h>
  #include <asm/byteorder.h>
  
 -#include <media/rds.h>
 +#include <media/saa6588.h>
  
  
  unsigned int bttv_num;                        /* number of Bt848s in use */
@@@ -189,8 -189,14 +189,14 @@@ static void request_modules(struct btt
        INIT_WORK(&dev->request_module_wk, request_module_async);
        schedule_work(&dev->request_module_wk);
  }
+ static void flush_request_modules(struct bttv *dev)
+ {
+       flush_work_sync(&dev->request_module_wk);
+ }
  #else
  #define request_modules(dev)
+ #define flush_request_modules(dev)
  #endif /* CONFIG_MODULES */
  
  
@@@ -854,6 -860,7 +860,6 @@@ int check_alloc_btres_lock(struct bttv 
                xbits |= RESOURCE_VIDEO_READ | RESOURCE_VIDEO_STREAM;
  
        /* is it free? */
 -      mutex_lock(&btv->lock);
        if (btv->resources & xbits) {
                /* no, someone else uses it */
                goto fail;
        /* it's free, grab it */
        fh->resources  |= bit;
        btv->resources |= bit;
 -      mutex_unlock(&btv->lock);
        return 1;
  
   fail:
 -      mutex_unlock(&btv->lock);
        return 0;
  }
  
@@@ -937,6 -946,7 +943,6 @@@ void free_btres_lock(struct bttv *btv, 
                /* trying to free ressources not allocated by us ... */
                printk("bttv: BUG! (btres)\n");
        }
 -      mutex_lock(&btv->lock);
        fh->resources  &= ~bits;
        btv->resources &= ~bits;
  
  
        if (0 == (bits & VBI_RESOURCES))
                disclaim_vbi_lines(btv);
 -
 -      mutex_unlock(&btv->lock);
  }
  
  /* ----------------------------------------------------------------------- */
@@@ -1707,20 -1719,28 +1713,20 @@@ static int bttv_prepare_buffer(struct v
  
                /* Make sure tvnorm and vbi_end remain consistent
                   until we're done. */
 -              mutex_lock(&btv->lock);
  
                norm = btv->tvnorm;
  
                /* In this mode capturing always starts at defrect.top
                   (default VDELAY), ignoring cropping parameters. */
                if (btv->vbi_end > bttv_tvnorms[norm].cropcap.defrect.top) {
 -                      mutex_unlock(&btv->lock);
                        return -EINVAL;
                }
  
 -              mutex_unlock(&btv->lock);
 -
                c.rect = bttv_tvnorms[norm].cropcap.defrect;
        } else {
 -              mutex_lock(&btv->lock);
 -
                norm = btv->tvnorm;
                c = btv->crop[!!fh->do_crop];
  
 -              mutex_unlock(&btv->lock);
 -
                if (width < c.min_scaled_width ||
                    width > c.max_scaled_width ||
                    height < c.min_scaled_height)
@@@ -1844,6 -1864,7 +1850,6 @@@ static int bttv_s_std(struct file *file
        unsigned int i;
        int err;
  
 -      mutex_lock(&btv->lock);
        err = v4l2_prio_check(&btv->prio, fh->prio);
        if (err)
                goto err;
        set_tvnorm(btv, i);
  
  err:
 -      mutex_unlock(&btv->lock);
  
        return err;
  }
@@@ -1882,6 -1904,7 +1888,6 @@@ static int bttv_enum_input(struct file 
        struct bttv *btv = fh->btv;
        int rc = 0;
  
 -      mutex_lock(&btv->lock);
        if (i->index >= bttv_tvcards[btv->c.type].video_inputs) {
                rc = -EINVAL;
                goto err;
        i->std = BTTV_NORMS;
  
  err:
 -      mutex_unlock(&btv->lock);
  
        return rc;
  }
@@@ -1920,7 -1944,9 +1926,7 @@@ static int bttv_g_input(struct file *fi
        struct bttv_fh *fh = priv;
        struct bttv *btv = fh->btv;
  
 -      mutex_lock(&btv->lock);
        *i = btv->input;
 -      mutex_unlock(&btv->lock);
  
        return 0;
  }
@@@ -1932,6 -1958,7 +1938,6 @@@ static int bttv_s_input(struct file *fi
  
        int err;
  
 -      mutex_lock(&btv->lock);
        err = v4l2_prio_check(&btv->prio, fh->prio);
        if (unlikely(err))
                goto err;
        set_input(btv, i, btv->tvnorm);
  
  err:
 -      mutex_unlock(&btv->lock);
        return 0;
  }
  
@@@ -1957,6 -1985,7 +1963,6 @@@ static int bttv_s_tuner(struct file *fi
        if (unlikely(0 != t->index))
                return -EINVAL;
  
 -      mutex_lock(&btv->lock);
        if (unlikely(btv->tuner_type == TUNER_ABSENT)) {
                err = -EINVAL;
                goto err;
                btv->audio_mode_gpio(btv, t, 1);
  
  err:
 -      mutex_unlock(&btv->lock);
  
        return 0;
  }
@@@ -1982,8 -2012,10 +1988,8 @@@ static int bttv_g_frequency(struct fil
        struct bttv_fh *fh  = priv;
        struct bttv *btv = fh->btv;
  
 -      mutex_lock(&btv->lock);
        f->type = btv->radio_user ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
        f->frequency = btv->freq;
 -      mutex_unlock(&btv->lock);
  
        return 0;
  }
@@@ -1998,6 -2030,7 +2004,6 @@@ static int bttv_s_frequency(struct fil
        if (unlikely(f->tuner != 0))
                return -EINVAL;
  
 -      mutex_lock(&btv->lock);
        err = v4l2_prio_check(&btv->prio, fh->prio);
        if (unlikely(err))
                goto err;
        if (btv->has_matchbox && btv->radio_user)
                tea5757_set_freq(btv, btv->freq);
  err:
 -      mutex_unlock(&btv->lock);
  
        return 0;
  }
@@@ -2144,6 -2178,7 +2150,6 @@@ limit_scaled_size_lock       (struct bt
  
        /* Make sure tvnorm, vbi_end and the current cropping parameters
           remain consistent until we're done. */
 -      mutex_lock(&btv->lock);
  
        b = &bttv_tvnorms[btv->tvnorm].cropcap.bounds;
  
        rc = 0; /* success */
  
   fail:
 -      mutex_unlock(&btv->lock);
  
        return rc;
  }
@@@ -2252,7 -2288,9 +2258,7 @@@ verify_window_lock              (struct bttv_fh 
        if (V4L2_FIELD_ANY == field) {
                __s32 height2;
  
 -              mutex_lock(&fh->btv->lock);
                height2 = fh->btv->crop[!!fh->do_crop].rect.height >> 1;
 -              mutex_unlock(&fh->btv->lock);
                field = (win->w.height > height2)
                        ? V4L2_FIELD_INTERLACED
                        : V4L2_FIELD_TOP;
@@@ -2328,6 -2366,7 +2334,6 @@@ static int setup_window_lock(struct btt
                }
        }
  
 -      mutex_lock(&fh->cap.vb_lock);
        /* clip against screen */
        if (NULL != btv->fbuf.base)
                n = btcx_screen_clips(btv->fbuf.fmt.width, btv->fbuf.fmt.height,
        fh->ov.field    = win->field;
        fh->ov.setup_ok = 1;
  
 -      /*
 -       * FIXME: btv is protected by btv->lock mutex, while btv->init
 -       *        is protected by fh->cap.vb_lock. This seems to open the
 -       *        possibility for some race situations. Maybe the better would
 -       *        be to unify those locks or to use another way to store the
 -       *        init values that will be consumed by videobuf callbacks
 -       */
        btv->init.ov.w.width   = win->w.width;
        btv->init.ov.w.height  = win->w.height;
        btv->init.ov.field     = win->field;
                bttv_overlay_risc(btv, &fh->ov, fh->ovfmt, new);
                retval = bttv_switch_overlay(btv,fh,new);
        }
 -      mutex_unlock(&fh->cap.vb_lock);
        return retval;
  }
  
@@@ -2485,7 -2532,9 +2491,7 @@@ static int bttv_try_fmt_vid_cap(struct 
        if (V4L2_FIELD_ANY == field) {
                __s32 height2;
  
 -              mutex_lock(&btv->lock);
                height2 = btv->crop[!!fh->do_crop].rect.height >> 1;
 -              mutex_unlock(&btv->lock);
                field = (f->fmt.pix.height > height2)
                        ? V4L2_FIELD_INTERLACED
                        : V4L2_FIELD_BOTTOM;
@@@ -2571,6 -2620,7 +2577,6 @@@ static int bttv_s_fmt_vid_cap(struct fi
        fmt = format_by_fourcc(f->fmt.pix.pixelformat);
  
        /* update our state informations */
 -      mutex_lock(&fh->cap.vb_lock);
        fh->fmt              = fmt;
        fh->cap.field        = f->fmt.pix.field;
        fh->cap.last         = V4L2_FIELD_NONE;
        btv->init.fmt        = fmt;
        btv->init.width      = f->fmt.pix.width;
        btv->init.height     = f->fmt.pix.height;
 -      mutex_unlock(&fh->cap.vb_lock);
  
        return 0;
  }
@@@ -2597,6 -2648,34 +2603,6 @@@ static int bttv_s_fmt_vid_overlay(struc
        return setup_window_lock(fh, btv, &f->fmt.win, 1);
  }
  
 -#ifdef CONFIG_VIDEO_V4L1_COMPAT
 -static int vidiocgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf)
 -{
 -      int retval;
 -      unsigned int i;
 -      struct bttv_fh *fh = priv;
 -
 -      mutex_lock(&fh->cap.vb_lock);
 -      retval = __videobuf_mmap_setup(&fh->cap, gbuffers, gbufsize,
 -                                   V4L2_MEMORY_MMAP);
 -      if (retval < 0) {
 -              mutex_unlock(&fh->cap.vb_lock);
 -              return retval;
 -      }
 -
 -      gbuffers = retval;
 -      memset(mbuf, 0, sizeof(*mbuf));
 -      mbuf->frames = gbuffers;
 -      mbuf->size   = gbuffers * gbufsize;
 -
 -      for (i = 0; i < gbuffers; i++)
 -              mbuf->offsets[i] = i * gbufsize;
 -
 -      mutex_unlock(&fh->cap.vb_lock);
 -      return 0;
 -}
 -#endif
 -
  static int bttv_querycap(struct file *file, void  *priv,
                                struct v4l2_capability *cap)
  {
@@@ -2702,8 -2781,10 +2708,8 @@@ static int bttv_overlay(struct file *fi
        int retval = 0;
  
        if (on) {
 -              mutex_lock(&fh->cap.vb_lock);
                /* verify args */
                if (unlikely(!btv->fbuf.base)) {
 -                      mutex_unlock(&fh->cap.vb_lock);
                        return -EINVAL;
                }
                if (unlikely(!fh->ov.setup_ok)) {
                }
                if (retval)
                        return retval;
 -              mutex_unlock(&fh->cap.vb_lock);
        }
  
        if (!check_alloc_btres_lock(btv, fh, RESOURCE_OVERLAY))
                return -EBUSY;
  
 -      mutex_lock(&fh->cap.vb_lock);
        if (on) {
                fh->ov.tvnorm = btv->tvnorm;
                new = videobuf_sg_alloc(sizeof(*new));
  
        /* switch over */
        retval = bttv_switch_overlay(btv, fh, new);
 -      mutex_unlock(&fh->cap.vb_lock);
        return retval;
  }
  
@@@ -2766,6 -2850,7 +2772,6 @@@ static int bttv_s_fbuf(struct file *fil
        }
  
        /* ok, accept it */
 -      mutex_lock(&fh->cap.vb_lock);
        btv->fbuf.base       = fb->base;
        btv->fbuf.fmt.width  = fb->fmt.width;
        btv->fbuf.fmt.height = fb->fmt.height;
                        retval = bttv_switch_overlay(btv, fh, new);
                }
        }
 -      mutex_unlock(&fh->cap.vb_lock);
        return retval;
  }
  
@@@ -2875,6 -2961,7 +2881,6 @@@ static int bttv_queryctrl(struct file *
             c->id >= V4L2_CID_PRIVATE_LASTP1))
                return -EINVAL;
  
 -      mutex_lock(&btv->lock);
        if (!btv->volume_gpio && (c->id == V4L2_CID_AUDIO_VOLUME))
                *c = no_ctl;
        else {
  
                *c = (NULL != ctrl) ? *ctrl : no_ctl;
        }
 -      mutex_unlock(&btv->lock);
  
        return 0;
  }
@@@ -2892,8 -2980,10 +2898,8 @@@ static int bttv_g_parm(struct file *fil
        struct bttv_fh *fh = f;
        struct bttv *btv = fh->btv;
  
 -      mutex_lock(&btv->lock);
        v4l2_video_std_frame_period(bttv_tvnorms[btv->tvnorm].v4l2_id,
                                    &parm->parm.capture.timeperframe);
 -      mutex_unlock(&btv->lock);
  
        return 0;
  }
@@@ -2909,6 -2999,7 +2915,6 @@@ static int bttv_g_tuner(struct file *fi
        if (0 != t->index)
                return -EINVAL;
  
 -      mutex_lock(&btv->lock);
        t->rxsubchans = V4L2_TUNER_SUB_MONO;
        bttv_call_all(btv, tuner, g_tuner, t);
        strcpy(t->name, "Television");
        if (btv->audio_mode_gpio)
                btv->audio_mode_gpio(btv, t, 0);
  
 -      mutex_unlock(&btv->lock);
        return 0;
  }
  
@@@ -2928,7 -3020,9 +2934,7 @@@ static int bttv_g_priority(struct file 
        struct bttv_fh *fh = f;
        struct bttv *btv = fh->btv;
  
 -      mutex_lock(&btv->lock);
        *p = v4l2_prio_max(&btv->prio);
 -      mutex_unlock(&btv->lock);
  
        return 0;
  }
@@@ -2940,7 -3034,9 +2946,7 @@@ static int bttv_s_priority(struct file 
        struct bttv *btv = fh->btv;
        int     rc;
  
 -      mutex_lock(&btv->lock);
        rc = v4l2_prio_change(&btv->prio, &fh->prio, prio);
 -      mutex_unlock(&btv->lock);
  
        return rc;
  }
@@@ -2955,7 -3051,9 +2961,7 @@@ static int bttv_cropcap(struct file *fi
            cap->type != V4L2_BUF_TYPE_VIDEO_OVERLAY)
                return -EINVAL;
  
 -      mutex_lock(&btv->lock);
        *cap = bttv_tvnorms[btv->tvnorm].cropcap;
 -      mutex_unlock(&btv->lock);
  
        return 0;
  }
@@@ -2973,7 -3071,9 +2979,7 @@@ static int bttv_g_crop(struct file *fil
           inconsistent with fh->width or fh->height and apps
           do not expect a change here. */
  
 -      mutex_lock(&btv->lock);
        crop->c = btv->crop[!!fh->do_crop].rect;
 -      mutex_unlock(&btv->lock);
  
        return 0;
  }
@@@ -2997,14 -3097,17 +3003,14 @@@ static int bttv_s_crop(struct file *fil
        /* Make sure tvnorm, vbi_end and the current cropping
           parameters remain consistent until we're done. Note
           read() may change vbi_end in check_alloc_btres_lock(). */
 -      mutex_lock(&btv->lock);
        retval = v4l2_prio_check(&btv->prio, fh->prio);
        if (0 != retval) {
 -              mutex_unlock(&btv->lock);
                return retval;
        }
  
        retval = -EBUSY;
  
        if (locked_btres(fh->btv, VIDEO_RESOURCES)) {
 -              mutex_unlock(&btv->lock);
                return retval;
        }
  
  
        b_top = max(b->top, btv->vbi_end);
        if (b_top + 32 >= b_bottom) {
 -              mutex_unlock(&btv->lock);
                return retval;
        }
  
  
        btv->crop[1] = c;
  
 -      mutex_unlock(&btv->lock);
 -
        fh->do_crop = 1;
  
 -      mutex_lock(&fh->cap.vb_lock);
 -
        if (fh->width < c.min_scaled_width) {
                fh->width = c.min_scaled_width;
                btv->init.width = c.min_scaled_width;
                btv->init.height = c.max_scaled_height;
        }
  
 -      mutex_unlock(&fh->cap.vb_lock);
 -
        return 0;
  }
  
@@@ -3123,6 -3233,7 +3129,6 @@@ static unsigned int bttv_poll(struct fi
                return videobuf_poll_stream(file, &fh->vbi, wait);
        }
  
 -      mutex_lock(&fh->cap.vb_lock);
        if (check_btres(fh,RESOURCE_VIDEO_STREAM)) {
                /* streaming capture */
                if (list_empty(&fh->cap.stream))
        else
                rc = 0;
  err:
 -      mutex_unlock(&fh->cap.vb_lock);
        return rc;
  }
  
@@@ -3187,11 -3299,23 +3193,11 @@@ static int bttv_open(struct file *file
                return -ENOMEM;
        file->private_data = fh;
  
 -      /*
 -       * btv is protected by btv->lock mutex, while btv->init and other
 -       * streaming vars are protected by fh->cap.vb_lock. We need to take
 -       * care of both locks to avoid troubles. However, vb_lock is used also
 -       * inside videobuf, without calling buf->lock. So, it is a very bad
 -       * idea to hold both locks at the same time.
 -       * Let's first copy btv->init at fh, holding cap.vb_lock, and then work
 -       * with the rest of init, holding btv->lock.
 -       */
 -      mutex_lock(&fh->cap.vb_lock);
        *fh = btv->init;
 -      mutex_unlock(&fh->cap.vb_lock);
  
        fh->type = type;
        fh->ov.setup_ok = 0;
  
 -      mutex_lock(&btv->lock);
        v4l2_prio_open(&btv->prio, &fh->prio);
  
        videobuf_queue_sg_init(&fh->cap, &bttv_video_qops,
                            V4L2_BUF_TYPE_VIDEO_CAPTURE,
                            V4L2_FIELD_INTERLACED,
                            sizeof(struct bttv_buffer),
 -                          fh, NULL);
 +                          fh, &btv->lock);
        videobuf_queue_sg_init(&fh->vbi, &bttv_vbi_qops,
                            &btv->c.pci->dev, &btv->s_lock,
                            V4L2_BUF_TYPE_VBI_CAPTURE,
                            V4L2_FIELD_SEQ_TB,
                            sizeof(struct bttv_buffer),
 -                          fh, NULL);
 +                          fh, &btv->lock);
        set_tvnorm(btv,btv->tvnorm);
        set_input(btv, btv->input, btv->tvnorm);
  
        bttv_vbi_fmt_reset(&fh->vbi_fmt, btv->tvnorm);
  
        bttv_field_count(btv);
 -      mutex_unlock(&btv->lock);
        return 0;
  }
  
@@@ -3236,6 -3361,7 +3242,6 @@@ static int bttv_release(struct file *fi
        struct bttv_fh *fh = file->private_data;
        struct bttv *btv = fh->btv;
  
 -      mutex_lock(&btv->lock);
        /* turn off overlay */
        if (check_btres(fh, RESOURCE_OVERLAY))
                bttv_switch_overlay(btv,fh,NULL);
  
        /* free stuff */
  
 -      /*
 -       * videobuf uses cap.vb_lock - we should avoid holding btv->lock,
 -       * otherwise we may have dead lock conditions
 -       */
 -      mutex_unlock(&btv->lock);
        videobuf_mmap_free(&fh->cap);
        videobuf_mmap_free(&fh->vbi);
 -      mutex_lock(&btv->lock);
        v4l2_prio_close(&btv->prio, fh->prio);
        file->private_data = NULL;
        kfree(fh);
  
        if (!btv->users)
                audio_mute(btv, 1);
 -      mutex_unlock(&btv->lock);
  
        return 0;
  }
@@@ -3329,6 -3462,9 +3335,6 @@@ static const struct v4l2_ioctl_ops bttv
        .vidioc_streamoff               = bttv_streamoff,
        .vidioc_g_tuner                 = bttv_g_tuner,
        .vidioc_s_tuner                 = bttv_s_tuner,
 -#ifdef CONFIG_VIDEO_V4L1_COMPAT
 -      .vidiocgmbuf                    = vidiocgmbuf,
 -#endif
        .vidioc_g_crop                  = bttv_g_crop,
        .vidioc_s_crop                  = bttv_s_crop,
        .vidioc_g_fbuf                  = bttv_g_fbuf,
@@@ -3372,8 -3508,11 +3378,8 @@@ static int radio_open(struct file *file
        if (unlikely(!fh))
                return -ENOMEM;
        file->private_data = fh;
 -      mutex_lock(&fh->cap.vb_lock);
        *fh = btv->init;
 -      mutex_unlock(&fh->cap.vb_lock);
  
 -      mutex_lock(&btv->lock);
        v4l2_prio_open(&btv->prio, &fh->prio);
  
        btv->radio_user++;
        bttv_call_all(btv, tuner, s_radio);
        audio_input(btv,TVAUDIO_INPUT_RADIO);
  
 -      mutex_unlock(&btv->lock);
        return 0;
  }
  
@@@ -3388,15 -3528,17 +3394,15 @@@ static int radio_release(struct file *f
  {
        struct bttv_fh *fh = file->private_data;
        struct bttv *btv = fh->btv;
 -      struct rds_command cmd;
 +      struct saa6588_command cmd;
  
 -      mutex_lock(&btv->lock);
        v4l2_prio_close(&btv->prio, fh->prio);
        file->private_data = NULL;
        kfree(fh);
  
        btv->radio_user--;
  
 -      bttv_call_all(btv, core, ioctl, RDS_CMD_CLOSE, &cmd);
 -      mutex_unlock(&btv->lock);
 +      bttv_call_all(btv, core, ioctl, SAA6588_CMD_CLOSE, &cmd);
  
        return 0;
  }
@@@ -3425,6 -3567,7 +3431,6 @@@ static int radio_g_tuner(struct file *f
                return -EINVAL;
        if (0 != t->index)
                return -EINVAL;
 -      mutex_lock(&btv->lock);
        strcpy(t->name, "Radio");
        t->type = V4L2_TUNER_RADIO;
  
        if (btv->audio_mode_gpio)
                btv->audio_mode_gpio(btv, t, 0);
  
 -      mutex_unlock(&btv->lock);
 -
        return 0;
  }
  
@@@ -3523,13 -3668,13 +3529,13 @@@ static ssize_t radio_read(struct file *
  {
        struct bttv_fh *fh = file->private_data;
        struct bttv *btv = fh->btv;
 -      struct rds_command cmd;
 +      struct saa6588_command cmd;
        cmd.block_count = count/3;
        cmd.buffer = data;
        cmd.instance = file;
        cmd.result = -ENODEV;
  
 -      bttv_call_all(btv, core, ioctl, RDS_CMD_READ, &cmd);
 +      bttv_call_all(btv, core, ioctl, SAA6588_CMD_READ, &cmd);
  
        return cmd.result;
  }
@@@ -3538,11 -3683,11 +3544,11 @@@ static unsigned int radio_poll(struct f
  {
        struct bttv_fh *fh = file->private_data;
        struct bttv *btv = fh->btv;
 -      struct rds_command cmd;
 +      struct saa6588_command cmd;
        cmd.instance = file;
        cmd.event_list = wait;
        cmd.result = -ENODEV;
 -      bttv_call_all(btv, core, ioctl, RDS_CMD_POLL, &cmd);
 +      bttv_call_all(btv, core, ioctl, SAA6588_CMD_POLL, &cmd);
  
        return cmd.result;
  }
@@@ -3553,7 -3698,7 +3559,7 @@@ static const struct v4l2_file_operation
        .open     = radio_open,
        .read     = radio_read,
        .release  = radio_release,
 -      .ioctl    = video_ioctl2,
 +      .unlocked_ioctl = video_ioctl2,
        .poll     = radio_poll,
  };
  
@@@ -4013,6 -4158,9 +4019,6 @@@ static irqreturn_t bttv_irq(int irq, vo
  
        btv=(struct bttv *)dev_id;
  
 -      if (btv->custom_irq)
 -              handled = btv->custom_irq(btv);
 -
        count=0;
        while (1) {
                /* get/clear interrupt status bits */
                        btv->field_count++;
  
                if ((astat & BT848_INT_GPINT) && btv->remote) {
 -                      wake_up(&btv->gpioq);
                        bttv_input_irq(btv);
                }
  
@@@ -4252,6 -4401,7 +4258,6 @@@ static int __devinit bttv_probe(struct 
        mutex_init(&btv->lock);
        spin_lock_init(&btv->s_lock);
        spin_lock_init(&btv->gpio_lock);
 -      init_waitqueue_head(&btv->gpioq);
        init_waitqueue_head(&btv->i2c_queue);
        INIT_LIST_HEAD(&btv->c.subs);
        INIT_LIST_HEAD(&btv->capture);
@@@ -4429,6 -4579,9 +4435,9 @@@ static void __devexit bttv_remove(struc
        if (bttv_verbose)
                printk("bttv%d: unloading\n",btv->c.nr);
  
+       if (bttv_tvcards[btv->c.type].has_dvb)
+               flush_request_modules(btv);
        /* shutdown everything (DMA+IRQs) */
        btand(~15, BT848_GPIO_DMA_CTL);
        btwrite(0, BT848_INT_MASK);
  
        /* tell gpio modules we are leaving ... */
        btv->shutdown=1;
 -      wake_up(&btv->gpioq);
        bttv_input_fini(btv);
        bttv_sub_del_devices(&btv->c);
  
  
  static int ir_debug;
  module_param(ir_debug, int, 0644);
 -static int repeat_delay = 500;
 -module_param(repeat_delay, int, 0644);
 -static int repeat_period = 33;
 -module_param(repeat_period, int, 0644);
  
  static int ir_rc5_remote_gap = 885;
  module_param(ir_rc5_remote_gap, int, 0644);
 -static int ir_rc5_key_timeout = 200;
 -module_param(ir_rc5_key_timeout, int, 0644);
  
  #undef dprintk
  #define dprintk(arg...) do {  \
@@@ -49,7 -55,7 +49,7 @@@
  
  static void ir_handle_key(struct bttv *btv)
  {
 -      struct card_ir *ir = btv->remote;
 +      struct bttv_ir *ir = btv->remote;
        u32 gpio,data;
  
        /* read gpio value */
                (gpio & ir->mask_keydown) ? " down" : "",
                (gpio & ir->mask_keyup)   ? " up"   : "");
  
 -      if ((ir->mask_keydown  &&  (0 != (gpio & ir->mask_keydown))) ||
 -          (ir->mask_keyup    &&  (0 == (gpio & ir->mask_keyup)))) {
 -              ir_input_keydown(ir->dev, &ir->ir, data);
 +      if ((ir->mask_keydown && (gpio & ir->mask_keydown)) ||
 +          (ir->mask_keyup   && !(gpio & ir->mask_keyup))) {
 +              rc_keydown_notimeout(ir->dev, data, 0);
        } else {
                /* HACK: Probably, ir->mask_keydown is missing
                   for this board */
                if (btv->c.type == BTTV_BOARD_WINFAST2000)
 -                      ir_input_keydown(ir->dev, &ir->ir, data);
 +                      rc_keydown_notimeout(ir->dev, data, 0);
  
 -              ir_input_nokey(ir->dev,&ir->ir);
 +              rc_keyup(ir->dev);
        }
 -
  }
  
  static void ir_enltv_handle_key(struct bttv *btv)
  {
 -      struct card_ir *ir = btv->remote;
 +      struct bttv_ir *ir = btv->remote;
        u32 gpio, data, keyup;
  
        /* read gpio value */
                        gpio, data,
                        (gpio & ir->mask_keyup) ? " up" : "up/down");
  
 -              ir_input_keydown(ir->dev, &ir->ir, data);
 +              rc_keydown_notimeout(ir->dev, data, 0);
                if (keyup)
 -                      ir_input_nokey(ir->dev, &ir->ir);
 +                      rc_keyup(ir->dev);
        } else {
                if ((ir->last_gpio & 1 << 31) == keyup)
                        return;
                        (gpio & ir->mask_keyup) ? " up" : "down");
  
                if (keyup)
 -                      ir_input_nokey(ir->dev, &ir->ir);
 +                      rc_keyup(ir->dev);
                else
 -                      ir_input_keydown(ir->dev, &ir->ir, data);
 +                      rc_keydown_notimeout(ir->dev, data, 0);
        }
  
        ir->last_gpio = data | keyup;
  }
  
 +static int bttv_rc5_irq(struct bttv *btv);
 +
  void bttv_input_irq(struct bttv *btv)
  {
 -      struct card_ir *ir = btv->remote;
 +      struct bttv_ir *ir = btv->remote;
  
 -      if (!ir->polling)
 +      if (ir->rc5_gpio)
 +              bttv_rc5_irq(btv);
 +      else if (!ir->polling)
                ir_handle_key(btv);
  }
  
  static void bttv_input_timer(unsigned long data)
  {
        struct bttv *btv = (struct bttv*)data;
 -      struct card_ir *ir = btv->remote;
 +      struct bttv_ir *ir = btv->remote;
  
        if (btv->c.type == BTTV_BOARD_ENLTV_FM_2)
                ir_enltv_handle_key(btv);
        mod_timer(&ir->timer, jiffies + msecs_to_jiffies(ir->polling));
  }
  
 -/* ---------------------------------------------------------------*/
 +/*
 + * FIXME: Nebula digi uses the legacy way to decode RC5, instead of relying
 + * on the rc-core way. As we need to be sure that both IRQ transitions are
 + * properly triggered, Better to touch it only with this hardware for
 + * testing.
 + */
 +
 +#define RC5_START(x)  (((x) >> 12) & 3)
 +#define RC5_TOGGLE(x) (((x) >> 11) & 1)
 +#define RC5_ADDR(x)   (((x) >> 6) & 31)
 +#define RC5_INSTR(x)  ((x) & 63)
 +
 +/* decode raw bit pattern to RC5 code */
 +static u32 bttv_rc5_decode(unsigned int code)
 +{
 +      unsigned int org_code = code;
 +      unsigned int pair;
 +      unsigned int rc5 = 0;
 +      int i;
 +
 +      for (i = 0; i < 14; ++i) {
 +              pair = code & 0x3;
 +              code >>= 2;
 +
 +              rc5 <<= 1;
 +              switch (pair) {
 +              case 0:
 +              case 2:
 +                      break;
 +              case 1:
 +                      rc5 |= 1;
 +              break;
 +              case 3:
 +                      dprintk(KERN_INFO DEVNAME ":rc5_decode(%x) bad code\n",
 +                              org_code);
 +                      return 0;
 +              }
 +      }
 +      dprintk(KERN_INFO DEVNAME ":"
 +              "code=%x, rc5=%x, start=%x, toggle=%x, address=%x, "
 +              "instr=%x\n", rc5, org_code, RC5_START(rc5),
 +              RC5_TOGGLE(rc5), RC5_ADDR(rc5), RC5_INSTR(rc5));
 +      return rc5;
 +}
 +
 +static void bttv_rc5_timer_end(unsigned long data)
 +{
 +      struct bttv_ir *ir = (struct bttv_ir *)data;
 +      struct timeval tv;
 +      unsigned long current_jiffies;
 +      u32 gap;
 +      u32 rc5 = 0;
 +
 +      /* get time */
 +      current_jiffies = jiffies;
 +      do_gettimeofday(&tv);
 +
 +      /* avoid overflow with gap >1s */
 +      if (tv.tv_sec - ir->base_time.tv_sec > 1) {
 +              gap = 200000;
 +      } else {
 +              gap = 1000000 * (tv.tv_sec - ir->base_time.tv_sec) +
 +                  tv.tv_usec - ir->base_time.tv_usec;
 +      }
 +
 +      /* signal we're ready to start a new code */
 +      ir->active = false;
 +
 +      /* Allow some timer jitter (RC5 is ~24ms anyway so this is ok) */
 +      if (gap < 28000) {
 +              dprintk(KERN_INFO DEVNAME ": spurious timer_end\n");
 +              return;
 +      }
 +
 +      if (ir->last_bit < 20) {
 +              /* ignore spurious codes (caused by light/other remotes) */
 +              dprintk(KERN_INFO DEVNAME ": short code: %x\n", ir->code);
 +      } else {
 +              ir->code = (ir->code << ir->shift_by) | 1;
 +              rc5 = bttv_rc5_decode(ir->code);
 +
 +              /* two start bits? */
 +              if (RC5_START(rc5) != ir->start) {
 +                      printk(KERN_INFO DEVNAME ":"
 +                             " rc5 start bits invalid: %u\n", RC5_START(rc5));
 +
 +                      /* right address? */
 +              } else if (RC5_ADDR(rc5) == ir->addr) {
 +                      u32 toggle = RC5_TOGGLE(rc5);
 +                      u32 instr = RC5_INSTR(rc5);
 +
 +                      /* Good code */
 +                      rc_keydown(ir->dev, instr, toggle);
 +                      dprintk(KERN_INFO DEVNAME ":"
 +                              " instruction %x, toggle %x\n",
 +                              instr, toggle);
 +              }
 +      }
 +}
  
  static int bttv_rc5_irq(struct bttv *btv)
  {
 -      struct card_ir *ir = btv->remote;
 +      struct bttv_ir *ir = btv->remote;
        struct timeval tv;
        u32 gpio;
        u32 gap;
        /* read gpio port */
        gpio = bttv_gpio_read(&btv->c);
  
 -      /* remote IRQ? */
 -      if (!(gpio & 0x20))
 -              return 0;
 -
        /* get time of bit */
        current_jiffies = jiffies;
        do_gettimeofday(&tv);
                    tv.tv_usec - ir->base_time.tv_usec;
        }
  
 +      dprintk(KERN_INFO DEVNAME ": RC5 IRQ: gap %d us for %s\n",
 +              gap, (gpio & 0x20) ? "mark" : "space");
 +
 +      /* remote IRQ? */
 +      if (!(gpio & 0x20))
 +              return 0;
 +
        /* active code => add bit */
        if (ir->active) {
                /* only if in the code (otherwise spurious IRQ or timer
                }
                /* starting new code */
        } else {
 -              ir->active = 1;
 +              ir->active = true;
                ir->code = 0;
                ir->base_time = tv;
                ir->last_bit = 0;
  
 -              mod_timer(&ir->timer_end,
 -                        current_jiffies + msecs_to_jiffies(30));
 +              mod_timer(&ir->timer, current_jiffies + msecs_to_jiffies(30));
        }
  
        /* toggle GPIO pin 4 to reset the irq */
  
  /* ---------------------------------------------------------------------- */
  
 -static void bttv_ir_start(struct bttv *btv, struct card_ir *ir)
 +static void bttv_ir_start(struct bttv *btv, struct bttv_ir *ir)
  {
        if (ir->polling) {
                setup_timer(&ir->timer, bttv_input_timer, (unsigned long)btv);
                add_timer(&ir->timer);
        } else if (ir->rc5_gpio) {
                /* set timer_end for code completion */
 -              init_timer(&ir->timer_end);
 -              ir->timer_end.function = ir_rc5_timer_end;
 -              ir->timer_end.data = (unsigned long)ir;
 -
 -              init_timer(&ir->timer_keyup);
 -              ir->timer_keyup.function = ir_rc5_timer_keyup;
 -              ir->timer_keyup.data = (unsigned long)ir;
 +              setup_timer(&ir->timer, bttv_rc5_timer_end, (unsigned long)ir);
                ir->shift_by = 1;
                ir->start = 3;
                ir->addr = 0x0;
 -              ir->rc5_key_timeout = ir_rc5_key_timeout;
                ir->rc5_remote_gap = ir_rc5_remote_gap;
        }
  }
  
  static void bttv_ir_stop(struct bttv *btv)
  {
-       if (btv->remote->polling) {
+       if (btv->remote->polling)
                del_timer_sync(&btv->remote->timer);
-               flush_scheduled_work();
-       }
  
        if (btv->remote->rc5_gpio) {
                u32 gpio;
  
 -              del_timer_sync(&btv->remote->timer_end);
 +              del_timer_sync(&btv->remote->timer);
-               flush_scheduled_work();
  
                gpio = bttv_gpio_read(&btv->c);
                bttv_gpio_write(&btv->c, gpio & ~(1 << 4));
@@@ -354,18 -261,6 +351,18 @@@ static int get_key_pv951(struct IR_i2c 
                return 0;
        dprintk(KERN_INFO DEVNAME ": key %02x\n", b);
  
 +      /*
 +       * NOTE:
 +       * lirc_i2c maps the pv951 code as:
 +       *      addr = 0x61D6
 +       *      cmd = bit_reverse (b)
 +       * So, it seems that this device uses NEC extended
 +       * I decided to not fix the table, due to two reasons:
 +       *      1) Without the actual device, this is only a guess;
 +       *      2) As the addr is not reported via I2C, nor can be changed,
 +       *         the device is bound to the vendor-provided RC.
 +       */
 +
        *ir_key = b;
        *ir_raw = b;
        return 1;
@@@ -392,15 -287,16 +389,15 @@@ void __devinit init_bttv_i2c_ir(struct 
                btv->init_data.name = "PV951";
                btv->init_data.get_key = get_key_pv951;
                btv->init_data.ir_codes = RC_MAP_PV951;
 -              btv->init_data.type = IR_TYPE_OTHER;
                info.addr = 0x4b;
                break;
        default:
                /*
                 * The external IR receiver is at i2c address 0x34 (0x35 for
 -                 * reads).  Future Hauppauge cards will have an internal
 -                 * receiver at 0x30 (0x31 for reads).  In theory, both can be
 -                 * fitted, and Hauppauge suggest an external overrides an
 -                 * internal.
 +               * reads).  Future Hauppauge cards will have an internal
 +               * receiver at 0x30 (0x31 for reads).  In theory, both can be
 +               * fitted, and Hauppauge suggest an external overrides an
 +               * internal.
                 * That's why we probe 0x1a (~0x34) first. CB
                 */
  
@@@ -425,17 -321,18 +422,17 @@@ int __devexit fini_bttv_i2c(struct btt
  
  int bttv_input_init(struct bttv *btv)
  {
 -      struct card_ir *ir;
 +      struct bttv_ir *ir;
        char *ir_codes = NULL;
 -      struct input_dev *input_dev;
 -      u64 ir_type = IR_TYPE_OTHER;
 +      struct rc_dev *rc;
        int err = -ENOMEM;
  
        if (!btv->has_remote)
                return -ENODEV;
  
        ir = kzalloc(sizeof(*ir),GFP_KERNEL);
 -      input_dev = input_allocate_device();
 -      if (!ir || !input_dev)
 +      rc = rc_allocate_device();
 +      if (!ir || !rc)
                goto err_out_free;
  
        /* detect & configure */
                break;
        case BTTV_BOARD_NEBULA_DIGITV:
                ir_codes = RC_MAP_NEBULA;
 -              btv->custom_irq = bttv_rc5_irq;
 -              ir->rc5_gpio = 1;
 +              ir->rc5_gpio = true;
                break;
        case BTTV_BOARD_MACHTV_MAGICTV:
                ir_codes         = RC_MAP_APAC_VIEWCOMP;
        }
  
        /* init input device */
 -      ir->dev = input_dev;
 +      ir->dev = rc;
  
        snprintf(ir->name, sizeof(ir->name), "bttv IR (card=%d)",
                 btv->c.type);
        snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0",
                 pci_name(btv->c.pci));
  
 -      err = ir_input_init(input_dev, &ir->ir, ir_type);
 -      if (err < 0)
 -              goto err_out_free;
 -
 -      input_dev->name = ir->name;
 -      input_dev->phys = ir->phys;
 -      input_dev->id.bustype = BUS_PCI;
 -      input_dev->id.version = 1;
 +      rc->input_name = ir->name;
 +      rc->input_phys = ir->phys;
 +      rc->input_id.bustype = BUS_PCI;
 +      rc->input_id.version = 1;
        if (btv->c.pci->subsystem_vendor) {
 -              input_dev->id.vendor  = btv->c.pci->subsystem_vendor;
 -              input_dev->id.product = btv->c.pci->subsystem_device;
 +              rc->input_id.vendor  = btv->c.pci->subsystem_vendor;
 +              rc->input_id.product = btv->c.pci->subsystem_device;
        } else {
 -              input_dev->id.vendor  = btv->c.pci->vendor;
 -              input_dev->id.product = btv->c.pci->device;
 +              rc->input_id.vendor  = btv->c.pci->vendor;
 +              rc->input_id.product = btv->c.pci->device;
        }
 -      input_dev->dev.parent = &btv->c.pci->dev;
 +      rc->dev.parent = &btv->c.pci->dev;
 +      rc->map_name = ir_codes;
 +      rc->driver_name = MODULE_NAME;
  
        btv->remote = ir;
        bttv_ir_start(btv, ir);
  
        /* all done */
 -      err = ir_input_register(btv->remote->dev, ir_codes, NULL, MODULE_NAME);
 +      err = rc_register_device(rc);
        if (err)
                goto err_out_stop;
  
 -      /* the remote isn't as bouncy as a keyboard */
 -      ir->dev->rep[REP_DELAY] = repeat_delay;
 -      ir->dev->rep[REP_PERIOD] = repeat_period;
 -
        return 0;
  
   err_out_stop:
        bttv_ir_stop(btv);
        btv->remote = NULL;
   err_out_free:
 +      rc_free_device(rc);
        kfree(ir);
        return err;
  }
@@@ -587,7 -490,7 +584,7 @@@ void bttv_input_fini(struct bttv *btv
                return;
  
        bttv_ir_stop(btv);
 -      ir_input_unregister(btv->remote->dev);
 +      rc_unregister_device(btv->remote->dev);
        kfree(btv->remote);
        btv->remote = NULL;
  }
@@@ -156,7 -156,6 +156,7 @@@ MODULE_PARM_DESC(cardtype
                 "\t\t\t 6 = Toshiba Qosmio DVB-T/Analog\n"
                 "\t\t\t 7 = Leadtek WinFast PVR2100\n"
                 "\t\t\t 8 = Leadtek WinFast DVR3100 H\n"
 +               "\t\t\t 9 = GoTView PCI DVD3 Hybrid\n"
                 "\t\t\t 0 = Autodetect (default)\n"
                 "\t\t\t-1 = Ignore this card\n\t\t");
  MODULE_PARM_DESC(pal, "Set PAL standard: B, G, H, D, K, I, M, N, Nc, 60");
@@@ -267,8 -266,14 +267,14 @@@ static void request_modules(struct cx1
        INIT_WORK(&dev->request_module_wk, request_module_async);
        schedule_work(&dev->request_module_wk);
  }
+ static void flush_request_modules(struct cx18 *dev)
+ {
+       flush_work_sync(&dev->request_module_wk);
+ }
  #else
  #define request_modules(dev)
+ #define flush_request_modules(dev)
  #endif /* CONFIG_MODULES */
  
  /* Generic utility functions */
@@@ -334,7 -339,6 +340,7 @@@ void cx18_read_eeprom(struct cx18 *cx, 
                tveeprom_hauppauge_analog(&c, tv, eedata);
                break;
        case CX18_CARD_YUAN_MPC718:
 +      case CX18_CARD_GOTVIEW_PCI_DVD3:
                tv->model = 0x718;
                cx18_eeprom_dump(cx, eedata, sizeof(eedata));
                CX18_INFO("eeprom PCI ID: %02x%02x:%02x%02x\n",
@@@ -925,13 -929,8 +931,13 @@@ static int __devinit cx18_probe(struct 
        cx->enc_mem = ioremap_nocache(cx->base_addr + CX18_MEM_OFFSET,
                                       CX18_MEM_SIZE);
        if (!cx->enc_mem) {
 -              CX18_ERR("ioremap failed, perhaps increasing __VMALLOC_RESERVE in page.h\n");
 -              CX18_ERR("or disabling CONFIG_HIGHMEM4G into the kernel would help\n");
 +              CX18_ERR("ioremap failed. Can't get a window into CX23418 "
 +                       "memory and register space\n");
 +              CX18_ERR("Each capture card with a CX23418 needs 64 MB of "
 +                       "vmalloc address space for the window\n");
 +              CX18_ERR("Check the output of 'grep Vmalloc /proc/meminfo'\n");
 +              CX18_ERR("Use the vmalloc= kernel command line option to set "
 +                       "VmallocTotal to a larger value\n");
                retval = -ENOMEM;
                goto free_mem;
        }
@@@ -1233,6 -1232,8 +1239,8 @@@ static void cx18_remove(struct pci_dev 
  
        CX18_DEBUG_INFO("Removing Card\n");
  
+       flush_request_modules(cx);
        /* Stop all captures */
        CX18_DEBUG_INFO("Stopping all streams\n");
        if (atomic_read(&cx->tot_capturing) > 0)
@@@ -34,7 -34,6 +34,7 @@@
  #include <media/cx25840.h>
  #include "dvb-usb-ids.h"
  #include "xc5000.h"
 +#include "tda18271.h"
  
  #include "cx231xx.h"
  
@@@ -396,45 -395,6 +396,45 @@@ struct cx231xx_board cx231xx_boards[] 
                        .gpio = 0,
                } },
        },
 +      [CX231XX_BOARD_PV_PLAYTV_USB_HYBRID] = {
 +              .name = "Pixelview PlayTV USB Hybrid",
 +              .tuner_type = TUNER_NXP_TDA18271,
 +              .tuner_addr = 0x60,
 +              .decoder = CX231XX_AVDECODER,
 +              .output_mode = OUT_MODE_VIP11,
 +              .demod_xfer_mode = 0,
 +              .ctl_pin_status_mask = 0xFFFFFFC4,
 +              .agc_analog_digital_select_gpio = 0x00, /* According with PV cxPolaris.inf file */
 +              .tuner_sif_gpio = -1,
 +              .tuner_scl_gpio = -1,
 +              .tuner_sda_gpio = -1,
 +              .gpio_pin_status_mask = 0x4001000,
 +              .tuner_i2c_master = 2,
 +              .demod_i2c_master = 1,
 +              .ir_i2c_master = 2,
 +              .rc_map_name = RC_MAP_PIXELVIEW_002T,
 +              .has_dvb = 1,
 +              .demod_addr = 0x10,
 +              .norm = V4L2_STD_PAL_M,
 +              .input = {{
 +                      .type = CX231XX_VMUX_TELEVISION,
 +                      .vmux = CX231XX_VIN_3_1,
 +                      .amux = CX231XX_AMUX_VIDEO,
 +                      .gpio = 0,
 +              }, {
 +                      .type = CX231XX_VMUX_COMPOSITE1,
 +                      .vmux = CX231XX_VIN_2_1,
 +                      .amux = CX231XX_AMUX_LINE_IN,
 +                      .gpio = 0,
 +              }, {
 +                      .type = CX231XX_VMUX_SVIDEO,
 +                      .vmux = CX231XX_VIN_1_1 |
 +                              (CX231XX_VIN_1_2 << 8) |
 +                              CX25840_SVIDEO_ON,
 +                      .amux = CX231XX_AMUX_LINE_IN,
 +                      .gpio = 0,
 +              } },
 +      },
  };
  const unsigned int cx231xx_bcount = ARRAY_SIZE(cx231xx_boards);
  
  struct usb_device_id cx231xx_id_table[] = {
        {USB_DEVICE(0x0572, 0x5A3C),
         .driver_info = CX231XX_BOARD_UNKNOWN},
 -      {USB_DEVICE_VER(USB_VID_PIXELVIEW, USB_PID_PIXELVIEW_SBTVD, 0x4000,0x4fff),
 -       .driver_info = CX231XX_BOARD_UNKNOWN},
        {USB_DEVICE(0x0572, 0x58A2),
         .driver_info = CX231XX_BOARD_CNXT_CARRAERA},
        {USB_DEVICE(0x0572, 0x58A1),
         .driver_info = CX231XX_BOARD_HAUPPAUGE_EXETER},
        {USB_DEVICE(0x2040, 0xc200),
         .driver_info = CX231XX_BOARD_HAUPPAUGE_USBLIVE2},
 +      {USB_DEVICE_VER(USB_VID_PIXELVIEW, USB_PID_PIXELVIEW_SBTVD, 0x4000, 0x4001),
 +       .driver_info = CX231XX_BOARD_PV_PLAYTV_USB_HYBRID},
        {},
  };
  
@@@ -493,16 -453,6 +493,16 @@@ int cx231xx_tuner_callback(void *ptr, i
                                               1);
                        msleep(10);
                }
 +      } else if (dev->tuner_type == TUNER_NXP_TDA18271) {
 +              switch (command) {
 +              case TDA18271_CALLBACK_CMD_AGC_ENABLE:
 +                      if (dev->model == CX231XX_BOARD_PV_PLAYTV_USB_HYBRID)
 +                              rc = cx231xx_set_agc_analog_digital_mux_select(dev, arg);
 +                      break;
 +              default:
 +                      rc = -EINVAL;
 +                      break;
 +              }
        }
        return rc;
  }
@@@ -610,7 -560,7 +610,7 @@@ void cx231xx_card_setup(struct cx231xx 
        if (dev->board.decoder == CX231XX_AVDECODER) {
                dev->sd_cx25840 = v4l2_i2c_new_subdev(&dev->v4l2_dev,
                                        &dev->i2c_bus[0].i2c_adap,
 -                                      NULL, "cx25840", 0x88 >> 1, NULL);
 +                                      "cx25840", 0x88 >> 1, NULL);
                if (dev->sd_cx25840 == NULL)
                        cx231xx_info("cx25840 subdev registration failure\n");
                cx25840_call(dev, core, load_fw);
        if (dev->board.tuner_type != TUNER_ABSENT) {
                dev->sd_tuner = v4l2_i2c_new_subdev(&dev->v4l2_dev,
                                                    &dev->i2c_bus[dev->board.tuner_i2c_master].i2c_adap,
 -                                                  NULL, "tuner",
 +                                                  "tuner",
                                                    dev->tuner_addr, NULL);
                if (dev->sd_tuner == NULL)
                        cx231xx_info("tuner subdev registration failure\n");
@@@ -665,11 -615,8 +665,11 @@@ void cx231xx_release_resources(struct c
  
        cx231xx_remove_from_devlist(dev);
  
 +      /* Release I2C buses */
        cx231xx_dev_uninit(dev);
  
 +      cx231xx_ir_exit(dev);
 +
        usb_put_dev(dev->udev);
  
        /* Mark device as unused */
@@@ -784,14 -731,16 +784,14 @@@ static int cx231xx_init_dev(struct cx23
        retval = cx231xx_register_analog_devices(dev);
        if (retval < 0) {
                cx231xx_release_resources(dev);
 -              goto fail_reg_devices;
 +              return retval;
        }
  
 +      cx231xx_ir_init(dev);
 +
        cx231xx_init_extension(dev);
  
        return 0;
 -
 -fail_reg_devices:
 -      mutex_unlock(&dev->lock);
 -      return retval;
  }
  
  #if defined(CONFIG_MODULES) && defined(MODULE)
@@@ -813,8 -762,14 +813,14 @@@ static void request_modules(struct cx23
        INIT_WORK(&dev->request_module_wk, request_module_async);
        schedule_work(&dev->request_module_wk);
  }
+ static void flush_request_modules(struct cx231xx *dev)
+ {
+       flush_work_sync(&dev->request_module_wk);
+ }
  #else
  #define request_modules(dev)
+ #define flush_request_modules(dev)
  #endif /* CONFIG_MODULES */
  
  /*
@@@ -1147,6 -1102,8 +1153,8 @@@ static void cx231xx_usb_disconnect(stru
        if (!dev->udev)
                return;
  
+       flush_request_modules(dev);
        /* delete v4l2 device */
        v4l2_device_unregister(&dev->v4l2_dev);
  
@@@ -35,8 -35,9 +35,8 @@@
   *  02110-1301, USA.
   */
  
 -#include <linux/input.h>
  #include <linux/slab.h>
 -#include <media/ir-core.h>
 +#include <media/rc-core.h>
  #include <media/v4l2-subdev.h>
  
  #include "cx23885.h"
@@@ -61,16 -62,16 +61,16 @@@ static void cx23885_input_process_measu
                count = num / sizeof(struct ir_raw_event);
  
                for (i = 0; i < count; i++) {
 -                      ir_raw_event_store(kernel_ir->inp_dev,
 +                      ir_raw_event_store(kernel_ir->rc,
                                           &ir_core_event[i]);
                        handle = true;
                }
        } while (num != 0);
  
        if (overrun)
 -              ir_raw_event_reset(kernel_ir->inp_dev);
 +              ir_raw_event_reset(kernel_ir->rc);
        else if (handle)
 -              ir_raw_event_handle(kernel_ir->inp_dev);
 +              ir_raw_event_handle(kernel_ir->rc);
  }
  
  void cx23885_input_rx_work_handler(struct cx23885_dev *dev, u32 events)
@@@ -196,9 -197,9 +196,9 @@@ static int cx23885_input_ir_start(struc
        return 0;
  }
  
 -static int cx23885_input_ir_open(void *priv)
 +static int cx23885_input_ir_open(struct rc_dev *rc)
  {
 -      struct cx23885_kernel_ir *kernel_ir = priv;
 +      struct cx23885_kernel_ir *kernel_ir = rc->priv;
  
        if (kernel_ir->cx == NULL)
                return -ENODEV;
@@@ -229,13 -230,11 +229,11 @@@ static void cx23885_input_ir_stop(struc
                v4l2_subdev_call(dev->sd_ir, ir, rx_s_parameters, &params);
                v4l2_subdev_call(dev->sd_ir, ir, rx_g_parameters, &params);
        }
-       flush_scheduled_work();
  }
  
 -static void cx23885_input_ir_close(void *priv)
 +static void cx23885_input_ir_close(struct rc_dev *rc)
  {
 -      struct cx23885_kernel_ir *kernel_ir = priv;
 +      struct cx23885_kernel_ir *kernel_ir = rc->priv;
  
        if (kernel_ir->cx != NULL)
                cx23885_input_ir_stop(kernel_ir->cx);
  int cx23885_input_init(struct cx23885_dev *dev)
  {
        struct cx23885_kernel_ir *kernel_ir;
 -      struct input_dev *inp_dev;
 -      struct ir_dev_props *props;
 -
 +      struct rc_dev *rc;
        char *rc_map;
        enum rc_driver_type driver_type;
        unsigned long allowed_protos;
        case CX23885_BOARD_HAUPPAUGE_HVR1250:
                /* Integrated CX2388[58] IR controller */
                driver_type = RC_DRIVER_IR_RAW;
 -              allowed_protos = IR_TYPE_ALL;
 +              allowed_protos = RC_TYPE_ALL;
                /* The grey Hauppauge RC-5 remote */
                rc_map = RC_MAP_RC5_HAUPPAUGE_NEW;
                break;
        case CX23885_BOARD_TEVII_S470:
                /* Integrated CX23885 IR controller */
                driver_type = RC_DRIVER_IR_RAW;
 -              allowed_protos = IR_TYPE_ALL;
 +              allowed_protos = RC_TYPE_ALL;
                /* A guess at the remote */
                rc_map = RC_MAP_TEVII_NEC;
                break;
                                    pci_name(dev->pci));
  
        /* input device */
 -      inp_dev = input_allocate_device();
 -      if (inp_dev == NULL) {
 +      rc = rc_allocate_device();
 +      if (!rc) {
                ret = -ENOMEM;
                goto err_out_free;
        }
  
 -      kernel_ir->inp_dev = inp_dev;
 -      inp_dev->name = kernel_ir->name;
 -      inp_dev->phys = kernel_ir->phys;
 -      inp_dev->id.bustype = BUS_PCI;
 -      inp_dev->id.version = 1;
 +      kernel_ir->rc = rc;
 +      rc->input_name = kernel_ir->name;
 +      rc->input_phys = kernel_ir->phys;
 +      rc->input_id.bustype = BUS_PCI;
 +      rc->input_id.version = 1;
        if (dev->pci->subsystem_vendor) {
 -              inp_dev->id.vendor  = dev->pci->subsystem_vendor;
 -              inp_dev->id.product = dev->pci->subsystem_device;
 +              rc->input_id.vendor  = dev->pci->subsystem_vendor;
 +              rc->input_id.product = dev->pci->subsystem_device;
        } else {
 -              inp_dev->id.vendor  = dev->pci->vendor;
 -              inp_dev->id.product = dev->pci->device;
 +              rc->input_id.vendor  = dev->pci->vendor;
 +              rc->input_id.product = dev->pci->device;
        }
 -      inp_dev->dev.parent = &dev->pci->dev;
 -
 -      /* kernel ir device properties */
 -      props = &kernel_ir->props;
 -      props->driver_type = driver_type;
 -      props->allowed_protos = allowed_protos;
 -      props->priv = kernel_ir;
 -      props->open = cx23885_input_ir_open;
 -      props->close = cx23885_input_ir_close;
 +      rc->dev.parent = &dev->pci->dev;
 +      rc->driver_type = driver_type;
 +      rc->allowed_protos = allowed_protos;
 +      rc->priv = kernel_ir;
 +      rc->open = cx23885_input_ir_open;
 +      rc->close = cx23885_input_ir_close;
 +      rc->map_name = rc_map;
 +      rc->driver_name = MODULE_NAME;
  
        /* Go */
        dev->kernel_ir = kernel_ir;
 -      ret = ir_input_register(inp_dev, rc_map, props, MODULE_NAME);
 +      ret = rc_register_device(rc);
        if (ret)
                goto err_out_stop;
  
  err_out_stop:
        cx23885_input_ir_stop(dev);
        dev->kernel_ir = NULL;
 -      /* TODO: double check clean-up of kernel_ir->inp_dev */
 +      rc_free_device(rc);
  err_out_free:
        kfree(kernel_ir->phys);
        kfree(kernel_ir->name);
@@@ -344,7 -346,7 +342,7 @@@ void cx23885_input_fini(struct cx23885_
  
        if (dev->kernel_ir == NULL)
                return;
 -      ir_input_unregister(dev->kernel_ir->inp_dev);
 +      rc_unregister_device(dev->kernel_ir->rc);
        kfree(dev->kernel_ir->phys);
        kfree(dev->kernel_ir->name);
        kfree(dev->kernel_ir);
@@@ -268,20 -268,6 +268,20 @@@ static struct em28xx_reg_seq dikom_dk30
  };
  
  
 +/* Reset for the most [digital] boards */
 +static struct em28xx_reg_seq leadership_digital[] = {
 +      {EM2874_R80_GPIO,       0x70,   0xff,   10},
 +      {       -1,             -1,     -1,     -1},
 +};
 +
 +static struct em28xx_reg_seq leadership_reset[] = {
 +      {EM2874_R80_GPIO,       0xf0,   0xff,   10},
 +      {EM2874_R80_GPIO,       0xb0,   0xff,   10},
 +      {EM2874_R80_GPIO,       0xf0,   0xff,   10},
 +      {       -1,             -1,     -1,     -1},
 +};
 +
 +
  /*
   *  Board definitions
   */
@@@ -1238,19 -1224,6 +1238,19 @@@ struct em28xx_board em28xx_boards[] = 
                        .vmux     = SAA7115_COMPOSITE0,
                } },
        },
 +
 +      [EM2874_LEADERSHIP_ISDBT] = {
 +              .i2c_speed      = EM2874_I2C_SECONDARY_BUS_SELECT |
 +                                EM28XX_I2C_CLK_WAIT_ENABLE |
 +                                EM28XX_I2C_FREQ_100_KHZ,
 +              .xclk           = EM28XX_XCLK_FREQUENCY_10MHZ,
 +              .name           = "EM2874 Leadership ISDBT",
 +              .tuner_type     = TUNER_ABSENT,
 +              .tuner_gpio     = leadership_reset,
 +              .dvb_gpio       = leadership_digital,
 +              .has_dvb        = 1,
 +      },
 +
        [EM2880_BOARD_MSI_DIGIVOX_AD] = {
                .name         = "MSI DigiVox A/D",
                .valid        = EM28XX_BOARD_NOT_VALIDATED,
                } },
        },
        [EM2882_BOARD_TERRATEC_HYBRID_XS] = {
 -              .name         = "Terratec Hybrid XS (em2882)",
 +              .name         = "Terratec Cinnergy Hybrid T USB XS (em2882)",
                .tuner_type   = TUNER_XC2028,
                .tuner_gpio   = default_tuner_gpio,
                .mts_firmware = 1,
                .input           = { {
                        .type     = EM28XX_VMUX_COMPOSITE1,
                        .vmux     = SAA7115_COMPOSITE0,
 -                      .amux     = EM28XX_AMUX_VIDEO2,
 +                      .amux     = EM28XX_AMUX_LINE_IN,
                }, {
                        .type     = EM28XX_VMUX_SVIDEO,
                        .vmux     = SAA7115_SVIDEO3,
 -                      .amux     = EM28XX_AMUX_VIDEO2,
 +                      .amux     = EM28XX_AMUX_LINE_IN,
                } },
        },
        [EM2860_BOARD_TERRATEC_AV350] = {
@@@ -1781,8 -1754,6 +1781,8 @@@ struct usb_device_id em28xx_id_table[] 
                        .driver_info = EM2820_BOARD_UNKNOWN },
        { USB_DEVICE(0xeb1a, 0x2868),
                        .driver_info = EM2820_BOARD_UNKNOWN },
 +      { USB_DEVICE(0xeb1a, 0x2875),
 +                      .driver_info = EM2820_BOARD_UNKNOWN },
        { USB_DEVICE(0xeb1a, 0xe300),
                        .driver_info = EM2861_BOARD_KWORLD_PVRTV_300U },
        { USB_DEVICE(0xeb1a, 0xe303),
        { USB_DEVICE(0x0ccd, 0x005e),
                        .driver_info = EM2882_BOARD_TERRATEC_HYBRID_XS },
        { USB_DEVICE(0x0ccd, 0x0042),
 -                      .driver_info = EM2880_BOARD_TERRATEC_HYBRID_XS },
 +                      .driver_info = EM2882_BOARD_TERRATEC_HYBRID_XS },
        { USB_DEVICE(0x0ccd, 0x0043),
                        .driver_info = EM2870_BOARD_TERRATEC_XS },
        { USB_DEVICE(0x0ccd, 0x0047),
@@@ -1902,7 -1873,6 +1902,7 @@@ static struct em28xx_hash_table em28xx_
        {0x77800080, EM2860_BOARD_TVP5150_REFERENCE_DESIGN, TUNER_ABSENT},
        {0xc51200e3, EM2820_BOARD_GADMEI_TVR200, TUNER_LG_PAL_NEW_TAPC},
        {0x4ba50080, EM2861_BOARD_GADMEI_UTV330PLUS, TUNER_TNF_5335MF},
 +      {0x6b800080, EM2874_LEADERSHIP_ISDBT, TUNER_ABSENT},
  };
  
  /* I2C possible address to saa7115, tvp5150, msp3400, tvaudio */
@@@ -2438,7 -2408,7 +2438,7 @@@ void em28xx_register_i2c_ir(struct em28
                dev->init_data.get_key = em28xx_get_key_em_haup;
                dev->init_data.name = "i2c IR (EM2840 Hauppauge)";
        case EM2820_BOARD_LEADTEK_WINFAST_USBII_DELUXE:
 -              dev->init_data.ir_codes = RC_MAP_WINFAST_USBII_DELUXE;;
 +              dev->init_data.ir_codes = RC_MAP_WINFAST_USBII_DELUXE;
                dev->init_data.get_key = em28xx_get_key_winfast_usbii_deluxe;
                dev->init_data.name = "i2c IR (EM2820 Winfast TV USBII Deluxe)";
                break;
@@@ -2460,36 -2430,8 +2460,36 @@@ void em28xx_card_setup(struct em28xx *d
                        dev->board.is_webcam = 0;
                else
                        dev->progressive = 1;
 -      } else
 -              em28xx_set_model(dev);
 +      }
 +
 +      if (!dev->board.is_webcam) {
 +              switch (dev->model) {
 +              case EM2820_BOARD_UNKNOWN:
 +              case EM2800_BOARD_UNKNOWN:
 +              /*
 +               * The K-WORLD DVB-T 310U is detected as an MSI Digivox AD.
 +               *
 +               * This occurs because they share identical USB vendor and
 +               * product IDs.
 +               *
 +               * What we do here is look up the EEPROM hash of the K-WORLD
 +               * and if it is found then we decide that we do not have
 +               * a DIGIVOX and reset the device to the K-WORLD instead.
 +               *
 +               * This solution is only valid if they do not share eeprom
 +               * hash identities which has not been determined as yet.
 +               */
 +              if (em28xx_hint_board(dev) < 0)
 +                      em28xx_errdev("Board not discovered\n");
 +              else {
 +                      em28xx_set_model(dev);
 +                      em28xx_pre_card_setup(dev);
 +              }
 +              break;
 +              default:
 +                      em28xx_set_model(dev);
 +              }
 +      }
  
        em28xx_info("Identified as %s (card=%d)\n",
                    dev->board.name, dev->model);
        /* request some modules */
        if (dev->board.has_msp34xx)
                v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
 -                      NULL, "msp3400", 0, msp3400_addrs);
 +                      "msp3400", 0, msp3400_addrs);
  
        if (dev->board.decoder == EM28XX_SAA711X)
                v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
 -                      NULL, "saa7115_auto", 0, saa711x_addrs);
 +                      "saa7115_auto", 0, saa711x_addrs);
  
        if (dev->board.decoder == EM28XX_TVP5150)
                v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
 -                      NULL, "tvp5150", 0, tvp5150_addrs);
 +                      "tvp5150", 0, tvp5150_addrs);
  
        if (dev->em28xx_sensor == EM28XX_MT9V011) {
                struct v4l2_subdev *sd;
  
                sd = v4l2_i2c_new_subdev(&dev->v4l2_dev,
 -                       &dev->i2c_adap, NULL, "mt9v011", 0, mt9v011_addrs);
 +                       &dev->i2c_adap, "mt9v011", 0, mt9v011_addrs);
                v4l2_subdev_call(sd, core, s_config, 0, &dev->sensor_xtal);
        }
  
  
        if (dev->board.adecoder == EM28XX_TVAUDIO)
                v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
 -                      NULL, "tvaudio", dev->board.tvaudio_addr, NULL);
 +                      "tvaudio", dev->board.tvaudio_addr, NULL);
  
        if (dev->board.tuner_type != TUNER_ABSENT) {
                int has_demod = (dev->tda9887_conf & TDA9887_PRESENT);
  
                if (dev->board.radio.type)
                        v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
 -                              NULL, "tuner", dev->board.radio_addr, NULL);
 +                              "tuner", dev->board.radio_addr, NULL);
  
                if (has_demod)
                        v4l2_i2c_new_subdev(&dev->v4l2_dev,
 -                              &dev->i2c_adap, NULL, "tuner",
 +                              &dev->i2c_adap, "tuner",
                                0, v4l2_i2c_tuner_addrs(ADDRS_DEMOD));
                if (dev->tuner_addr == 0) {
                        enum v4l2_i2c_tuner_type type =
                        struct v4l2_subdev *sd;
  
                        sd = v4l2_i2c_new_subdev(&dev->v4l2_dev,
 -                              &dev->i2c_adap, NULL, "tuner",
 +                              &dev->i2c_adap, "tuner",
                                0, v4l2_i2c_tuner_addrs(type));
  
                        if (sd)
                                dev->tuner_addr = v4l2_i2c_subdev_addr(sd);
                } else {
                        v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
 -                              NULL, "tuner", dev->tuner_addr, NULL);
 +                              "tuner", dev->tuner_addr, NULL);
                }
        }
  
@@@ -2690,8 -2632,14 +2690,14 @@@ static void request_modules(struct em28
        INIT_WORK(&dev->request_module_wk, request_module_async);
        schedule_work(&dev->request_module_wk);
  }
+ static void flush_request_modules(struct em28xx *dev)
+ {
+       flush_work_sync(&dev->request_module_wk);
+ }
  #else
  #define request_modules(dev)
+ #define flush_request_modules(dev)
  #endif /* CONFIG_MODULES */
  
  /*
@@@ -2807,8 -2755,8 +2813,8 @@@ static int em28xx_init_dev(struct em28x
        em28xx_pre_card_setup(dev);
  
        if (!dev->board.is_em2800) {
 -              /* Sets I2C speed to 100 KHz */
 -              retval = em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x40);
 +              /* Resets I2C speed */
 +              em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, dev->board.i2c_speed);
                if (retval < 0) {
                        em28xx_errdev("%s: em28xx_write_regs_req failed!"
                                      " retval [%d]\n",
@@@ -3118,6 -3066,8 +3124,8 @@@ static void em28xx_usb_disconnect(struc
  
        em28xx_info("disconnecting %s\n", dev->vdev->name);
  
+       flush_request_modules(dev);
        /* wait until all current v4l2 io is finished then deallocate
           resources */
        mutex_lock(&dev->lock);
@@@ -25,6 -25,7 +25,6 @@@
  #include <linux/init.h>
  #include <linux/delay.h>
  #include <linux/interrupt.h>
 -#include <linux/input.h>
  #include <linux/usb.h>
  #include <linux/slab.h>
  
@@@ -63,7 -64,7 +63,7 @@@ struct em28xx_ir_poll_result 
  
  struct em28xx_IR {
        struct em28xx *dev;
 -      struct input_dev *input;
 +      struct rc_dev *rc;
        char name[32];
        char phys[32];
  
        unsigned int last_readcount;
  
        int  (*get_key)(struct em28xx_IR *, struct em28xx_ir_poll_result *);
 -
 -      /* IR device properties */
 -
 -      struct ir_dev_props props;
  };
  
  /**********************************************************
@@@ -297,12 -302,12 +297,12 @@@ static void em28xx_ir_handle_key(struc
                        poll_result.toggle_bit, poll_result.read_count,
                        poll_result.rc_address, poll_result.rc_data[0]);
                if (ir->full_code)
 -                      ir_keydown(ir->input,
 +                      rc_keydown(ir->rc,
                                   poll_result.rc_address << 8 |
                                   poll_result.rc_data[0],
                                   poll_result.toggle_bit);
                else
 -                      ir_keydown(ir->input,
 +                      rc_keydown(ir->rc,
                                   poll_result.rc_data[0],
                                   poll_result.toggle_bit);
  
@@@ -326,9 -331,9 +326,9 @@@ static void em28xx_ir_work(struct work_
        schedule_delayed_work(&ir->work, msecs_to_jiffies(ir->polling));
  }
  
 -static int em28xx_ir_start(void *priv)
 +static int em28xx_ir_start(struct rc_dev *rc)
  {
 -      struct em28xx_IR *ir = priv;
 +      struct em28xx_IR *ir = rc->priv;
  
        INIT_DELAYED_WORK(&ir->work, em28xx_ir_work);
        schedule_delayed_work(&ir->work, 0);
        return 0;
  }
  
 -static void em28xx_ir_stop(void *priv)
 +static void em28xx_ir_stop(struct rc_dev *rc)
  {
 -      struct em28xx_IR *ir = priv;
 +      struct em28xx_IR *ir = rc->priv;
  
        cancel_delayed_work_sync(&ir->work);
  }
  
 -int em28xx_ir_change_protocol(void *priv, u64 ir_type)
 +int em28xx_ir_change_protocol(struct rc_dev *rc_dev, u64 rc_type)
  {
        int rc = 0;
 -      struct em28xx_IR *ir = priv;
 +      struct em28xx_IR *ir = rc_dev->priv;
        struct em28xx *dev = ir->dev;
        u8 ir_config = EM2874_IR_RC5;
  
        /* Adjust xclk based o IR table for RC5/NEC tables */
  
 -      if (ir_type == IR_TYPE_RC5) {
 +      if (rc_type == RC_TYPE_RC5) {
                dev->board.xclk |= EM28XX_XCLK_IR_RC5_MODE;
                ir->full_code = 1;
 -      } else if (ir_type == IR_TYPE_NEC) {
 +      } else if (rc_type == RC_TYPE_NEC) {
                dev->board.xclk &= ~EM28XX_XCLK_IR_RC5_MODE;
                ir_config = EM2874_IR_NEC;
                ir->full_code = 1;
 -      } else if (ir_type != IR_TYPE_UNKNOWN)
 +      } else if (rc_type != RC_TYPE_UNKNOWN)
                rc = -EINVAL;
  
        em28xx_write_reg_bits(dev, EM28XX_R0F_XCLK, dev->board.xclk,
  int em28xx_ir_init(struct em28xx *dev)
  {
        struct em28xx_IR *ir;
 -      struct input_dev *input_dev;
 +      struct rc_dev *rc;
        int err = -ENOMEM;
  
        if (dev->board.ir_codes == NULL) {
        }
  
        ir = kzalloc(sizeof(*ir), GFP_KERNEL);
 -      input_dev = input_allocate_device();
 -      if (!ir || !input_dev)
 +      rc = rc_allocate_device();
 +      if (!ir || !rc)
                goto err_out_free;
  
        /* record handles to ourself */
        ir->dev = dev;
        dev->ir = ir;
 -
 -      ir->input = input_dev;
 +      ir->rc = rc;
  
        /*
         * em2874 supports more protocols. For now, let's just announce
         * the two protocols that were already tested
         */
 -      ir->props.allowed_protos = IR_TYPE_RC5 | IR_TYPE_NEC;
 -      ir->props.priv = ir;
 -      ir->props.change_protocol = em28xx_ir_change_protocol;
 -      ir->props.open = em28xx_ir_start;
 -      ir->props.close = em28xx_ir_stop;
 +      rc->allowed_protos = RC_TYPE_RC5 | RC_TYPE_NEC;
 +      rc->priv = ir;
 +      rc->change_protocol = em28xx_ir_change_protocol;
 +      rc->open = em28xx_ir_start;
 +      rc->close = em28xx_ir_stop;
  
        /* By default, keep protocol field untouched */
 -      err = em28xx_ir_change_protocol(ir, IR_TYPE_UNKNOWN);
 +      err = em28xx_ir_change_protocol(rc, RC_TYPE_UNKNOWN);
        if (err)
                goto err_out_free;
  
        usb_make_path(dev->udev, ir->phys, sizeof(ir->phys));
        strlcat(ir->phys, "/input0", sizeof(ir->phys));
  
 -      input_dev->name = ir->name;
 -      input_dev->phys = ir->phys;
 -      input_dev->id.bustype = BUS_USB;
 -      input_dev->id.version = 1;
 -      input_dev->id.vendor = le16_to_cpu(dev->udev->descriptor.idVendor);
 -      input_dev->id.product = le16_to_cpu(dev->udev->descriptor.idProduct);
 -
 -      input_dev->dev.parent = &dev->udev->dev;
 -
 -
 +      rc->input_name = ir->name;
 +      rc->input_phys = ir->phys;
 +      rc->input_id.bustype = BUS_USB;
 +      rc->input_id.version = 1;
 +      rc->input_id.vendor = le16_to_cpu(dev->udev->descriptor.idVendor);
 +      rc->input_id.product = le16_to_cpu(dev->udev->descriptor.idProduct);
 +      rc->dev.parent = &dev->udev->dev;
 +      rc->map_name = dev->board.ir_codes;
 +      rc->driver_name = MODULE_NAME;
  
        /* all done */
 -      err = ir_input_register(ir->input, dev->board.ir_codes,
 -                              &ir->props, MODULE_NAME);
 +      err = rc_register_device(rc);
        if (err)
                goto err_out_stop;
  
        return 0;
 +
   err_out_stop:
        dev->ir = NULL;
   err_out_free:
 +      rc_free_device(rc);
        kfree(ir);
        return err;
  }
@@@ -462,8 -468,8 +462,8 @@@ int em28xx_ir_fini(struct em28xx *dev
        if (!ir)
                return 0;
  
 -      em28xx_ir_stop(ir);
 -      ir_input_unregister(ir->input);
 +      em28xx_ir_stop(ir->rc);
 +      rc_unregister_device(ir->rc);
        kfree(ir);
  
        /* done */
@@@ -551,7 -557,7 +551,7 @@@ void em28xx_deregister_snapshot_button(
  {
        if (dev->sbutton_input_dev != NULL) {
                em28xx_info("Deregistering snapshot button\n");
-               cancel_rearming_delayed_work(&dev->sbutton_query_work);
+               cancel_delayed_work_sync(&dev->sbutton_query_work);
                input_unregister_device(dev->sbutton_input_dev);
                dev->sbutton_input_dev = NULL;
        }
@@@ -166,8 -166,14 +166,14 @@@ static void request_submodules(struct s
        schedule_work(&dev->request_module_wk);
  }
  
+ static void flush_request_submodules(struct saa7134_dev *dev)
+ {
+       flush_work_sync(&dev->request_module_wk);
+ }
  #else
  #define request_submodules(dev)
+ #define flush_request_submodules(dev)
  #endif /* CONFIG_MODULES */
  
  /* ------------------------------------------------------------------ */
@@@ -991,7 -997,7 +997,7 @@@ static int __devinit saa7134_initdev(st
        if (card_is_empress(dev)) {
                struct v4l2_subdev *sd =
                        v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
 -                              NULL, "saa6752hs",
 +                              "saa6752hs",
                                saa7134_boards[dev->board].empress_addr, NULL);
  
                if (sd)
                struct v4l2_subdev *sd;
  
                sd = v4l2_i2c_new_subdev(&dev->v4l2_dev,
 -                              &dev->i2c_adap, NULL, "saa6588",
 +                              &dev->i2c_adap, "saa6588",
                                0, I2C_ADDRS(saa7134_boards[dev->board].rds_addr));
                if (sd) {
                        printk(KERN_INFO "%s: found RDS decoder\n", dev->name);
                }
        }
  
-       request_submodules(dev);
        v4l2_prio_init(&dev->prio);
  
        mutex_lock(&saa7134_devlist_lock);
        if (saa7134_dmasound_init && !dev->dmasound.priv_data)
                saa7134_dmasound_init(dev);
  
+       request_submodules(dev);
        return 0;
  
   fail4:
@@@ -1091,6 -1096,8 +1096,8 @@@ static void __devexit saa7134_finidev(s
        struct saa7134_dev *dev = container_of(v4l2_dev, struct saa7134_dev, v4l2_dev);
        struct saa7134_mpeg_ops *mops;
  
+       flush_request_submodules(dev);
        /* Release DMA sound modules if present */
        if (saa7134_dmasound_exit && dev->dmasound.priv_data) {
                saa7134_dmasound_exit(dev);
diff --combined drivers/mmc/core/core.c
@@@ -1559,7 -1559,7 +1559,7 @@@ void mmc_stop_host(struct mmc_host *hos
  
        if (host->caps & MMC_CAP_DISABLE)
                cancel_delayed_work(&host->disable);
 -      cancel_delayed_work(&host->detect);
 +      cancel_delayed_work_sync(&host->detect);
        mmc_flush_scheduled_work();
  
        /* clear pm flags now and let card drivers set them as needed */
@@@ -1773,7 -1773,6 +1773,7 @@@ int mmc_pm_notify(struct notifier_bloc
  
        case PM_POST_SUSPEND:
        case PM_POST_HIBERNATION:
 +      case PM_POST_RESTORE:
  
                spin_lock_irqsave(&host->lock, flags);
                host->rescan_disable = 0;
@@@ -1790,7 -1789,7 +1790,7 @@@ static int __init mmc_init(void
  {
        int ret;
  
-       workqueue = create_singlethread_workqueue("kmmcd");
+       workqueue = alloc_ordered_workqueue("kmmcd", 0);
        if (!workqueue)
                return -ENOMEM;
  
@@@ -1002,7 -1002,7 +1002,7 @@@ static inline void omap_hsmmc_reset_con
         * Monitor a 0->1 transition first
         */
        if (mmc_slot(host).features & HSMMC_HAS_UPDATED_RESET) {
 -              while ((!(OMAP_HSMMC_READ(host, SYSCTL) & bit))
 +              while ((!(OMAP_HSMMC_READ(host->base, SYSCTL) & bit))
                                        && (i++ < limit))
                        cpu_relax();
        }
@@@ -2290,7 -2290,7 +2290,7 @@@ static int omap_hsmmc_remove(struct pla
                free_irq(host->irq, host);
                if (mmc_slot(host).card_detect_irq)
                        free_irq(mmc_slot(host).card_detect_irq, host);
-               flush_scheduled_work();
+               flush_work_sync(&host->mmc_carddetect_work);
  
                mmc_host_disable(host->mmc);
                clk_disable(host->iclk);
@@@ -1279,7 -1279,7 +1279,7 @@@ static void emac_force_link_update(stru
        netif_carrier_off(dev->ndev);
        smp_rmb();
        if (dev->link_polling) {
-               cancel_rearming_delayed_work(&dev->link_work);
+               cancel_delayed_work_sync(&dev->link_work);
                if (dev->link_polling)
                        schedule_delayed_work(&dev->link_work,  PHY_POLL_LINK_OFF);
        }
@@@ -1294,7 -1294,7 +1294,7 @@@ static int emac_close(struct net_devic
  
        if (dev->phy.address >= 0) {
                dev->link_polling = 0;
-               cancel_rearming_delayed_work(&dev->link_work);
+               cancel_delayed_work_sync(&dev->link_work);
        }
        mutex_lock(&dev->link_lock);
        emac_netif_stop(dev);
@@@ -2950,7 -2950,7 +2950,7 @@@ static int __devexit emac_remove(struc
  
        unregister_netdev(dev->ndev);
  
 -      flush_scheduled_work();
 +      cancel_work_sync(&dev->reset_work);
  
        if (emac_has_feature(dev, EMAC_FTR_HAS_TAH))
                tah_detach(dev->tah_dev, dev->tah_port);
@@@ -826,13 -826,6 +826,13 @@@ const struct address_space_operations p
        .set_page_dirty         = __set_page_dirty_nobuffers,
  };
  
 +static void pohmelfs_i_callback(struct rcu_head *head)
 +{
 +      struct inode *inode = container_of(head, struct inode, i_rcu);
 +      INIT_LIST_HEAD(&inode->i_dentry);
 +      kmem_cache_free(pohmelfs_inode_cache, POHMELFS_I(inode));
 +}
 +
  /*
   * ->detroy_inode() callback. Deletes inode from the caches
   *  and frees private data.
@@@ -849,8 -842,8 +849,8 @@@ static void pohmelfs_destroy_inode(stru
  
        dprintk("%s: pi: %p, inode: %p, ino: %llu.\n",
                __func__, pi, &pi->vfs_inode, pi->ino);
 -      kmem_cache_free(pohmelfs_inode_cache, pi);
        atomic_long_dec(&psb->total_inodes);
 +      call_rcu(&inode->i_rcu, pohmelfs_i_callback);
  }
  
  /*
@@@ -1325,8 -1318,8 +1325,8 @@@ static void pohmelfs_put_super(struct s
        }
  
        psb->trans_scan_timeout = psb->drop_scan_timeout = 0;
-       cancel_rearming_delayed_work(&psb->dwork);
-       cancel_rearming_delayed_work(&psb->drop_dwork);
+       cancel_delayed_work_sync(&psb->dwork);
+       cancel_delayed_work_sync(&psb->drop_dwork);
        flush_scheduled_work();
  
        dprintk("%s: stopped workqueues.\n", __func__);
@@@ -240,9 -240,6 +240,9 @@@ rx_submit(struct eth_dev *dev, struct u
        size += out->maxpacket - 1;
        size -= size % out->maxpacket;
  
 +      if (dev->port_usb->is_fixed)
 +              size = max(size, dev->port_usb->fixed_out_len);
 +
        skb = alloc_skb(size + NET_IP_ALIGN, gfp_flags);
        if (skb == NULL) {
                DBG(dev, "no rx skb\n");
@@@ -581,19 -578,12 +581,19 @@@ static netdev_tx_t eth_start_xmit(struc
        req->context = skb;
        req->complete = tx_complete;
  
 +      /* NCM requires no zlp if transfer is dwNtbInMaxSize */
 +      if (dev->port_usb->is_fixed &&
 +          length == dev->port_usb->fixed_in_len &&
 +          (length % in->maxpacket) == 0)
 +              req->zero = 0;
 +      else
 +              req->zero = 1;
 +
        /* use zlp framing on tx for strict CDC-Ether conformance,
         * though any robust network rx path ignores extra padding.
         * and some hardware doesn't like to write zlps.
         */
 -      req->zero = 1;
 -      if (!dev->zlp && (length % in->maxpacket) == 0)
 +      if (req->zero && !dev->zlp && (length % in->maxpacket) == 0)
                length++;
  
        req->length = length;
@@@ -839,11 -829,9 +839,9 @@@ void gether_cleanup(void
                return;
  
        unregister_netdev(the_dev->net);
+       flush_work_sync(&the_dev->work);
        free_netdev(the_dev->net);
  
-       /* assuming we used keventd, it must quiesce too */
-       flush_scheduled_work();
        the_dev = NULL;
  }
  
@@@ -901,7 -901,8 +901,8 @@@ static void ohci_stop (struct usb_hcd *
  
        ohci_dump (ohci, 1);
  
-       flush_scheduled_work();
+       if (quirk_nec(ohci))
+               flush_work_sync(&ohci->nec_work);
  
        ohci_usb_reset (ohci);
        ohci_writel (ohci, OHCI_INTR_MIE, &ohci->regs->intrdisable);
@@@ -1081,11 -1082,6 +1082,11 @@@ MODULE_LICENSE ("GPL")
  #define OF_PLATFORM_DRIVER    ohci_hcd_ppc_of_driver
  #endif
  
 +#ifdef CONFIG_PLAT_SPEAR
 +#include "ohci-spear.c"
 +#define PLATFORM_DRIVER               spear_ohci_hcd_driver
 +#endif
 +
  #ifdef CONFIG_PPC_PS3
  #include "ohci-ps3.c"
  #define PS3_SYSTEM_BUS_DRIVER ps3_ohci_driver
  #define PLATFORM_DRIVER               ohci_octeon_driver
  #endif
  
 +#ifdef CONFIG_USB_CNS3XXX_OHCI
 +#include "ohci-cns3xxx.c"
 +#define PLATFORM_DRIVER               ohci_hcd_cns3xxx_driver
 +#endif
 +
  #if   !defined(PCI_DRIVER) &&         \
        !defined(PLATFORM_DRIVER) &&    \
        !defined(OMAP1_PLATFORM_DRIVER) &&      \
diff --combined fs/ncpfs/inode.c
@@@ -29,7 -29,6 +29,7 @@@
  #include <linux/vfs.h>
  #include <linux/mount.h>
  #include <linux/seq_file.h>
 +#include <linux/namei.h>
  
  #include <linux/ncp_fs.h>
  
@@@ -59,18 -58,11 +59,18 @@@ static struct inode *ncp_alloc_inode(st
        return &ei->vfs_inode;
  }
  
 -static void ncp_destroy_inode(struct inode *inode)
 +static void ncp_i_callback(struct rcu_head *head)
  {
 +      struct inode *inode = container_of(head, struct inode, i_rcu);
 +      INIT_LIST_HEAD(&inode->i_dentry);
        kmem_cache_free(ncp_inode_cachep, NCP_FINFO(inode));
  }
  
 +static void ncp_destroy_inode(struct inode *inode)
 +{
 +      call_rcu(&inode->i_rcu, ncp_i_callback);
 +}
 +
  static void init_once(void *foo)
  {
        struct ncp_inode_info *ei = (struct ncp_inode_info *) foo;
@@@ -317,7 -309,12 +317,12 @@@ static void ncp_stop_tasks(struct ncp_s
        sk->sk_write_space  = server->write_space;
        release_sock(sk);
        del_timer_sync(&server->timeout_tm);
-       flush_scheduled_work();
+       flush_work_sync(&server->rcv.tq);
+       if (sk->sk_socket->type == SOCK_STREAM)
+               flush_work_sync(&server->tx.tq);
+       else
+               flush_work_sync(&server->timeout_tq);
  }
  
  static int  ncp_show_options(struct seq_file *seq, struct vfsmount *mnt)
@@@ -718,7 -715,7 +723,7 @@@ static int ncp_fill_super(struct super_
        sb->s_root = d_alloc_root(root_inode);
          if (!sb->s_root)
                goto out_no_root;
 -      sb->s_root->d_op = &ncp_root_dentry_operations;
 +      d_set_d_op(sb->s_root, &ncp_root_dentry_operations);
        return 0;
  
  out_no_root:
@@@ -307,8 -307,7 +307,7 @@@ static void o2hb_arm_write_timeout(stru
  
  static void o2hb_disarm_write_timeout(struct o2hb_region *reg)
  {
-       cancel_delayed_work(&reg->hr_write_timeout_work);
-       flush_scheduled_work();
+       cancel_delayed_work_sync(&reg->hr_write_timeout_work);
  }
  
  static inline void o2hb_bio_wait_init(struct o2hb_bio_wait_ctxt *wc)
@@@ -1964,10 -1963,8 +1963,10 @@@ static struct config_item *o2hb_heartbe
        if (reg == NULL)
                return ERR_PTR(-ENOMEM);
  
 -      if (strlen(name) > O2HB_MAX_REGION_NAME_LEN)
 -              return ERR_PTR(-ENAMETOOLONG);
 +      if (strlen(name) > O2HB_MAX_REGION_NAME_LEN) {
 +              ret = -ENAMETOOLONG;
 +              goto free;
 +      }
  
        spin_lock(&o2hb_live_lock);
        reg->hr_region_num = 0;
                                                         O2NM_MAX_REGIONS);
                if (reg->hr_region_num >= O2NM_MAX_REGIONS) {
                        spin_unlock(&o2hb_live_lock);
 -                      return ERR_PTR(-EFBIG);
 +                      ret = -EFBIG;
 +                      goto free;
                }
                set_bit(reg->hr_region_num, o2hb_region_bitmap);
        }
        ret = o2hb_debug_region_init(reg, o2hb_debug_dir);
        if (ret) {
                config_item_put(&reg->hr_item);
 -              return ERR_PTR(ret);
 +              goto free;
        }
  
        return &reg->hr_item;
 +free:
 +      kfree(reg);
 +      return ERR_PTR(ret);
  }
  
  static void o2hb_heartbeat_group_drop_item(struct config_group *group,
@@@ -127,20 -127,12 +127,20 @@@ struct execute_work 
        .timer = TIMER_INITIALIZER(NULL, 0, 0),                 \
        }
  
 +#define __DEFERRED_WORK_INITIALIZER(n, f) {                   \
 +      .work = __WORK_INITIALIZER((n).work, (f)),              \
 +      .timer = TIMER_DEFERRED_INITIALIZER(NULL, 0, 0),        \
 +      }
 +
  #define DECLARE_WORK(n, f)                                    \
        struct work_struct n = __WORK_INITIALIZER(n, f)
  
  #define DECLARE_DELAYED_WORK(n, f)                            \
        struct delayed_work n = __DELAYED_WORK_INITIALIZER(n, f)
  
 +#define DECLARE_DEFERRED_WORK(n, f)                           \
 +      struct delayed_work n = __DEFERRED_WORK_INITIALIZER(n, f)
 +
  /*
   * initialize a work item's function pointer
   */
@@@ -409,7 -401,7 +409,7 @@@ static inline bool __cancel_delayed_wor
  }
  
  /* Obsolete. use cancel_delayed_work_sync() */
- static inline
+ static inline __deprecated
  void cancel_rearming_delayed_workqueue(struct workqueue_struct *wq,
                                        struct delayed_work *work)
  {
  }
  
  /* Obsolete. use cancel_delayed_work_sync() */
- static inline
+ static inline __deprecated
  void cancel_rearming_delayed_work(struct delayed_work *work)
  {
        cancel_delayed_work_sync(work);
diff --combined init/main.c
@@@ -67,7 -67,6 +67,7 @@@
  #include <linux/sfi.h>
  #include <linux/shmem_fs.h>
  #include <linux/slab.h>
 +#include <linux/perf_event.h>
  
  #include <asm/io.h>
  #include <asm/bugs.h>
@@@ -604,8 -603,6 +604,8 @@@ asmlinkage void __init start_kernel(voi
                                "enabled *very* early, fixing it\n");
                local_irq_disable();
        }
 +      idr_init_cache();
 +      perf_event_init();
        rcu_init();
        radix_tree_init();
        /* init some links before init_ISA_irqs() */
        enable_debug_pagealloc();
        kmemleak_init();
        debug_objects_mem_init();
 -      idr_init_cache();
        setup_per_cpu_pageset();
        numa_policy_init();
        if (late_time_init)
@@@ -777,9 -775,6 +777,6 @@@ static void __init do_initcalls(void
  
        for (fn = __early_initcall_end; fn < __initcall_end; fn++)
                do_one_initcall(*fn);
-       /* Make sure there is no pending stuff from the initcall sequence */
-       flush_scheduled_work();
  }
  
  /*
@@@ -884,7 -879,6 +881,7 @@@ static int __init kernel_init(void * un
        smp_prepare_cpus(setup_max_cpus);
  
        do_pre_smp_initcalls();
 +      lockup_detector_init();
  
        smp_init();
        sched_init_smp();
diff --combined mm/slab.c
+++ b/mm/slab.c
@@@ -1293,7 -1293,7 +1293,7 @@@ static int __cpuinit cpuup_callback(str
                 * anything expensive but will only modify reap_work
                 * and reschedule the timer.
                */
-               cancel_rearming_delayed_work(&per_cpu(slab_reap_work, cpu));
+               cancel_delayed_work_sync(&per_cpu(slab_reap_work, cpu));
                /* Now the cache_reaper is guaranteed to be not running. */
                per_cpu(slab_reap_work, cpu).work.func = NULL;
                break;
@@@ -2781,7 -2781,7 +2781,7 @@@ static void slab_put_obj(struct kmem_ca
  /*
   * Map pages beginning at addr to the given cache and slab. This is required
   * for the slab allocator to be able to lookup the cache and slab of a
 - * virtual address for kfree, ksize, kmem_ptr_validate, and slab debugging.
 + * virtual address for kfree, ksize, and slab debugging.
   */
  static void slab_map_pages(struct kmem_cache *cache, struct slab *slab,
                           void *addr)
@@@ -3660,6 -3660,36 +3660,6 @@@ void *kmem_cache_alloc_notrace(struct k
  EXPORT_SYMBOL(kmem_cache_alloc_notrace);
  #endif
  
 -/**
 - * kmem_ptr_validate - check if an untrusted pointer might be a slab entry.
 - * @cachep: the cache we're checking against
 - * @ptr: pointer to validate
 - *
 - * This verifies that the untrusted pointer looks sane;
 - * it is _not_ a guarantee that the pointer is actually
 - * part of the slab cache in question, but it at least
 - * validates that the pointer can be dereferenced and
 - * looks half-way sane.
 - *
 - * Currently only used for dentry validation.
 - */
 -int kmem_ptr_validate(struct kmem_cache *cachep, const void *ptr)
 -{
 -      unsigned long size = cachep->buffer_size;
 -      struct page *page;
 -
 -      if (unlikely(!kern_ptr_validate(ptr, size)))
 -              goto out;
 -      page = virt_to_page(ptr);
 -      if (unlikely(!PageSlab(page)))
 -              goto out;
 -      if (unlikely(page_get_cache(page) != cachep))
 -              goto out;
 -      return 1;
 -out:
 -      return 0;
 -}
 -
  #ifdef CONFIG_NUMA
  void *kmem_cache_alloc_node(struct kmem_cache *cachep, gfp_t flags, int nodeid)
  {
diff --combined mm/vmstat.c
@@@ -750,6 -750,8 +750,6 @@@ static const char * const vmstat_text[
        "nr_shmem",
        "nr_dirtied",
        "nr_written",
 -      "nr_dirty_threshold",
 -      "nr_dirty_background_threshold",
  
  #ifdef CONFIG_NUMA
        "numa_hit",
        "numa_local",
        "numa_other",
  #endif
 +      "nr_dirty_threshold",
 +      "nr_dirty_background_threshold",
  
  #ifdef CONFIG_VM_EVENT_COUNTERS
        "pgpgin",
@@@ -1033,7 -1033,7 +1033,7 @@@ static int __cpuinit vmstat_cpuup_callb
                break;
        case CPU_DOWN_PREPARE:
        case CPU_DOWN_PREPARE_FROZEN:
-               cancel_rearming_delayed_work(&per_cpu(vmstat_work, cpu));
+               cancel_delayed_work_sync(&per_cpu(vmstat_work, cpu));
                per_cpu(vmstat_work, cpu).work.func = NULL;
                break;
        case CPU_DOWN_FAILED:
diff --combined net/atm/lec.c
@@@ -816,7 -816,8 +816,7 @@@ static int lec_mcast_attach(struct atm_
        if (arg < 0 || arg >= MAX_LEC_ITF || !dev_lec[arg])
                return -EINVAL;
        vcc->proto_data = dev_lec[arg];
 -      return lec_mcast_make((struct lec_priv *)netdev_priv(dev_lec[arg]),
 -                              vcc);
 +      return lec_mcast_make(netdev_priv(dev_lec[arg]), vcc);
  }
  
  /* Initialize device. */
@@@ -1607,7 -1608,7 +1607,7 @@@ static void lec_arp_destroy(struct lec_
        struct lec_arp_table *entry;
        int i;
  
-       cancel_rearming_delayed_work(&priv->lec_arp_work);
+       cancel_delayed_work_sync(&priv->lec_arp_work);
  
        /*
         * Remove all entries
diff --combined net/core/netpoll.c
@@@ -35,6 -35,7 +35,6 @@@
  
  #define MAX_UDP_CHUNK 1460
  #define MAX_SKBS 32
 -#define MAX_QUEUE_DEPTH (MAX_SKBS / 2)
  
  static struct sk_buff_head skb_pool;
  
@@@ -75,7 -76,8 +75,7 @@@ static void queue_process(struct work_s
  
                local_irq_save(flags);
                __netif_tx_lock(txq, smp_processor_id());
 -              if (netif_tx_queue_stopped(txq) ||
 -                  netif_tx_queue_frozen(txq) ||
 +              if (netif_tx_queue_frozen_or_stopped(txq) ||
                    ops->ndo_start_xmit(skb, dev) != NETDEV_TX_OK) {
                        skb_queue_head(&npinfo->txq, skb);
                        __netif_tx_unlock(txq);
@@@ -923,7 -925,7 +923,7 @@@ void __netpoll_cleanup(struct netpoll *
  
                skb_queue_purge(&npinfo->arp_tx);
                skb_queue_purge(&npinfo->txq);
-               cancel_rearming_delayed_work(&npinfo->tx_work);
+               cancel_delayed_work_sync(&npinfo->tx_work);
  
                /* clean after last, unfinished work */
                __skb_queue_purge(&npinfo->txq);
@@@ -110,8 -110,10 +110,8 @@@ static int __ip_vs_addr_is_local_v6(con
        struct rt6_info *rt;
        struct flowi fl = {
                .oif = 0,
 -              .nl_u = {
 -                      .ip6_u = {
 -                              .daddr = *addr,
 -                              .saddr = { .s6_addr32 = {0, 0, 0, 0} }, } },
 +              .fl6_dst = *addr,
 +              .fl6_src = { .s6_addr32 = {0, 0, 0, 0} },
        };
  
        rt = (struct rt6_info *)ip6_route_output(&init_net, NULL, &fl);
@@@ -3430,7 -3432,7 +3430,7 @@@ void ip_vs_control_cleanup(void
  {
        EnterFunction(2);
        ip_vs_trash_cleanup();
-       cancel_rearming_delayed_work(&defense_work);
+       cancel_delayed_work_sync(&defense_work);
        cancel_work_sync(&defense_work.work);
        ip_vs_kill_estimator(&ip_vs_stats);
        unregister_sysctl_table(sysctl_header);