From b4bde3771c0d510b033cb990e1314809b7ddd788 Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Tue, 3 Nov 2009 14:29:50 +0100 Subject: [PATCH] --- yaml --- r: 170328 b: refs/heads/master c: 13dab0808bb41b18888e1758a060a685deee1f30 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/sound/pci/hda/hda_beep.c | 42 ++++++++++++++++++++++------------ trunk/sound/pci/hda/hda_beep.h | 3 ++- 3 files changed, 30 insertions(+), 17 deletions(-) diff --git a/[refs] b/[refs] index ff957a07af33..174b437551e6 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 123c07aeddd71fbb295842a8c19866e780b9a100 +refs/heads/master: 13dab0808bb41b18888e1758a060a685deee1f30 diff --git a/trunk/sound/pci/hda/hda_beep.c b/trunk/sound/pci/hda/hda_beep.c index 0e986537d570..74db40edb336 100644 --- a/trunk/sound/pci/hda/hda_beep.c +++ b/trunk/sound/pci/hda/hda_beep.c @@ -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); diff --git a/trunk/sound/pci/hda/hda_beep.h b/trunk/sound/pci/hda/hda_beep.h index 68465f679d8c..53eba8d8414d 100644 --- a/trunk/sound/pci/hda/hda_beep.h +++ b/trunk/sound/pci/hda/hda_beep.h @@ -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; };