Commit 13dab080 authored by Jaroslav Kysela's avatar Jaroslav Kysela Committed by Takashi Iwai

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: default avatarJaroslav Kysela <perex@perex.cz>
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent 123c07ae
...@@ -164,20 +164,21 @@ static void snd_hda_do_register(struct work_struct *work) ...@@ -164,20 +164,21 @@ static void snd_hda_do_register(struct work_struct *work)
{ {
struct hda_beep *beep = struct hda_beep *beep =
container_of(work, struct hda_beep, register_work); container_of(work, struct hda_beep, register_work);
int request;
mutex_lock(&beep->mutex); mutex_lock(&beep->mutex);
request = beep->request_enable; if (beep->enabled && !beep->dev)
if (beep->enabled != request) { snd_hda_do_attach(beep);
if (!request) { mutex_unlock(&beep->mutex);
snd_hda_do_detach(beep); }
} else {
if (snd_hda_do_attach(beep) < 0) static void snd_hda_do_unregister(struct work_struct *work)
goto __out; {
} struct hda_beep *beep =
beep->enabled = request; container_of(work, struct hda_beep, unregister_work.work);
}
__out: mutex_lock(&beep->mutex);
if (!beep->enabled && beep->dev)
snd_hda_do_detach(beep);
mutex_unlock(&beep->mutex); mutex_unlock(&beep->mutex);
} }
...@@ -185,9 +186,19 @@ int snd_hda_enable_beep_device(struct hda_codec *codec, int enable) ...@@ -185,9 +186,19 @@ int snd_hda_enable_beep_device(struct hda_codec *codec, int enable)
{ {
struct hda_beep *beep = codec->beep; struct hda_beep *beep = codec->beep;
enable = !!enable; enable = !!enable;
if (beep && beep->enabled != enable) { if (beep == NULL)
beep->request_enable = enable; return 0;
schedule_work(&beep->register_work); 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 1;
} }
return 0; return 0;
...@@ -215,6 +226,7 @@ int snd_hda_attach_beep_device(struct hda_codec *codec, int nid) ...@@ -215,6 +226,7 @@ int snd_hda_attach_beep_device(struct hda_codec *codec, int nid)
codec->beep = beep; codec->beep = beep;
INIT_WORK(&beep->register_work, &snd_hda_do_register); 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); INIT_WORK(&beep->beep_work, &snd_hda_generate_beep);
mutex_init(&beep->mutex); mutex_init(&beep->mutex);
......
...@@ -34,7 +34,8 @@ struct hda_beep { ...@@ -34,7 +34,8 @@ struct hda_beep {
unsigned int enabled:1; unsigned int enabled:1;
unsigned int request_enable:1; unsigned int request_enable:1;
unsigned int linear_tone:1; /* linear tone for IDT/STAC codec */ 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 work_struct beep_work; /* scheduled task for beep event */
struct mutex mutex; struct mutex mutex;
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment