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:
parent
45e4d67f8a
commit
6053a71247
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue