aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-01-22 14:53:56 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2016-01-22 14:53:56 -0500
commite7cc3edd1758f9aab39f5afcd988ffed55cb26ca (patch)
tree25baf439dbaeebc5cbc7229f03bcdbb4406c1395 /sound
parent2101ae42899a14fe7caa73114e2161e778328661 (diff)
parent40ed9444cd2421cceedb35bb8d8ff913a5ae1ac3 (diff)
Merge tag 'sound-fix-4.5-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
Pull sound fixes from Takashi Iwai: "Here are lots of small fixes that have been collected since the previous pull. This time, not only trivial ones but fixes for some serious bugs are included: - Fix for CPU lockups by snd-hrtimer accesses - Fix for unsafe disconnection handling in ALSA timer code - Fix for Oops due to race at HD-audio module removal - Fixes for possible memory corruption via 32bit PCM and sequencer compat ioctls - Fix for regression in HD-audio generic model handling - Suppress kernel warnings for invalid TLV ioctls that may flood up - Fix the missing SSC clock handling for at73c213 - A pin fixup for ASUS N550JX" * tag 'sound-fix-4.5-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: ALSA: timer: Introduce disconnect op to snd_timer_instance ALSA: timer: Handle disconnection more safely ALSA: hda - Flush the pending probe work at remove ALSA: hda - Fix missing module loading with model=generic option ALSA: hda - Degrade i915 binding failure message ALSA: at73c213: manage SSC clock ALSA: control: Avoid kernel warnings from tlv ioctl with numid 0 ALSA: seq: Fix snd_seq_call_port_info_ioctl in compat mode ALSA: pcm: Fix snd_pcm_hw_params struct copy in compat mode ALSA: hrtimer: Fix stall by hrtimer_cancel() ALSA: hda - Fix bass pin fixup for ASUS N550JX
Diffstat (limited to 'sound')
-rw-r--r--sound/core/control.c2
-rw-r--r--sound/core/hrtimer.c3
-rw-r--r--sound/core/pcm_compat.c13
-rw-r--r--sound/core/seq/seq_compat.c9
-rw-r--r--sound/core/timer.c47
-rw-r--r--sound/hda/hdac_i915.c2
-rw-r--r--sound/pci/hda/hda_bind.c42
-rw-r--r--sound/pci/hda/hda_intel.c16
-rw-r--r--sound/pci/hda/patch_realtek.c1
-rw-r--r--sound/spi/at73c213.c11
10 files changed, 123 insertions, 23 deletions
diff --git a/sound/core/control.c b/sound/core/control.c
index 196a6fe100ca..a85d45595d02 100644
--- a/sound/core/control.c
+++ b/sound/core/control.c
@@ -1405,6 +1405,8 @@ static int snd_ctl_tlv_ioctl(struct snd_ctl_file *file,
1405 return -EFAULT; 1405 return -EFAULT;
1406 if (tlv.length < sizeof(unsigned int) * 2) 1406 if (tlv.length < sizeof(unsigned int) * 2)
1407 return -EINVAL; 1407 return -EINVAL;
1408 if (!tlv.numid)
1409 return -EINVAL;
1408 down_read(&card->controls_rwsem); 1410 down_read(&card->controls_rwsem);
1409 kctl = snd_ctl_find_numid(card, tlv.numid); 1411 kctl = snd_ctl_find_numid(card, tlv.numid);
1410 if (kctl == NULL) { 1412 if (kctl == NULL) {
diff --git a/sound/core/hrtimer.c b/sound/core/hrtimer.c
index f845ecf7e172..656d9a9032dc 100644
--- a/sound/core/hrtimer.c
+++ b/sound/core/hrtimer.c
@@ -90,7 +90,7 @@ static int snd_hrtimer_start(struct snd_timer *t)
90 struct snd_hrtimer *stime = t->private_data; 90 struct snd_hrtimer *stime = t->private_data;
91 91
92 atomic_set(&stime->running, 0); 92 atomic_set(&stime->running, 0);
93 hrtimer_cancel(&stime->hrt); 93 hrtimer_try_to_cancel(&stime->hrt);
94 hrtimer_start(&stime->hrt, ns_to_ktime(t->sticks * resolution), 94 hrtimer_start(&stime->hrt, ns_to_ktime(t->sticks * resolution),
95 HRTIMER_MODE_REL); 95 HRTIMER_MODE_REL);
96 atomic_set(&stime->running, 1); 96 atomic_set(&stime->running, 1);
@@ -101,6 +101,7 @@ static int snd_hrtimer_stop(struct snd_timer *t)
101{ 101{
102 struct snd_hrtimer *stime = t->private_data; 102 struct snd_hrtimer *stime = t->private_data;
103 atomic_set(&stime->running, 0); 103 atomic_set(&stime->running, 0);
104 hrtimer_try_to_cancel(&stime->hrt);
104 return 0; 105 return 0;
105} 106}
106 107
diff --git a/sound/core/pcm_compat.c b/sound/core/pcm_compat.c
index b48b434444ed..9630e9f72b7b 100644
--- a/sound/core/pcm_compat.c
+++ b/sound/core/pcm_compat.c
@@ -255,10 +255,15 @@ static int snd_pcm_ioctl_hw_params_compat(struct snd_pcm_substream *substream,
255 if (! (runtime = substream->runtime)) 255 if (! (runtime = substream->runtime))
256 return -ENOTTY; 256 return -ENOTTY;
257 257
258 /* only fifo_size is different, so just copy all */ 258 data = kmalloc(sizeof(*data), GFP_KERNEL);
259 data = memdup_user(data32, sizeof(*data32)); 259 if (!data)
260 if (IS_ERR(data)) 260 return -ENOMEM;
261 return PTR_ERR(data); 261
262 /* only fifo_size (RO from userspace) is different, so just copy all */
263 if (copy_from_user(data, data32, sizeof(*data32))) {
264 err = -EFAULT;
265 goto error;
266 }
262 267
263 if (refine) 268 if (refine)
264 err = snd_pcm_hw_refine(substream, data); 269 err = snd_pcm_hw_refine(substream, data);
diff --git a/sound/core/seq/seq_compat.c b/sound/core/seq/seq_compat.c
index 81f7c109dc46..65175902a68a 100644
--- a/sound/core/seq/seq_compat.c
+++ b/sound/core/seq/seq_compat.c
@@ -49,11 +49,12 @@ static int snd_seq_call_port_info_ioctl(struct snd_seq_client *client, unsigned
49 struct snd_seq_port_info *data; 49 struct snd_seq_port_info *data;
50 mm_segment_t fs; 50 mm_segment_t fs;
51 51
52 data = memdup_user(data32, sizeof(*data32)); 52 data = kmalloc(sizeof(*data), GFP_KERNEL);
53 if (IS_ERR(data)) 53 if (!data)
54 return PTR_ERR(data); 54 return -ENOMEM;
55 55
56 if (get_user(data->flags, &data32->flags) || 56 if (copy_from_user(data, data32, sizeof(*data32)) ||
57 get_user(data->flags, &data32->flags) ||
57 get_user(data->time_queue, &data32->time_queue)) 58 get_user(data->time_queue, &data32->time_queue))
58 goto error; 59 goto error;
59 data->kernel = NULL; 60 data->kernel = NULL;
diff --git a/sound/core/timer.c b/sound/core/timer.c
index cb25aded5349..af1f68f7e315 100644
--- a/sound/core/timer.c
+++ b/sound/core/timer.c
@@ -65,6 +65,7 @@ struct snd_timer_user {
65 int qtail; 65 int qtail;
66 int qused; 66 int qused;
67 int queue_size; 67 int queue_size;
68 bool disconnected;
68 struct snd_timer_read *queue; 69 struct snd_timer_read *queue;
69 struct snd_timer_tread *tqueue; 70 struct snd_timer_tread *tqueue;
70 spinlock_t qlock; 71 spinlock_t qlock;
@@ -290,6 +291,9 @@ int snd_timer_open(struct snd_timer_instance **ti,
290 mutex_unlock(&register_mutex); 291 mutex_unlock(&register_mutex);
291 return -ENOMEM; 292 return -ENOMEM;
292 } 293 }
294 /* take a card refcount for safe disconnection */
295 if (timer->card)
296 get_device(&timer->card->card_dev);
293 timeri->slave_class = tid->dev_sclass; 297 timeri->slave_class = tid->dev_sclass;
294 timeri->slave_id = slave_id; 298 timeri->slave_id = slave_id;
295 if (list_empty(&timer->open_list_head) && timer->hw.open) 299 if (list_empty(&timer->open_list_head) && timer->hw.open)
@@ -359,6 +363,9 @@ int snd_timer_close(struct snd_timer_instance *timeri)
359 } 363 }
360 spin_unlock(&timer->lock); 364 spin_unlock(&timer->lock);
361 spin_unlock_irq(&slave_active_lock); 365 spin_unlock_irq(&slave_active_lock);
366 /* release a card refcount for safe disconnection */
367 if (timer->card)
368 put_device(&timer->card->card_dev);
362 mutex_unlock(&register_mutex); 369 mutex_unlock(&register_mutex);
363 } 370 }
364 out: 371 out:
@@ -474,6 +481,8 @@ int snd_timer_start(struct snd_timer_instance *timeri, unsigned int ticks)
474 timer = timeri->timer; 481 timer = timeri->timer;
475 if (timer == NULL) 482 if (timer == NULL)
476 return -EINVAL; 483 return -EINVAL;
484 if (timer->card && timer->card->shutdown)
485 return -ENODEV;
477 spin_lock_irqsave(&timer->lock, flags); 486 spin_lock_irqsave(&timer->lock, flags);
478 timeri->ticks = timeri->cticks = ticks; 487 timeri->ticks = timeri->cticks = ticks;
479 timeri->pticks = 0; 488 timeri->pticks = 0;
@@ -505,6 +514,10 @@ static int _snd_timer_stop(struct snd_timer_instance *timeri, int event)
505 spin_lock_irqsave(&timer->lock, flags); 514 spin_lock_irqsave(&timer->lock, flags);
506 list_del_init(&timeri->ack_list); 515 list_del_init(&timeri->ack_list);
507 list_del_init(&timeri->active_list); 516 list_del_init(&timeri->active_list);
517 if (timer->card && timer->card->shutdown) {
518 spin_unlock_irqrestore(&timer->lock, flags);
519 return 0;
520 }
508 if ((timeri->flags & SNDRV_TIMER_IFLG_RUNNING) && 521 if ((timeri->flags & SNDRV_TIMER_IFLG_RUNNING) &&
509 !(--timer->running)) { 522 !(--timer->running)) {
510 timer->hw.stop(timer); 523 timer->hw.stop(timer);
@@ -565,6 +578,8 @@ int snd_timer_continue(struct snd_timer_instance *timeri)
565 timer = timeri->timer; 578 timer = timeri->timer;
566 if (! timer) 579 if (! timer)
567 return -EINVAL; 580 return -EINVAL;
581 if (timer->card && timer->card->shutdown)
582 return -ENODEV;
568 spin_lock_irqsave(&timer->lock, flags); 583 spin_lock_irqsave(&timer->lock, flags);
569 if (!timeri->cticks) 584 if (!timeri->cticks)
570 timeri->cticks = 1; 585 timeri->cticks = 1;
@@ -628,6 +643,9 @@ static void snd_timer_tasklet(unsigned long arg)
628 unsigned long resolution, ticks; 643 unsigned long resolution, ticks;
629 unsigned long flags; 644 unsigned long flags;
630 645
646 if (timer->card && timer->card->shutdown)
647 return;
648
631 spin_lock_irqsave(&timer->lock, flags); 649 spin_lock_irqsave(&timer->lock, flags);
632 /* now process all callbacks */ 650 /* now process all callbacks */
633 while (!list_empty(&timer->sack_list_head)) { 651 while (!list_empty(&timer->sack_list_head)) {
@@ -668,6 +686,9 @@ void snd_timer_interrupt(struct snd_timer * timer, unsigned long ticks_left)
668 if (timer == NULL) 686 if (timer == NULL)
669 return; 687 return;
670 688
689 if (timer->card && timer->card->shutdown)
690 return;
691
671 spin_lock_irqsave(&timer->lock, flags); 692 spin_lock_irqsave(&timer->lock, flags);
672 693
673 /* remember the current resolution */ 694 /* remember the current resolution */
@@ -881,8 +902,15 @@ static int snd_timer_dev_register(struct snd_device *dev)
881static int snd_timer_dev_disconnect(struct snd_device *device) 902static int snd_timer_dev_disconnect(struct snd_device *device)
882{ 903{
883 struct snd_timer *timer = device->device_data; 904 struct snd_timer *timer = device->device_data;
905 struct snd_timer_instance *ti;
906
884 mutex_lock(&register_mutex); 907 mutex_lock(&register_mutex);
885 list_del_init(&timer->device_list); 908 list_del_init(&timer->device_list);
909 /* wake up pending sleepers */
910 list_for_each_entry(ti, &timer->open_list_head, open_list) {
911 if (ti->disconnect)
912 ti->disconnect(ti);
913 }
886 mutex_unlock(&register_mutex); 914 mutex_unlock(&register_mutex);
887 return 0; 915 return 0;
888} 916}
@@ -893,6 +921,8 @@ void snd_timer_notify(struct snd_timer *timer, int event, struct timespec *tstam
893 unsigned long resolution = 0; 921 unsigned long resolution = 0;
894 struct snd_timer_instance *ti, *ts; 922 struct snd_timer_instance *ti, *ts;
895 923
924 if (timer->card && timer->card->shutdown)
925 return;
896 if (! (timer->hw.flags & SNDRV_TIMER_HW_SLAVE)) 926 if (! (timer->hw.flags & SNDRV_TIMER_HW_SLAVE))
897 return; 927 return;
898 if (snd_BUG_ON(event < SNDRV_TIMER_EVENT_MSTART || 928 if (snd_BUG_ON(event < SNDRV_TIMER_EVENT_MSTART ||
@@ -1051,6 +1081,8 @@ static void snd_timer_proc_read(struct snd_info_entry *entry,
1051 1081
1052 mutex_lock(&register_mutex); 1082 mutex_lock(&register_mutex);
1053 list_for_each_entry(timer, &snd_timer_list, device_list) { 1083 list_for_each_entry(timer, &snd_timer_list, device_list) {
1084 if (timer->card && timer->card->shutdown)
1085 continue;
1054 switch (timer->tmr_class) { 1086 switch (timer->tmr_class) {
1055 case SNDRV_TIMER_CLASS_GLOBAL: 1087 case SNDRV_TIMER_CLASS_GLOBAL:
1056 snd_iprintf(buffer, "G%i: ", timer->tmr_device); 1088 snd_iprintf(buffer, "G%i: ", timer->tmr_device);
@@ -1185,6 +1217,14 @@ static void snd_timer_user_ccallback(struct snd_timer_instance *timeri,
1185 wake_up(&tu->qchange_sleep); 1217 wake_up(&tu->qchange_sleep);
1186} 1218}
1187 1219
1220static void snd_timer_user_disconnect(struct snd_timer_instance *timeri)
1221{
1222 struct snd_timer_user *tu = timeri->callback_data;
1223
1224 tu->disconnected = true;
1225 wake_up(&tu->qchange_sleep);
1226}
1227
1188static void snd_timer_user_tinterrupt(struct snd_timer_instance *timeri, 1228static void snd_timer_user_tinterrupt(struct snd_timer_instance *timeri,
1189 unsigned long resolution, 1229 unsigned long resolution,
1190 unsigned long ticks) 1230 unsigned long ticks)
@@ -1558,6 +1598,7 @@ static int snd_timer_user_tselect(struct file *file,
1558 ? snd_timer_user_tinterrupt : snd_timer_user_interrupt; 1598 ? snd_timer_user_tinterrupt : snd_timer_user_interrupt;
1559 tu->timeri->ccallback = snd_timer_user_ccallback; 1599 tu->timeri->ccallback = snd_timer_user_ccallback;
1560 tu->timeri->callback_data = (void *)tu; 1600 tu->timeri->callback_data = (void *)tu;
1601 tu->timeri->disconnect = snd_timer_user_disconnect;
1561 } 1602 }
1562 1603
1563 __err: 1604 __err:
@@ -1876,6 +1917,10 @@ static ssize_t snd_timer_user_read(struct file *file, char __user *buffer,
1876 1917
1877 remove_wait_queue(&tu->qchange_sleep, &wait); 1918 remove_wait_queue(&tu->qchange_sleep, &wait);
1878 1919
1920 if (tu->disconnected) {
1921 err = -ENODEV;
1922 break;
1923 }
1879 if (signal_pending(current)) { 1924 if (signal_pending(current)) {
1880 err = -ERESTARTSYS; 1925 err = -ERESTARTSYS;
1881 break; 1926 break;
@@ -1925,6 +1970,8 @@ static unsigned int snd_timer_user_poll(struct file *file, poll_table * wait)
1925 mask = 0; 1970 mask = 0;
1926 if (tu->qused) 1971 if (tu->qused)
1927 mask |= POLLIN | POLLRDNORM; 1972 mask |= POLLIN | POLLRDNORM;
1973 if (tu->disconnected)
1974 mask |= POLLERR;
1928 1975
1929 return mask; 1976 return mask;
1930} 1977}
diff --git a/sound/hda/hdac_i915.c b/sound/hda/hdac_i915.c
index c50177fb469f..f6854dbd7d8d 100644
--- a/sound/hda/hdac_i915.c
+++ b/sound/hda/hdac_i915.c
@@ -306,7 +306,7 @@ out_master_del:
306out_err: 306out_err:
307 kfree(acomp); 307 kfree(acomp);
308 bus->audio_component = NULL; 308 bus->audio_component = NULL;
309 dev_err(dev, "failed to add i915 component master (%d)\n", ret); 309 dev_info(dev, "failed to add i915 component master (%d)\n", ret);
310 310
311 return ret; 311 return ret;
312} 312}
diff --git a/sound/pci/hda/hda_bind.c b/sound/pci/hda/hda_bind.c
index 70671ad65d24..6efadbfb3fe3 100644
--- a/sound/pci/hda/hda_bind.c
+++ b/sound/pci/hda/hda_bind.c
@@ -174,14 +174,40 @@ static inline bool codec_probed(struct hda_codec *codec)
174 return device_attach(hda_codec_dev(codec)) > 0 && codec->preset; 174 return device_attach(hda_codec_dev(codec)) > 0 && codec->preset;
175} 175}
176 176
177/* try to auto-load and bind the codec module */ 177/* try to auto-load codec module */
178static void codec_bind_module(struct hda_codec *codec) 178static void request_codec_module(struct hda_codec *codec)
179{ 179{
180#ifdef MODULE 180#ifdef MODULE
181 char modalias[32]; 181 char modalias[32];
182 const char *mod = NULL;
183
184 switch (codec->probe_id) {
185 case HDA_CODEC_ID_GENERIC_HDMI:
186#if IS_MODULE(CONFIG_SND_HDA_CODEC_HDMI)
187 mod = "snd-hda-codec-hdmi";
188#endif
189 break;
190 case HDA_CODEC_ID_GENERIC:
191#if IS_MODULE(CONFIG_SND_HDA_GENERIC)
192 mod = "snd-hda-codec-generic";
193#endif
194 break;
195 default:
196 snd_hdac_codec_modalias(&codec->core, modalias, sizeof(modalias));
197 mod = modalias;
198 break;
199 }
200
201 if (mod)
202 request_module(mod);
203#endif /* MODULE */
204}
182 205
183 snd_hdac_codec_modalias(&codec->core, modalias, sizeof(modalias)); 206/* try to auto-load and bind the codec module */
184 request_module(modalias); 207static void codec_bind_module(struct hda_codec *codec)
208{
209#ifdef MODULE
210 request_codec_module(codec);
185 if (codec_probed(codec)) 211 if (codec_probed(codec))
186 return; 212 return;
187#endif 213#endif
@@ -218,17 +244,13 @@ static int codec_bind_generic(struct hda_codec *codec)
218 244
219 if (is_likely_hdmi_codec(codec)) { 245 if (is_likely_hdmi_codec(codec)) {
220 codec->probe_id = HDA_CODEC_ID_GENERIC_HDMI; 246 codec->probe_id = HDA_CODEC_ID_GENERIC_HDMI;
221#if IS_MODULE(CONFIG_SND_HDA_CODEC_HDMI) 247 request_codec_module(codec);
222 request_module("snd-hda-codec-hdmi");
223#endif
224 if (codec_probed(codec)) 248 if (codec_probed(codec))
225 return 0; 249 return 0;
226 } 250 }
227 251
228 codec->probe_id = HDA_CODEC_ID_GENERIC; 252 codec->probe_id = HDA_CODEC_ID_GENERIC;
229#if IS_MODULE(CONFIG_SND_HDA_GENERIC) 253 request_codec_module(codec);
230 request_module("snd-hda-codec-generic");
231#endif
232 if (codec_probed(codec)) 254 if (codec_probed(codec))
233 return 0; 255 return 0;
234 return -ENODEV; 256 return -ENODEV;
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index c0bef11afa7e..256e6cda218f 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -2078,9 +2078,11 @@ static int azx_probe_continue(struct azx *chip)
2078 * for other chips, still continue probing as other 2078 * for other chips, still continue probing as other
2079 * codecs can be on the same link. 2079 * codecs can be on the same link.
2080 */ 2080 */
2081 if (CONTROLLER_IN_GPU(pci)) 2081 if (CONTROLLER_IN_GPU(pci)) {
2082 dev_err(chip->card->dev,
2083 "HSW/BDW HD-audio HDMI/DP requires binding with gfx driver\n");
2082 goto out_free; 2084 goto out_free;
2083 else 2085 } else
2084 goto skip_i915; 2086 goto skip_i915;
2085 } 2087 }
2086 2088
@@ -2149,9 +2151,17 @@ i915_power_fail:
2149static void azx_remove(struct pci_dev *pci) 2151static void azx_remove(struct pci_dev *pci)
2150{ 2152{
2151 struct snd_card *card = pci_get_drvdata(pci); 2153 struct snd_card *card = pci_get_drvdata(pci);
2154 struct azx *chip;
2155 struct hda_intel *hda;
2156
2157 if (card) {
2158 /* flush the pending probing work */
2159 chip = card->private_data;
2160 hda = container_of(chip, struct hda_intel, chip);
2161 flush_work(&hda->probe_work);
2152 2162
2153 if (card)
2154 snd_card_free(card); 2163 snd_card_free(card);
2164 }
2155} 2165}
2156 2166
2157static void azx_shutdown(struct pci_dev *pci) 2167static void azx_shutdown(struct pci_dev *pci)
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 8143c0e24a27..33753244f48f 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -6566,6 +6566,7 @@ static const struct snd_pci_quirk alc662_fixup_tbl[] = {
6566 SND_PCI_QUIRK(0x1028, 0x069f, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), 6566 SND_PCI_QUIRK(0x1028, 0x069f, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
6567 SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800), 6567 SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800),
6568 SND_PCI_QUIRK(0x1043, 0x11cd, "Asus N550", ALC662_FIXUP_BASS_1A), 6568 SND_PCI_QUIRK(0x1043, 0x11cd, "Asus N550", ALC662_FIXUP_BASS_1A),
6569 SND_PCI_QUIRK(0x1043, 0x13df, "Asus N550JX", ALC662_FIXUP_BASS_1A),
6569 SND_PCI_QUIRK(0x1043, 0x1477, "ASUS N56VZ", ALC662_FIXUP_BASS_MODE4_CHMAP), 6570 SND_PCI_QUIRK(0x1043, 0x1477, "ASUS N56VZ", ALC662_FIXUP_BASS_MODE4_CHMAP),
6570 SND_PCI_QUIRK(0x1043, 0x15a7, "ASUS UX51VZH", ALC662_FIXUP_BASS_16), 6571 SND_PCI_QUIRK(0x1043, 0x15a7, "ASUS UX51VZH", ALC662_FIXUP_BASS_16),
6571 SND_PCI_QUIRK(0x1043, 0x1b73, "ASUS N55SF", ALC662_FIXUP_BASS_16), 6572 SND_PCI_QUIRK(0x1043, 0x1b73, "ASUS N55SF", ALC662_FIXUP_BASS_16),
diff --git a/sound/spi/at73c213.c b/sound/spi/at73c213.c
index 39522367897c..fac7e6eb9529 100644
--- a/sound/spi/at73c213.c
+++ b/sound/spi/at73c213.c
@@ -221,6 +221,8 @@ static int snd_at73c213_pcm_open(struct snd_pcm_substream *substream)
221 runtime->hw = snd_at73c213_playback_hw; 221 runtime->hw = snd_at73c213_playback_hw;
222 chip->substream = substream; 222 chip->substream = substream;
223 223
224 clk_enable(chip->ssc->clk);
225
224 return 0; 226 return 0;
225} 227}
226 228
@@ -228,6 +230,7 @@ static int snd_at73c213_pcm_close(struct snd_pcm_substream *substream)
228{ 230{
229 struct snd_at73c213 *chip = snd_pcm_substream_chip(substream); 231 struct snd_at73c213 *chip = snd_pcm_substream_chip(substream);
230 chip->substream = NULL; 232 chip->substream = NULL;
233 clk_disable(chip->ssc->clk);
231 return 0; 234 return 0;
232} 235}
233 236
@@ -897,6 +900,8 @@ static int snd_at73c213_dev_init(struct snd_card *card,
897 chip->card = card; 900 chip->card = card;
898 chip->irq = -1; 901 chip->irq = -1;
899 902
903 clk_enable(chip->ssc->clk);
904
900 retval = request_irq(irq, snd_at73c213_interrupt, 0, "at73c213", chip); 905 retval = request_irq(irq, snd_at73c213_interrupt, 0, "at73c213", chip);
901 if (retval) { 906 if (retval) {
902 dev_dbg(&chip->spi->dev, "unable to request irq %d\n", irq); 907 dev_dbg(&chip->spi->dev, "unable to request irq %d\n", irq);
@@ -935,6 +940,8 @@ out_irq:
935 free_irq(chip->irq, chip); 940 free_irq(chip->irq, chip);
936 chip->irq = -1; 941 chip->irq = -1;
937out: 942out:
943 clk_disable(chip->ssc->clk);
944
938 return retval; 945 return retval;
939} 946}
940 947
@@ -1012,7 +1019,9 @@ static int snd_at73c213_remove(struct spi_device *spi)
1012 int retval; 1019 int retval;
1013 1020
1014 /* Stop playback. */ 1021 /* Stop playback. */
1022 clk_enable(chip->ssc->clk);
1015 ssc_writel(chip->ssc->regs, CR, SSC_BIT(CR_TXDIS)); 1023 ssc_writel(chip->ssc->regs, CR, SSC_BIT(CR_TXDIS));
1024 clk_disable(chip->ssc->clk);
1016 1025
1017 /* Mute sound. */ 1026 /* Mute sound. */
1018 retval = snd_at73c213_write_reg(chip, DAC_LMPG, 0x3f); 1027 retval = snd_at73c213_write_reg(chip, DAC_LMPG, 0x3f);
@@ -1080,6 +1089,7 @@ static int snd_at73c213_suspend(struct device *dev)
1080 struct snd_at73c213 *chip = card->private_data; 1089 struct snd_at73c213 *chip = card->private_data;
1081 1090
1082 ssc_writel(chip->ssc->regs, CR, SSC_BIT(CR_TXDIS)); 1091 ssc_writel(chip->ssc->regs, CR, SSC_BIT(CR_TXDIS));
1092 clk_disable(chip->ssc->clk);
1083 clk_disable(chip->board->dac_clk); 1093 clk_disable(chip->board->dac_clk);
1084 1094
1085 return 0; 1095 return 0;
@@ -1091,6 +1101,7 @@ static int snd_at73c213_resume(struct device *dev)
1091 struct snd_at73c213 *chip = card->private_data; 1101 struct snd_at73c213 *chip = card->private_data;
1092 1102
1093 clk_enable(chip->board->dac_clk); 1103 clk_enable(chip->board->dac_clk);
1104 clk_enable(chip->ssc->clk);
1094 ssc_writel(chip->ssc->regs, CR, SSC_BIT(CR_TXEN)); 1105 ssc_writel(chip->ssc->regs, CR, SSC_BIT(CR_TXEN));
1095 1106
1096 return 0; 1107 return 0;