ALSA: hda_intel: Digital PC Beep - delay input device unregistration
The massive register/unregister calls for input device layer might be overkill. Delay unregister call by one HZ as workaround. Also, as benefit, beep->enabled variable is changed immediately now (not from workqueue). Signed-off-by: Jaroslav Kysela <perex@perex.cz> Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
parent
123c07aedd
commit
13dab0808b
|
@ -164,20 +164,21 @@ static void snd_hda_do_register(struct work_struct *work)
|
|||
{
|
||||
struct hda_beep *beep =
|
||||
container_of(work, struct hda_beep, register_work);
|
||||
int request;
|
||||
|
||||
mutex_lock(&beep->mutex);
|
||||
request = beep->request_enable;
|
||||
if (beep->enabled != request) {
|
||||
if (!request) {
|
||||
snd_hda_do_detach(beep);
|
||||
} else {
|
||||
if (snd_hda_do_attach(beep) < 0)
|
||||
goto __out;
|
||||
}
|
||||
beep->enabled = request;
|
||||
}
|
||||
__out:
|
||||
if (beep->enabled && !beep->dev)
|
||||
snd_hda_do_attach(beep);
|
||||
mutex_unlock(&beep->mutex);
|
||||
}
|
||||
|
||||
static void snd_hda_do_unregister(struct work_struct *work)
|
||||
{
|
||||
struct hda_beep *beep =
|
||||
container_of(work, struct hda_beep, unregister_work.work);
|
||||
|
||||
mutex_lock(&beep->mutex);
|
||||
if (!beep->enabled && beep->dev)
|
||||
snd_hda_do_detach(beep);
|
||||
mutex_unlock(&beep->mutex);
|
||||
}
|
||||
|
||||
|
@ -185,9 +186,19 @@ int snd_hda_enable_beep_device(struct hda_codec *codec, int enable)
|
|||
{
|
||||
struct hda_beep *beep = codec->beep;
|
||||
enable = !!enable;
|
||||
if (beep && beep->enabled != enable) {
|
||||
beep->request_enable = enable;
|
||||
schedule_work(&beep->register_work);
|
||||
if (beep == NULL)
|
||||
return 0;
|
||||
if (beep->enabled != enable) {
|
||||
beep->enabled = enable;
|
||||
if (enable) {
|
||||
cancel_delayed_work(&beep->unregister_work);
|
||||
schedule_work(&beep->register_work);
|
||||
} else {
|
||||
/* turn off beep */
|
||||
snd_hda_codec_write_cache(beep->codec, beep->nid, 0,
|
||||
AC_VERB_SET_BEEP_CONTROL, 0);
|
||||
schedule_delayed_work(&beep->unregister_work, HZ);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
|
@ -215,6 +226,7 @@ int snd_hda_attach_beep_device(struct hda_codec *codec, int nid)
|
|||
codec->beep = beep;
|
||||
|
||||
INIT_WORK(&beep->register_work, &snd_hda_do_register);
|
||||
INIT_DELAYED_WORK(&beep->unregister_work, &snd_hda_do_unregister);
|
||||
INIT_WORK(&beep->beep_work, &snd_hda_generate_beep);
|
||||
mutex_init(&beep->mutex);
|
||||
|
||||
|
|
|
@ -34,7 +34,8 @@ struct hda_beep {
|
|||
unsigned int enabled:1;
|
||||
unsigned int request_enable:1;
|
||||
unsigned int linear_tone:1; /* linear tone for IDT/STAC codec */
|
||||
struct work_struct register_work; /* scheduled task for beep event */
|
||||
struct work_struct register_work; /* registration work */
|
||||
struct delayed_work unregister_work; /* unregistration work */
|
||||
struct work_struct beep_work; /* scheduled task for beep event */
|
||||
struct mutex mutex;
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue