diff options
author | Jaroslav Kysela <perex@perex.cz> | 2009-11-03 08:29:50 -0500 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2009-11-16 05:35:00 -0500 |
commit | 13dab0808bb41b18888e1758a060a685deee1f30 (patch) | |
tree | 3d0828a0c537d9ba9934562631816a4671a3bf56 /sound | |
parent | 123c07aeddd71fbb295842a8c19866e780b9a100 (diff) |
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>
Diffstat (limited to 'sound')
-rw-r--r-- | sound/pci/hda/hda_beep.c | 42 | ||||
-rw-r--r-- | sound/pci/hda/hda_beep.h | 3 |
2 files changed, 29 insertions, 16 deletions
diff --git a/sound/pci/hda/hda_beep.c b/sound/pci/hda/hda_beep.c index 0e986537d570..74db40edb336 100644 --- a/sound/pci/hda/hda_beep.c +++ b/sound/pci/hda/hda_beep.c | |||
@@ -164,20 +164,21 @@ static void snd_hda_do_register(struct work_struct *work) | |||
164 | { | 164 | { |
165 | struct hda_beep *beep = | 165 | struct hda_beep *beep = |
166 | container_of(work, struct hda_beep, register_work); | 166 | container_of(work, struct hda_beep, register_work); |
167 | int request; | ||
168 | 167 | ||
169 | mutex_lock(&beep->mutex); | 168 | mutex_lock(&beep->mutex); |
170 | request = beep->request_enable; | 169 | if (beep->enabled && !beep->dev) |
171 | if (beep->enabled != request) { | 170 | snd_hda_do_attach(beep); |
172 | if (!request) { | 171 | mutex_unlock(&beep->mutex); |
173 | snd_hda_do_detach(beep); | 172 | } |
174 | } else { | 173 | |
175 | if (snd_hda_do_attach(beep) < 0) | 174 | static void snd_hda_do_unregister(struct work_struct *work) |
176 | goto __out; | 175 | { |
177 | } | 176 | struct hda_beep *beep = |
178 | beep->enabled = request; | 177 | container_of(work, struct hda_beep, unregister_work.work); |
179 | } | 178 | |
180 | __out: | 179 | mutex_lock(&beep->mutex); |
180 | if (!beep->enabled && beep->dev) | ||
181 | snd_hda_do_detach(beep); | ||
181 | mutex_unlock(&beep->mutex); | 182 | mutex_unlock(&beep->mutex); |
182 | } | 183 | } |
183 | 184 | ||
@@ -185,9 +186,19 @@ int snd_hda_enable_beep_device(struct hda_codec *codec, int enable) | |||
185 | { | 186 | { |
186 | struct hda_beep *beep = codec->beep; | 187 | struct hda_beep *beep = codec->beep; |
187 | enable = !!enable; | 188 | enable = !!enable; |
188 | if (beep && beep->enabled != enable) { | 189 | if (beep == NULL) |
189 | beep->request_enable = enable; | 190 | return 0; |
190 | schedule_work(&beep->register_work); | 191 | if (beep->enabled != enable) { |
192 | beep->enabled = enable; | ||
193 | if (enable) { | ||
194 | cancel_delayed_work(&beep->unregister_work); | ||
195 | schedule_work(&beep->register_work); | ||
196 | } else { | ||
197 | /* turn off beep */ | ||
198 | snd_hda_codec_write_cache(beep->codec, beep->nid, 0, | ||
199 | AC_VERB_SET_BEEP_CONTROL, 0); | ||
200 | schedule_delayed_work(&beep->unregister_work, HZ); | ||
201 | } | ||
191 | return 1; | 202 | return 1; |
192 | } | 203 | } |
193 | return 0; | 204 | return 0; |
@@ -215,6 +226,7 @@ int snd_hda_attach_beep_device(struct hda_codec *codec, int nid) | |||
215 | codec->beep = beep; | 226 | codec->beep = beep; |
216 | 227 | ||
217 | INIT_WORK(&beep->register_work, &snd_hda_do_register); | 228 | INIT_WORK(&beep->register_work, &snd_hda_do_register); |
229 | INIT_DELAYED_WORK(&beep->unregister_work, &snd_hda_do_unregister); | ||
218 | INIT_WORK(&beep->beep_work, &snd_hda_generate_beep); | 230 | INIT_WORK(&beep->beep_work, &snd_hda_generate_beep); |
219 | mutex_init(&beep->mutex); | 231 | mutex_init(&beep->mutex); |
220 | 232 | ||
diff --git a/sound/pci/hda/hda_beep.h b/sound/pci/hda/hda_beep.h index 68465f679d8c..53eba8d8414d 100644 --- a/sound/pci/hda/hda_beep.h +++ b/sound/pci/hda/hda_beep.h | |||
@@ -34,7 +34,8 @@ struct hda_beep { | |||
34 | unsigned int enabled:1; | 34 | unsigned int enabled:1; |
35 | unsigned int request_enable:1; | 35 | unsigned int request_enable:1; |
36 | unsigned int linear_tone:1; /* linear tone for IDT/STAC codec */ | 36 | unsigned int linear_tone:1; /* linear tone for IDT/STAC codec */ |
37 | struct work_struct register_work; /* scheduled task for beep event */ | 37 | struct work_struct register_work; /* registration work */ |
38 | struct delayed_work unregister_work; /* unregistration work */ | ||
38 | struct work_struct beep_work; /* scheduled task for beep event */ | 39 | struct work_struct beep_work; /* scheduled task for beep event */ |
39 | struct mutex mutex; | 40 | struct mutex mutex; |
40 | }; | 41 | }; |