summaryrefslogtreecommitdiffstats
path: root/sound/pci
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2019-01-24 03:45:36 -0500
committerTakashi Iwai <tiwai@suse.de>2019-01-29 12:28:09 -0500
commit45571bb871b217f1031045a27d935ea7c6ea5d12 (patch)
treeafe743bfa29172c521d396e9e146dc95051b9fd2 /sound/pci
parent9a19c90276e85e78612ee1d0a67ffb431253bff2 (diff)
ALSA: hda - Use standard device registration for beep
Currently the registration and free of beep input device was done manually from the register and the disconnect callbacks of the assigned codec object. This seems working in most cases, but this may be a cause of some races at probe. Moreover, due to these manual calls, the total code became unnecessarily lengthy. This patch rewrites the beep registration code to follow the standard sound device object style. This allows us reducing the code, in addition to avoiding the nested device registration calls. Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci')
-rw-r--r--sound/pci/hda/hda_beep.c151
-rw-r--r--sound/pci/hda/hda_beep.h5
-rw-r--r--sound/pci/hda/hda_codec.c10
3 files changed, 72 insertions, 94 deletions
diff --git a/sound/pci/hda/hda_beep.c b/sound/pci/hda/hda_beep.c
index 066b5b59c4d7..b7d9160ed868 100644
--- a/sound/pci/hda/hda_beep.c
+++ b/sound/pci/hda/hda_beep.c
@@ -127,44 +127,6 @@ static void turn_off_beep(struct hda_beep *beep)
127 } 127 }
128} 128}
129 129
130static void snd_hda_do_detach(struct hda_beep *beep)
131{
132 if (beep->registered)
133 input_unregister_device(beep->dev);
134 else
135 input_free_device(beep->dev);
136 beep->dev = NULL;
137 turn_off_beep(beep);
138}
139
140static int snd_hda_do_attach(struct hda_beep *beep)
141{
142 struct input_dev *input_dev;
143 struct hda_codec *codec = beep->codec;
144
145 input_dev = input_allocate_device();
146 if (!input_dev)
147 return -ENOMEM;
148
149 /* setup digital beep device */
150 input_dev->name = "HDA Digital PCBeep";
151 input_dev->phys = beep->phys;
152 input_dev->id.bustype = BUS_PCI;
153 input_dev->dev.parent = &codec->card->card_dev;
154
155 input_dev->id.vendor = codec->core.vendor_id >> 16;
156 input_dev->id.product = codec->core.vendor_id & 0xffff;
157 input_dev->id.version = 0x01;
158
159 input_dev->evbit[0] = BIT_MASK(EV_SND);
160 input_dev->sndbit[0] = BIT_MASK(SND_BELL) | BIT_MASK(SND_TONE);
161 input_dev->event = snd_hda_beep_event;
162 input_set_drvdata(input_dev, beep);
163
164 beep->dev = input_dev;
165 return 0;
166}
167
168/** 130/**
169 * snd_hda_enable_beep_device - Turn on/off beep sound 131 * snd_hda_enable_beep_device - Turn on/off beep sound
170 * @codec: the HDA codec 132 * @codec: the HDA codec
@@ -186,6 +148,38 @@ int snd_hda_enable_beep_device(struct hda_codec *codec, int enable)
186} 148}
187EXPORT_SYMBOL_GPL(snd_hda_enable_beep_device); 149EXPORT_SYMBOL_GPL(snd_hda_enable_beep_device);
188 150
151static int beep_dev_register(struct snd_device *device)
152{
153 struct hda_beep *beep = device->device_data;
154 int err;
155
156 err = input_register_device(beep->dev);
157 if (!err)
158 beep->registered = true;
159 return err;
160}
161
162static int beep_dev_disconnect(struct snd_device *device)
163{
164 struct hda_beep *beep = device->device_data;
165
166 if (beep->registered)
167 input_unregister_device(beep->dev);
168 else
169 input_free_device(beep->dev);
170 turn_off_beep(beep);
171 return 0;
172}
173
174static int beep_dev_free(struct snd_device *device)
175{
176 struct hda_beep *beep = device->device_data;
177
178 beep->codec->beep = NULL;
179 kfree(beep);
180 return 0;
181}
182
189/** 183/**
190 * snd_hda_attach_beep_device - Attach a beep input device 184 * snd_hda_attach_beep_device - Attach a beep input device
191 * @codec: the HDA codec 185 * @codec: the HDA codec
@@ -194,14 +188,16 @@ EXPORT_SYMBOL_GPL(snd_hda_enable_beep_device);
194 * Attach a beep object to the given widget. If beep hint is turned off 188 * Attach a beep object to the given widget. If beep hint is turned off
195 * explicitly or beep_mode of the codec is turned off, this doesn't nothing. 189 * explicitly or beep_mode of the codec is turned off, this doesn't nothing.
196 * 190 *
197 * The attached beep device has to be registered via
198 * snd_hda_register_beep_device() and released via snd_hda_detach_beep_device()
199 * appropriately.
200 *
201 * Currently, only one beep device is allowed to each codec. 191 * Currently, only one beep device is allowed to each codec.
202 */ 192 */
203int snd_hda_attach_beep_device(struct hda_codec *codec, int nid) 193int snd_hda_attach_beep_device(struct hda_codec *codec, int nid)
204{ 194{
195 static struct snd_device_ops ops = {
196 .dev_register = beep_dev_register,
197 .dev_disconnect = beep_dev_disconnect,
198 .dev_free = beep_dev_free,
199 };
200 struct input_dev *input_dev;
205 struct hda_beep *beep; 201 struct hda_beep *beep;
206 int err; 202 int err;
207 203
@@ -226,14 +222,41 @@ int snd_hda_attach_beep_device(struct hda_codec *codec, int nid)
226 INIT_WORK(&beep->beep_work, &snd_hda_generate_beep); 222 INIT_WORK(&beep->beep_work, &snd_hda_generate_beep);
227 mutex_init(&beep->mutex); 223 mutex_init(&beep->mutex);
228 224
229 err = snd_hda_do_attach(beep); 225 input_dev = input_allocate_device();
230 if (err < 0) { 226 if (!input_dev) {
231 kfree(beep); 227 err = -ENOMEM;
232 codec->beep = NULL; 228 goto err_free;
233 return err;
234 } 229 }
235 230
231 /* setup digital beep device */
232 input_dev->name = "HDA Digital PCBeep";
233 input_dev->phys = beep->phys;
234 input_dev->id.bustype = BUS_PCI;
235 input_dev->dev.parent = &codec->card->card_dev;
236
237 input_dev->id.vendor = codec->core.vendor_id >> 16;
238 input_dev->id.product = codec->core.vendor_id & 0xffff;
239 input_dev->id.version = 0x01;
240
241 input_dev->evbit[0] = BIT_MASK(EV_SND);
242 input_dev->sndbit[0] = BIT_MASK(SND_BELL) | BIT_MASK(SND_TONE);
243 input_dev->event = snd_hda_beep_event;
244 input_set_drvdata(input_dev, beep);
245
246 beep->dev = input_dev;
247
248 err = snd_device_new(codec->card, SNDRV_DEV_JACK, beep, &ops);
249 if (err < 0)
250 goto err_input;
251
236 return 0; 252 return 0;
253
254 err_input:
255 input_free_device(beep->dev);
256 err_free:
257 kfree(beep);
258 codec->beep = NULL;
259 return err;
237} 260}
238EXPORT_SYMBOL_GPL(snd_hda_attach_beep_device); 261EXPORT_SYMBOL_GPL(snd_hda_attach_beep_device);
239 262
@@ -243,41 +266,11 @@ EXPORT_SYMBOL_GPL(snd_hda_attach_beep_device);
243 */ 266 */
244void snd_hda_detach_beep_device(struct hda_codec *codec) 267void snd_hda_detach_beep_device(struct hda_codec *codec)
245{ 268{
246 struct hda_beep *beep = codec->beep; 269 if (!codec->bus->shutdown && codec->beep)
247 if (beep) { 270 snd_device_free(codec->card, codec->beep);
248 if (beep->dev)
249 snd_hda_do_detach(beep);
250 codec->beep = NULL;
251 kfree(beep);
252 }
253} 271}
254EXPORT_SYMBOL_GPL(snd_hda_detach_beep_device); 272EXPORT_SYMBOL_GPL(snd_hda_detach_beep_device);
255 273
256/**
257 * snd_hda_register_beep_device - Register the beep device
258 * @codec: the HDA codec
259 */
260int snd_hda_register_beep_device(struct hda_codec *codec)
261{
262 struct hda_beep *beep = codec->beep;
263 int err;
264
265 if (!beep || !beep->dev)
266 return 0;
267
268 err = input_register_device(beep->dev);
269 if (err < 0) {
270 codec_err(codec, "hda_beep: unable to register input device\n");
271 input_free_device(beep->dev);
272 codec->beep = NULL;
273 kfree(beep);
274 return err;
275 }
276 beep->registered = true;
277 return 0;
278}
279EXPORT_SYMBOL_GPL(snd_hda_register_beep_device);
280
281static bool ctl_has_mute(struct snd_kcontrol *kcontrol) 274static bool ctl_has_mute(struct snd_kcontrol *kcontrol)
282{ 275{
283 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 276 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
diff --git a/sound/pci/hda/hda_beep.h b/sound/pci/hda/hda_beep.h
index f1457c6b3969..a25358a4807a 100644
--- a/sound/pci/hda/hda_beep.h
+++ b/sound/pci/hda/hda_beep.h
@@ -34,7 +34,6 @@ struct hda_beep {
34int snd_hda_enable_beep_device(struct hda_codec *codec, int enable); 34int snd_hda_enable_beep_device(struct hda_codec *codec, int enable);
35int snd_hda_attach_beep_device(struct hda_codec *codec, int nid); 35int snd_hda_attach_beep_device(struct hda_codec *codec, int nid);
36void snd_hda_detach_beep_device(struct hda_codec *codec); 36void snd_hda_detach_beep_device(struct hda_codec *codec);
37int snd_hda_register_beep_device(struct hda_codec *codec);
38#else 37#else
39static inline int snd_hda_attach_beep_device(struct hda_codec *codec, int nid) 38static inline int snd_hda_attach_beep_device(struct hda_codec *codec, int nid)
40{ 39{
@@ -43,9 +42,5 @@ static inline int snd_hda_attach_beep_device(struct hda_codec *codec, int nid)
43static inline void snd_hda_detach_beep_device(struct hda_codec *codec) 42static inline void snd_hda_detach_beep_device(struct hda_codec *codec)
44{ 43{
45} 44}
46static inline int snd_hda_register_beep_device(struct hda_codec *codec)
47{
48 return 0;
49}
50#endif 45#endif
51#endif 46#endif
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index dc7b342f00ef..5f2005098a60 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -813,7 +813,6 @@ void snd_hda_codec_register(struct hda_codec *codec)
813 if (codec->registered) 813 if (codec->registered)
814 return; 814 return;
815 if (device_is_registered(hda_codec_dev(codec))) { 815 if (device_is_registered(hda_codec_dev(codec))) {
816 snd_hda_register_beep_device(codec);
817 codec_display_power(codec, true); 816 codec_display_power(codec, true);
818 pm_runtime_enable(hda_codec_dev(codec)); 817 pm_runtime_enable(hda_codec_dev(codec));
819 /* it was powered up in snd_hda_codec_new(), now all done */ 818 /* it was powered up in snd_hda_codec_new(), now all done */
@@ -828,14 +827,6 @@ static int snd_hda_codec_dev_register(struct snd_device *device)
828 return 0; 827 return 0;
829} 828}
830 829
831static int snd_hda_codec_dev_disconnect(struct snd_device *device)
832{
833 struct hda_codec *codec = device->device_data;
834
835 snd_hda_detach_beep_device(codec);
836 return 0;
837}
838
839static int snd_hda_codec_dev_free(struct snd_device *device) 830static int snd_hda_codec_dev_free(struct snd_device *device)
840{ 831{
841 struct hda_codec *codec = device->device_data; 832 struct hda_codec *codec = device->device_data;
@@ -921,7 +912,6 @@ int snd_hda_codec_device_new(struct hda_bus *bus, struct snd_card *card,
921 int err; 912 int err;
922 static struct snd_device_ops dev_ops = { 913 static struct snd_device_ops dev_ops = {
923 .dev_register = snd_hda_codec_dev_register, 914 .dev_register = snd_hda_codec_dev_register,
924 .dev_disconnect = snd_hda_codec_dev_disconnect,
925 .dev_free = snd_hda_codec_dev_free, 915 .dev_free = snd_hda_codec_dev_free,
926 }; 916 };
927 917