struct {
                int stream;
                struct snd_timer_id id;
-               struct tasklet_struct event_tasklet;
+               struct work_struct event_work;
                struct snd_timer_instance *instance;
        } snd_timer;
 };
         */
        snd_timer_close(cable->snd_timer.instance);
 
-       /* wait till drain tasklet has finished if requested */
-       tasklet_kill(&cable->snd_timer.event_tasklet);
+       /* wait till drain work has finished if requested */
+       cancel_work_sync(&cable->snd_timer.event_work);
 
        snd_timer_instance_free(cable->snd_timer.instance);
        memset(&cable->snd_timer, 0, sizeof(cable->snd_timer));
                                          resolution);
 }
 
-static void loopback_snd_timer_tasklet(unsigned long arg)
+static void loopback_snd_timer_work(struct work_struct *work)
 {
-       struct snd_timer_instance *timeri = (struct snd_timer_instance *)arg;
-       struct loopback_cable *cable = timeri->callback_data;
+       struct loopback_cable *cable;
 
+       cable = container_of(work, struct loopback_cable, snd_timer.event_work);
        loopback_snd_timer_period_elapsed(cable, SNDRV_TIMER_EVENT_MSTOP, 0);
 }
 
                 * state the streaming will be aborted by the usual timeout. It
                 * should not be aborted here because may be the timer sound
                 * card does only a recovery and the timer is back soon.
-                * This tasklet triggers loopback_snd_timer_tasklet()
+                * This work triggers loopback_snd_timer_work()
                 */
-               tasklet_schedule(&cable->snd_timer.event_tasklet);
+               schedule_work(&cable->snd_timer.event_work);
        }
 }
 
                err = -ENOMEM;
                goto exit;
        }
-       /* The callback has to be called from another tasklet. If
+       /* The callback has to be called from another work. If
         * SNDRV_TIMER_IFLG_FAST is specified it will be called from the
         * snd_pcm_period_elapsed() call of the selected sound card.
         * snd_pcm_period_elapsed() helds snd_pcm_stream_lock_irqsave().
        timeri->callback_data = (void *)cable;
        timeri->ccallback = loopback_snd_timer_event;
 
-       /* initialise a tasklet used for draining */
-       tasklet_init(&cable->snd_timer.event_tasklet,
-                    loopback_snd_timer_tasklet, (unsigned long)timeri);
+       /* initialise a work used for draining */
+       INIT_WORK(&cable->snd_timer.event_work, loopback_snd_timer_work);
 
        /* The mutex loopback->cable_lock is kept locked.
         * Therefore snd_timer_open() cannot be called a second time