ALSA: aloop: Replace tasklet with work

The tasklet is an old API that should be deprecated, usually can be
converted to another decent API.  In aloop driver, a tasklet is still
used for offloading the timer event task.  It can be achieved
gracefully with a work queued, too.

This patch replaces the tasklet usage in aloop driver with a simple
work.

Link: https://lore.kernel.org/r/20200903104131.21097-6-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
Takashi Iwai 2020-09-03 12:41:25 +02:00
parent 45e4d67f8a
commit 6053a71247
1 changed files with 11 additions and 12 deletions

View File

@ -110,7 +110,7 @@ struct loopback_cable {
struct { struct {
int stream; int stream;
struct snd_timer_id id; struct snd_timer_id id;
struct tasklet_struct event_tasklet; struct work_struct event_work;
struct snd_timer_instance *instance; struct snd_timer_instance *instance;
} snd_timer; } snd_timer;
}; };
@ -309,8 +309,8 @@ static int loopback_snd_timer_close_cable(struct loopback_pcm *dpcm)
*/ */
snd_timer_close(cable->snd_timer.instance); snd_timer_close(cable->snd_timer.instance);
/* wait till drain tasklet has finished if requested */ /* wait till drain work has finished if requested */
tasklet_kill(&cable->snd_timer.event_tasklet); cancel_work_sync(&cable->snd_timer.event_work);
snd_timer_instance_free(cable->snd_timer.instance); snd_timer_instance_free(cable->snd_timer.instance);
memset(&cable->snd_timer, 0, sizeof(cable->snd_timer)); memset(&cable->snd_timer, 0, sizeof(cable->snd_timer));
@ -794,11 +794,11 @@ static void loopback_snd_timer_function(struct snd_timer_instance *timeri,
resolution); 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;
struct loopback_cable *cable = timeri->callback_data;
cable = container_of(work, struct loopback_cable, snd_timer.event_work);
loopback_snd_timer_period_elapsed(cable, SNDRV_TIMER_EVENT_MSTOP, 0); loopback_snd_timer_period_elapsed(cable, SNDRV_TIMER_EVENT_MSTOP, 0);
} }
@ -828,9 +828,9 @@ static void loopback_snd_timer_event(struct snd_timer_instance *timeri,
* state the streaming will be aborted by the usual timeout. It * state the streaming will be aborted by the usual timeout. It
* should not be aborted here because may be the timer sound * should not be aborted here because may be the timer sound
* card does only a recovery and the timer is back soon. * 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);
} }
} }
@ -1124,7 +1124,7 @@ static int loopback_snd_timer_open(struct loopback_pcm *dpcm)
err = -ENOMEM; err = -ENOMEM;
goto exit; 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 * 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() call of the selected sound card.
* snd_pcm_period_elapsed() helds snd_pcm_stream_lock_irqsave(). * snd_pcm_period_elapsed() helds snd_pcm_stream_lock_irqsave().
@ -1137,9 +1137,8 @@ static int loopback_snd_timer_open(struct loopback_pcm *dpcm)
timeri->callback_data = (void *)cable; timeri->callback_data = (void *)cable;
timeri->ccallback = loopback_snd_timer_event; timeri->ccallback = loopback_snd_timer_event;
/* initialise a tasklet used for draining */ /* initialise a work used for draining */
tasklet_init(&cable->snd_timer.event_tasklet, INIT_WORK(&cable->snd_timer.event_work, loopback_snd_timer_work);
loopback_snd_timer_tasklet, (unsigned long)timeri);
/* The mutex loopback->cable_lock is kept locked. /* The mutex loopback->cable_lock is kept locked.
* Therefore snd_timer_open() cannot be called a second time * Therefore snd_timer_open() cannot be called a second time