hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/sound/hda/hdac_device.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * HD-audio codec core device
34 */
....@@ -19,7 +20,7 @@
1920
2021 static void default_release(struct device *dev)
2122 {
22
- snd_hdac_device_exit(container_of(dev, struct hdac_device, dev));
23
+ snd_hdac_device_exit(dev_to_hdac_dev(dev));
2324 }
2425
2526 /**
....@@ -55,6 +56,8 @@
5556 codec->bus = bus;
5657 codec->addr = addr;
5758 codec->type = HDA_DEV_CORE;
59
+ mutex_init(&codec->widget_lock);
60
+ mutex_init(&codec->regmap_lock);
5861 pm_runtime_set_active(&codec->dev);
5962 pm_runtime_get_noresume(&codec->dev);
6063 atomic_set(&codec->in_pm, 0);
....@@ -88,7 +91,7 @@
8891
8992 fg = codec->afg ? codec->afg : codec->mfg;
9093
91
- err = snd_hdac_refresh_widgets(codec, false);
94
+ err = snd_hdac_refresh_widgets(codec);
9295 if (err < 0)
9396 goto error;
9497
....@@ -134,7 +137,7 @@
134137
135138 /**
136139 * snd_hdac_device_register - register the hd-audio codec base device
137
- * codec: the device to register
140
+ * @codec: the device to register
138141 */
139142 int snd_hdac_device_register(struct hdac_device *codec)
140143 {
....@@ -143,7 +146,9 @@
143146 err = device_add(&codec->dev);
144147 if (err < 0)
145148 return err;
149
+ mutex_lock(&codec->widget_lock);
146150 err = hda_widget_sysfs_init(codec);
151
+ mutex_unlock(&codec->widget_lock);
147152 if (err < 0) {
148153 device_del(&codec->dev);
149154 return err;
....@@ -155,12 +160,14 @@
155160
156161 /**
157162 * snd_hdac_device_unregister - unregister the hd-audio codec base device
158
- * codec: the device to unregister
163
+ * @codec: the device to unregister
159164 */
160165 void snd_hdac_device_unregister(struct hdac_device *codec)
161166 {
162167 if (device_is_registered(&codec->dev)) {
168
+ mutex_lock(&codec->widget_lock);
163169 hda_widget_sysfs_exit(codec);
170
+ mutex_unlock(&codec->widget_lock);
164171 device_del(&codec->dev);
165172 snd_hdac_bus_remove_device(codec->bus, codec);
166173 }
....@@ -199,7 +206,7 @@
199206 */
200207 int snd_hdac_codec_modalias(struct hdac_device *codec, char *buf, size_t size)
201208 {
202
- return snprintf(buf, size, "hdaudio:v%08Xr%08Xa%02X\n",
209
+ return scnprintf(buf, size, "hdaudio:v%08Xr%08Xa%02X\n",
203210 codec->vendor_id, codec->revision_id, codec->type);
204211 }
205212 EXPORT_SYMBOL_GPL(snd_hdac_codec_modalias);
....@@ -214,8 +221,8 @@
214221 *
215222 * Return an encoded command verb or -1 for error.
216223 */
217
-unsigned int snd_hdac_make_cmd(struct hdac_device *codec, hda_nid_t nid,
218
- unsigned int verb, unsigned int parm)
224
+static unsigned int snd_hdac_make_cmd(struct hdac_device *codec, hda_nid_t nid,
225
+ unsigned int verb, unsigned int parm)
219226 {
220227 u32 val, addr;
221228
....@@ -233,7 +240,6 @@
233240 val |= parm;
234241 return val;
235242 }
236
-EXPORT_SYMBOL_GPL(snd_hdac_make_cmd);
237243
238244 /**
239245 * snd_hdac_exec_verb - execute an encoded verb
....@@ -254,7 +260,6 @@
254260 return codec->exec_verb(codec, cmd, flags, res);
255261 return snd_hdac_bus_exec_verb(codec->bus, codec->addr, cmd, res);
256262 }
257
-EXPORT_SYMBOL_GPL(snd_hdac_exec_verb);
258263
259264
260265 /**
....@@ -278,6 +283,10 @@
278283
279284 /**
280285 * _snd_hdac_read_parm - read a parmeter
286
+ * @codec: the codec object
287
+ * @nid: NID to read a parameter
288
+ * @parm: parameter to read
289
+ * @res: pointer to store the read value
281290 *
282291 * This function returns zero or an error unlike snd_hdac_read_parm().
283292 */
....@@ -391,30 +400,35 @@
391400 /**
392401 * snd_hdac_refresh_widgets - Reset the widget start/end nodes
393402 * @codec: the codec object
394
- * @sysfs: re-initialize sysfs tree, too
395403 */
396
-int snd_hdac_refresh_widgets(struct hdac_device *codec, bool sysfs)
404
+int snd_hdac_refresh_widgets(struct hdac_device *codec)
397405 {
398406 hda_nid_t start_nid;
399
- int nums, err;
407
+ int nums, err = 0;
400408
409
+ /*
410
+ * Serialize against multiple threads trying to update the sysfs
411
+ * widgets array.
412
+ */
413
+ mutex_lock(&codec->widget_lock);
401414 nums = snd_hdac_get_sub_nodes(codec, codec->afg, &start_nid);
402415 if (!start_nid || nums <= 0 || nums >= 0xff) {
403416 dev_err(&codec->dev, "cannot read sub nodes for FG 0x%02x\n",
404417 codec->afg);
405
- return -EINVAL;
418
+ err = -EINVAL;
419
+ goto unlock;
406420 }
407421
408
- if (sysfs) {
409
- err = hda_widget_sysfs_reinit(codec, start_nid, nums);
410
- if (err < 0)
411
- return err;
412
- }
422
+ err = hda_widget_sysfs_reinit(codec, start_nid, nums);
423
+ if (err < 0)
424
+ goto unlock;
413425
414426 codec->num_nodes = nums;
415427 codec->start_nid = start_nid;
416428 codec->end_nid = start_nid + nums;
417
- return 0;
429
+unlock:
430
+ mutex_unlock(&codec->widget_lock);
431
+ return err;
418432 }
419433 EXPORT_SYMBOL_GPL(snd_hdac_refresh_widgets);
420434
....@@ -597,7 +611,7 @@
597611 int snd_hdac_keep_power_up(struct hdac_device *codec)
598612 {
599613 if (!atomic_inc_not_zero(&codec->in_pm)) {
600
- int ret = pm_runtime_get_if_in_use(&codec->dev);
614
+ int ret = pm_runtime_get_if_active(&codec->dev, true);
601615 if (!ret)
602616 return -1;
603617 if (ret < 0)
....@@ -624,30 +638,13 @@
624638 EXPORT_SYMBOL_GPL(snd_hdac_power_down_pm);
625639 #endif
626640
627
-/**
628
- * snd_hdac_link_power - Enable/disable the link power for a codec
629
- * @codec: the codec object
630
- * @bool: enable or disable the link power
631
- */
632
-int snd_hdac_link_power(struct hdac_device *codec, bool enable)
633
-{
634
- if (!codec->link_power_control)
635
- return 0;
636
-
637
- if (codec->bus->ops->link_power)
638
- return codec->bus->ops->link_power(codec->bus, enable);
639
- else
640
- return -EINVAL;
641
-}
642
-EXPORT_SYMBOL_GPL(snd_hdac_link_power);
643
-
644641 /* codec vendor labels */
645642 struct hda_vendor_id {
646643 unsigned int id;
647644 const char *name;
648645 };
649646
650
-static struct hda_vendor_id hda_vendor_ids[] = {
647
+static const struct hda_vendor_id hda_vendor_ids[] = {
651648 { 0x1002, "ATI" },
652649 { 0x1013, "Cirrus Logic" },
653650 { 0x1057, "Motorola" },
....@@ -663,6 +660,7 @@
663660 { 0x14f1, "Conexant" },
664661 { 0x17e8, "Chrontel" },
665662 { 0x1854, "LG" },
663
+ { 0x19e5, "Huawei" },
666664 { 0x1aec, "Wolfson Microelectronics" },
667665 { 0x1af4, "QEMU" },
668666 { 0x434d, "C-Media" },
....@@ -702,7 +700,7 @@
702700 (AC_FMT_BASE_##base##K | (((mult) - 1) << AC_FMT_MULT_SHIFT) | \
703701 (((div) - 1) << AC_FMT_DIV_SHIFT))
704702
705
-static struct hda_rate_tbl rate_bits[] = {
703
+static const struct hda_rate_tbl rate_bits[] = {
706704 /* rate in Hz, ALSA rate bitmask, HDA format value */
707705
708706 /* autodetected value used in snd_hda_query_supported_pcm */
....@@ -1071,9 +1069,9 @@
10711069 * snd_hdac_sync_power_state - wait until actual power state matches
10721070 * with the target state
10731071 *
1074
- * @hdac: the HDAC device
1072
+ * @codec: the HDAC device
10751073 * @nid: NID to send the command
1076
- * @target_state: target state to check for
1074
+ * @power_state: target power state to wait for
10771075 *
10781076 * Return power state or PS_ERROR if codec rejects GET verb.
10791077 */