@@ -50,11 +50,19 @@ static const struct reg_sequence cs35l56_hda_dai_config[] = {
50
50
51
51
};
52
52
53
+ static void cs35l56_hda_wait_dsp_ready (struct cs35l56_hda * cs35l56 )
54
+ {
55
+ /* Wait for patching to complete */
56
+ flush_work (& cs35l56 -> dsp_work );
57
+ }
58
+
53
59
static void cs35l56_hda_play (struct cs35l56_hda * cs35l56 )
54
60
{
55
61
unsigned int val ;
56
62
int ret ;
57
63
64
+ cs35l56_hda_wait_dsp_ready (cs35l56 );
65
+
58
66
pm_runtime_get_sync (cs35l56 -> base .dev );
59
67
ret = cs35l56_mbox_send (& cs35l56 -> base , CS35L56_MBOX_CMD_AUDIO_PLAY );
60
68
if (ret == 0 ) {
@@ -180,6 +188,8 @@ static int cs35l56_hda_mixer_get(struct snd_kcontrol *kcontrol,
180
188
unsigned int reg_val ;
181
189
int i ;
182
190
191
+ cs35l56_hda_wait_dsp_ready (cs35l56 );
192
+
183
193
regmap_read (cs35l56 -> base .regmap , kcontrol -> private_value , & reg_val );
184
194
reg_val &= CS35L56_ASP_TXn_SRC_MASK ;
185
195
@@ -203,6 +213,8 @@ static int cs35l56_hda_mixer_put(struct snd_kcontrol *kcontrol,
203
213
if (item >= CS35L56_NUM_INPUT_SRC )
204
214
return - EINVAL ;
205
215
216
+ cs35l56_hda_wait_dsp_ready (cs35l56 );
217
+
206
218
regmap_update_bits_check (cs35l56 -> base .regmap , kcontrol -> private_value ,
207
219
CS35L56_INPUT_MASK , cs35l56_tx_input_values [item ],
208
220
& changed );
@@ -227,6 +239,8 @@ static int cs35l56_hda_posture_get(struct snd_kcontrol *kcontrol,
227
239
unsigned int pos ;
228
240
int ret ;
229
241
242
+ cs35l56_hda_wait_dsp_ready (cs35l56 );
243
+
230
244
ret = regmap_read (cs35l56 -> base .regmap , CS35L56_MAIN_POSTURE_NUMBER , & pos );
231
245
if (ret )
232
246
return ret ;
@@ -248,6 +262,8 @@ static int cs35l56_hda_posture_put(struct snd_kcontrol *kcontrol,
248
262
(pos > CS35L56_MAIN_POSTURE_MAX ))
249
263
return - EINVAL ;
250
264
265
+ cs35l56_hda_wait_dsp_ready (cs35l56 );
266
+
251
267
ret = regmap_update_bits_check (cs35l56 -> base .regmap ,
252
268
CS35L56_MAIN_POSTURE_NUMBER ,
253
269
CS35L56_MAIN_POSTURE_MASK ,
@@ -291,6 +307,8 @@ static int cs35l56_hda_vol_get(struct snd_kcontrol *kcontrol,
291
307
int vol ;
292
308
int ret ;
293
309
310
+ cs35l56_hda_wait_dsp_ready (cs35l56 );
311
+
294
312
ret = regmap_read (cs35l56 -> base .regmap , CS35L56_MAIN_RENDER_USER_VOLUME , & raw_vol );
295
313
296
314
if (ret )
@@ -323,6 +341,8 @@ static int cs35l56_hda_vol_put(struct snd_kcontrol *kcontrol,
323
341
raw_vol = (vol + CS35L56_MAIN_RENDER_USER_VOLUME_MIN ) <<
324
342
CS35L56_MAIN_RENDER_USER_VOLUME_SHIFT ;
325
343
344
+ cs35l56_hda_wait_dsp_ready (cs35l56 );
345
+
326
346
ret = regmap_update_bits_check (cs35l56 -> base .regmap ,
327
347
CS35L56_MAIN_RENDER_USER_VOLUME ,
328
348
CS35L56_MAIN_RENDER_USER_VOLUME_MASK ,
@@ -539,8 +559,9 @@ static void cs35l56_hda_release_firmware_files(const struct firmware *wmfw_firmw
539
559
kfree (coeff_filename );
540
560
}
541
561
542
- static void cs35l56_hda_add_dsp_controls (struct cs35l56_hda * cs35l56 )
562
+ static void cs35l56_hda_create_dsp_controls_work (struct work_struct * work )
543
563
{
564
+ struct cs35l56_hda * cs35l56 = container_of (work , struct cs35l56_hda , control_work );
544
565
struct hda_cs_dsp_ctl_info info ;
545
566
546
567
info .device_name = cs35l56 -> amp_name ;
@@ -566,23 +587,42 @@ static void cs35l56_hda_apply_calibration(struct cs35l56_hda *cs35l56)
566
587
dev_info (cs35l56 -> base .dev , "Calibration applied\n" );
567
588
}
568
589
569
- static int cs35l56_hda_fw_load (struct cs35l56_hda * cs35l56 )
590
+ static void cs35l56_hda_fw_load (struct cs35l56_hda * cs35l56 )
570
591
{
571
592
const struct firmware * coeff_firmware = NULL ;
572
593
const struct firmware * wmfw_firmware = NULL ;
573
594
char * coeff_filename = NULL ;
574
595
char * wmfw_filename = NULL ;
575
596
unsigned int preloaded_fw_ver ;
576
597
bool firmware_missing ;
577
- int ret = 0 ;
598
+ bool add_dsp_controls_required = false;
599
+ int ret ;
600
+
601
+ /*
602
+ * control_work must be flushed before proceeding, but we can't do that
603
+ * here as it would create a deadlock on controls_rwsem so it must be
604
+ * performed before queuing dsp_work.
605
+ */
606
+ WARN_ON_ONCE (work_busy (& cs35l56 -> control_work ));
578
607
579
- /* Prepare for a new DSP power-up */
608
+ /*
609
+ * Prepare for a new DSP power-up. If the DSP has had firmware
610
+ * downloaded previously then it needs to be powered down so that it
611
+ * can be updated and if hadn't been patched before then the controls
612
+ * will need to be added once firmware download succeeds.
613
+ */
580
614
if (cs35l56 -> base .fw_patched )
581
615
cs_dsp_power_down (& cs35l56 -> cs_dsp );
616
+ else
617
+ add_dsp_controls_required = true;
582
618
583
619
cs35l56 -> base .fw_patched = false;
584
620
585
- pm_runtime_get_sync (cs35l56 -> base .dev );
621
+ ret = pm_runtime_resume_and_get (cs35l56 -> base .dev );
622
+ if (ret < 0 ) {
623
+ dev_err (cs35l56 -> base .dev , "Failed to resume and get %d\n" , ret );
624
+ return ;
625
+ }
586
626
587
627
/*
588
628
* The firmware can only be upgraded if it is currently running
@@ -606,7 +646,6 @@ static int cs35l56_hda_fw_load(struct cs35l56_hda *cs35l56)
606
646
*/
607
647
if (!coeff_firmware && firmware_missing ) {
608
648
dev_err (cs35l56 -> base .dev , ".bin file required but not found\n" );
609
- ret = - ENOENT ;
610
649
goto err_fw_release ;
611
650
}
612
651
@@ -659,6 +698,15 @@ static int cs35l56_hda_fw_load(struct cs35l56_hda *cs35l56)
659
698
CS35L56_FIRMWARE_MISSING );
660
699
cs35l56 -> base .fw_patched = true;
661
700
701
+ /*
702
+ * Adding controls is deferred to prevent a lock inversion - ALSA takes
703
+ * the controls_rwsem when adding a control, the get() / put()
704
+ * functions of a control are called holding controls_rwsem and those
705
+ * that depend on running firmware wait for dsp_work() to complete.
706
+ */
707
+ if (add_dsp_controls_required )
708
+ queue_work (system_long_wq , & cs35l56 -> control_work );
709
+
662
710
ret = cs_dsp_run (& cs35l56 -> cs_dsp );
663
711
if (ret )
664
712
dev_dbg (cs35l56 -> base .dev , "%s: cs_dsp_run ret %d\n" , __func__ , ret );
@@ -678,16 +726,20 @@ static int cs35l56_hda_fw_load(struct cs35l56_hda *cs35l56)
678
726
coeff_firmware , coeff_filename );
679
727
err_pm_put :
680
728
pm_runtime_put (cs35l56 -> base .dev );
729
+ }
681
730
682
- return ret ;
731
+ static void cs35l56_hda_dsp_work (struct work_struct * work )
732
+ {
733
+ struct cs35l56_hda * cs35l56 = container_of (work , struct cs35l56_hda , dsp_work );
734
+
735
+ cs35l56_hda_fw_load (cs35l56 );
683
736
}
684
737
685
738
static int cs35l56_hda_bind (struct device * dev , struct device * master , void * master_data )
686
739
{
687
740
struct cs35l56_hda * cs35l56 = dev_get_drvdata (dev );
688
741
struct hda_component_parent * parent = master_data ;
689
742
struct hda_component * comp ;
690
- int ret ;
691
743
692
744
comp = hda_component_from_index (parent , cs35l56 -> index );
693
745
if (!comp )
@@ -701,12 +753,10 @@ static int cs35l56_hda_bind(struct device *dev, struct device *master, void *mas
701
753
strscpy (comp -> name , dev_name (dev ), sizeof (comp -> name ));
702
754
comp -> playback_hook = cs35l56_hda_playback_hook ;
703
755
704
- ret = cs35l56_hda_fw_load (cs35l56 );
705
- if (ret )
706
- return ret ;
756
+ flush_work (& cs35l56 -> control_work );
757
+ queue_work (system_long_wq , & cs35l56 -> dsp_work );
707
758
708
759
cs35l56_hda_create_controls (cs35l56 );
709
- cs35l56_hda_add_dsp_controls (cs35l56 );
710
760
711
761
#if IS_ENABLED (CONFIG_SND_DEBUG )
712
762
cs35l56 -> debugfs_root = debugfs_create_dir (dev_name (cs35l56 -> base .dev ), sound_debugfs_root );
@@ -724,6 +774,9 @@ static void cs35l56_hda_unbind(struct device *dev, struct device *master, void *
724
774
struct hda_component_parent * parent = master_data ;
725
775
struct hda_component * comp ;
726
776
777
+ cancel_work_sync (& cs35l56 -> dsp_work );
778
+ cancel_work_sync (& cs35l56 -> control_work );
779
+
727
780
cs35l56_hda_remove_controls (cs35l56 );
728
781
729
782
#if IS_ENABLED (CONFIG_SND_DEBUG )
@@ -752,6 +805,9 @@ static int cs35l56_hda_system_suspend(struct device *dev)
752
805
{
753
806
struct cs35l56_hda * cs35l56 = dev_get_drvdata (dev );
754
807
808
+ cs35l56_hda_wait_dsp_ready (cs35l56 );
809
+ flush_work (& cs35l56 -> control_work );
810
+
755
811
if (cs35l56 -> playing )
756
812
cs35l56_hda_pause (cs35l56 );
757
813
@@ -850,11 +906,8 @@ static int cs35l56_hda_system_resume(struct device *dev)
850
906
851
907
ret = cs35l56_is_fw_reload_needed (& cs35l56 -> base );
852
908
dev_dbg (cs35l56 -> base .dev , "fw_reload_needed: %d\n" , ret );
853
- if (ret > 0 ) {
854
- ret = cs35l56_hda_fw_load (cs35l56 );
855
- if (ret )
856
- return ret ;
857
- }
909
+ if (ret > 0 )
910
+ queue_work (system_long_wq , & cs35l56 -> dsp_work );
858
911
859
912
if (cs35l56 -> playing )
860
913
cs35l56_hda_play (cs35l56 );
@@ -972,6 +1025,9 @@ int cs35l56_hda_common_probe(struct cs35l56_hda *cs35l56, int hid, int id)
972
1025
mutex_init (& cs35l56 -> base .irq_lock );
973
1026
dev_set_drvdata (cs35l56 -> base .dev , cs35l56 );
974
1027
1028
+ INIT_WORK (& cs35l56 -> dsp_work , cs35l56_hda_dsp_work );
1029
+ INIT_WORK (& cs35l56 -> control_work , cs35l56_hda_create_dsp_controls_work );
1030
+
975
1031
ret = cs35l56_hda_read_acpi (cs35l56 , hid , id );
976
1032
if (ret )
977
1033
goto err ;
0 commit comments