Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+27 −15
Original line number Diff line number Diff line
@@ -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;
	if (beep->enabled && !beep->dev)
		snd_hda_do_attach(beep);
	mutex_unlock(&beep->mutex);
}
       __out:

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;
	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);

+2 −1
Original line number Diff line number Diff line
@@ -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;
};