aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2015-01-28 16:32:10 -0500
committerTakashi Iwai <tiwai@suse.de>2015-01-28 16:32:10 -0500
commitd832f3dcb6e2d153fbb69b91931058d138bc41cb (patch)
treeb58210600b92bbe0c20c02724a47068682b99d5e
parent5da7f924a41949797875c98a776dca1737a0f372 (diff)
parent1781e78c63317c04e6ae6a076acfd53236f420bc (diff)
Merge branch 'topic/ak411x-fix' into for-next
-rw-r--r--include/sound/ak4113.h11
-rw-r--r--include/sound/ak4114.h11
-rw-r--r--sound/i2c/other/ak4113.c36
-rw-r--r--sound/i2c/other/ak4114.c46
-rw-r--r--sound/pci/ice1712/juli.c4
5 files changed, 81 insertions, 27 deletions
diff --git a/include/sound/ak4113.h b/include/sound/ak4113.h
index 2609048c1d44..58c145620c3c 100644
--- a/include/sound/ak4113.h
+++ b/include/sound/ak4113.h
@@ -286,7 +286,8 @@ struct ak4113 {
286 ak4113_write_t *write; 286 ak4113_write_t *write;
287 ak4113_read_t *read; 287 ak4113_read_t *read;
288 void *private_data; 288 void *private_data;
289 unsigned int init:1; 289 atomic_t wq_processing;
290 struct mutex reinit_mutex;
290 spinlock_t lock; 291 spinlock_t lock;
291 unsigned char regmap[AK4113_WRITABLE_REGS]; 292 unsigned char regmap[AK4113_WRITABLE_REGS];
292 struct snd_kcontrol *kctls[AK4113_CONTROLS]; 293 struct snd_kcontrol *kctls[AK4113_CONTROLS];
@@ -317,5 +318,13 @@ int snd_ak4113_build(struct ak4113 *ak4113,
317int snd_ak4113_external_rate(struct ak4113 *ak4113); 318int snd_ak4113_external_rate(struct ak4113 *ak4113);
318int snd_ak4113_check_rate_and_errors(struct ak4113 *ak4113, unsigned int flags); 319int snd_ak4113_check_rate_and_errors(struct ak4113 *ak4113, unsigned int flags);
319 320
321#ifdef CONFIG_PM
322void snd_ak4113_suspend(struct ak4113 *chip);
323void snd_ak4113_resume(struct ak4113 *chip);
324#else
325static inline void snd_ak4113_suspend(struct ak4113 *chip) {}
326static inline void snd_ak4113_resume(struct ak4113 *chip) {}
327#endif
328
320#endif /* __SOUND_AK4113_H */ 329#endif /* __SOUND_AK4113_H */
321 330
diff --git a/include/sound/ak4114.h b/include/sound/ak4114.h
index 52f02a60dba7..b6feb7e225f2 100644
--- a/include/sound/ak4114.h
+++ b/include/sound/ak4114.h
@@ -168,7 +168,8 @@ struct ak4114 {
168 ak4114_write_t * write; 168 ak4114_write_t * write;
169 ak4114_read_t * read; 169 ak4114_read_t * read;
170 void * private_data; 170 void * private_data;
171 unsigned int init: 1; 171 atomic_t wq_processing;
172 struct mutex reinit_mutex;
172 spinlock_t lock; 173 spinlock_t lock;
173 unsigned char regmap[6]; 174 unsigned char regmap[6];
174 unsigned char txcsb[5]; 175 unsigned char txcsb[5];
@@ -199,5 +200,13 @@ int snd_ak4114_build(struct ak4114 *ak4114,
199int snd_ak4114_external_rate(struct ak4114 *ak4114); 200int snd_ak4114_external_rate(struct ak4114 *ak4114);
200int snd_ak4114_check_rate_and_errors(struct ak4114 *ak4114, unsigned int flags); 201int snd_ak4114_check_rate_and_errors(struct ak4114 *ak4114, unsigned int flags);
201 202
203#ifdef CONFIG_PM
204void snd_ak4114_suspend(struct ak4114 *chip);
205void snd_ak4114_resume(struct ak4114 *chip);
206#else
207static inline void snd_ak4114_suspend(struct ak4114 *chip) {}
208static inline void snd_ak4114_resume(struct ak4114 *chip) {}
209#endif
210
202#endif /* __SOUND_AK4114_H */ 211#endif /* __SOUND_AK4114_H */
203 212
diff --git a/sound/i2c/other/ak4113.c b/sound/i2c/other/ak4113.c
index 1a3a6fa27158..88844881cbff 100644
--- a/sound/i2c/other/ak4113.c
+++ b/sound/i2c/other/ak4113.c
@@ -56,8 +56,7 @@ static inline unsigned char reg_read(struct ak4113 *ak4113, unsigned char reg)
56 56
57static void snd_ak4113_free(struct ak4113 *chip) 57static void snd_ak4113_free(struct ak4113 *chip)
58{ 58{
59 chip->init = 1; /* don't schedule new work */ 59 atomic_inc(&chip->wq_processing); /* don't schedule new work */
60 mb();
61 cancel_delayed_work_sync(&chip->work); 60 cancel_delayed_work_sync(&chip->work);
62 kfree(chip); 61 kfree(chip);
63} 62}
@@ -89,6 +88,8 @@ int snd_ak4113_create(struct snd_card *card, ak4113_read_t *read,
89 chip->write = write; 88 chip->write = write;
90 chip->private_data = private_data; 89 chip->private_data = private_data;
91 INIT_DELAYED_WORK(&chip->work, ak4113_stats); 90 INIT_DELAYED_WORK(&chip->work, ak4113_stats);
91 atomic_set(&chip->wq_processing, 0);
92 mutex_init(&chip->reinit_mutex);
92 93
93 for (reg = 0; reg < AK4113_WRITABLE_REGS ; reg++) 94 for (reg = 0; reg < AK4113_WRITABLE_REGS ; reg++)
94 chip->regmap[reg] = pgm[reg]; 95 chip->regmap[reg] = pgm[reg];
@@ -139,13 +140,13 @@ static void ak4113_init_regs(struct ak4113 *chip)
139 140
140void snd_ak4113_reinit(struct ak4113 *chip) 141void snd_ak4113_reinit(struct ak4113 *chip)
141{ 142{
142 chip->init = 1; 143 if (atomic_inc_return(&chip->wq_processing) == 1)
143 mb(); 144 cancel_delayed_work_sync(&chip->work);
144 flush_delayed_work(&chip->work); 145 mutex_lock(&chip->reinit_mutex);
145 ak4113_init_regs(chip); 146 ak4113_init_regs(chip);
147 mutex_unlock(&chip->reinit_mutex);
146 /* bring up statistics / event queing */ 148 /* bring up statistics / event queing */
147 chip->init = 0; 149 if (atomic_dec_and_test(&chip->wq_processing))
148 if (chip->kctls[0])
149 schedule_delayed_work(&chip->work, HZ / 10); 150 schedule_delayed_work(&chip->work, HZ / 10);
150} 151}
151EXPORT_SYMBOL_GPL(snd_ak4113_reinit); 152EXPORT_SYMBOL_GPL(snd_ak4113_reinit);
@@ -632,8 +633,25 @@ static void ak4113_stats(struct work_struct *work)
632{ 633{
633 struct ak4113 *chip = container_of(work, struct ak4113, work.work); 634 struct ak4113 *chip = container_of(work, struct ak4113, work.work);
634 635
635 if (!chip->init) 636 if (atomic_inc_return(&chip->wq_processing) == 1)
636 snd_ak4113_check_rate_and_errors(chip, chip->check_flags); 637 snd_ak4113_check_rate_and_errors(chip, chip->check_flags);
637 638
638 schedule_delayed_work(&chip->work, HZ / 10); 639 if (atomic_dec_and_test(&chip->wq_processing))
640 schedule_delayed_work(&chip->work, HZ / 10);
641}
642
643#ifdef CONFIG_PM
644void snd_ak4113_suspend(struct ak4113 *chip)
645{
646 atomic_inc(&chip->wq_processing); /* don't schedule new work */
647 cancel_delayed_work_sync(&chip->work);
648}
649EXPORT_SYMBOL(snd_ak4113_suspend);
650
651void snd_ak4113_resume(struct ak4113 *chip)
652{
653 atomic_dec(&chip->wq_processing);
654 snd_ak4113_reinit(chip);
639} 655}
656EXPORT_SYMBOL(snd_ak4113_resume);
657#endif
diff --git a/sound/i2c/other/ak4114.c b/sound/i2c/other/ak4114.c
index c7f56339415d..5a4cf3fab4ae 100644
--- a/sound/i2c/other/ak4114.c
+++ b/sound/i2c/other/ak4114.c
@@ -66,8 +66,7 @@ static void reg_dump(struct ak4114 *ak4114)
66 66
67static void snd_ak4114_free(struct ak4114 *chip) 67static void snd_ak4114_free(struct ak4114 *chip)
68{ 68{
69 chip->init = 1; /* don't schedule new work */ 69 atomic_inc(&chip->wq_processing); /* don't schedule new work */
70 mb();
71 cancel_delayed_work_sync(&chip->work); 70 cancel_delayed_work_sync(&chip->work);
72 kfree(chip); 71 kfree(chip);
73} 72}
@@ -100,6 +99,8 @@ int snd_ak4114_create(struct snd_card *card,
100 chip->write = write; 99 chip->write = write;
101 chip->private_data = private_data; 100 chip->private_data = private_data;
102 INIT_DELAYED_WORK(&chip->work, ak4114_stats); 101 INIT_DELAYED_WORK(&chip->work, ak4114_stats);
102 atomic_set(&chip->wq_processing, 0);
103 mutex_init(&chip->reinit_mutex);
103 104
104 for (reg = 0; reg < 6; reg++) 105 for (reg = 0; reg < 6; reg++)
105 chip->regmap[reg] = pgm[reg]; 106 chip->regmap[reg] = pgm[reg];
@@ -122,6 +123,7 @@ int snd_ak4114_create(struct snd_card *card,
122 snd_ak4114_free(chip); 123 snd_ak4114_free(chip);
123 return err < 0 ? err : -EIO; 124 return err < 0 ? err : -EIO;
124} 125}
126EXPORT_SYMBOL(snd_ak4114_create);
125 127
126void snd_ak4114_reg_write(struct ak4114 *chip, unsigned char reg, unsigned char mask, unsigned char val) 128void snd_ak4114_reg_write(struct ak4114 *chip, unsigned char reg, unsigned char mask, unsigned char val)
127{ 129{
@@ -131,6 +133,7 @@ void snd_ak4114_reg_write(struct ak4114 *chip, unsigned char reg, unsigned char
131 reg_write(chip, reg, 133 reg_write(chip, reg,
132 (chip->txcsb[reg-AK4114_REG_TXCSB0] & ~mask) | val); 134 (chip->txcsb[reg-AK4114_REG_TXCSB0] & ~mask) | val);
133} 135}
136EXPORT_SYMBOL(snd_ak4114_reg_write);
134 137
135static void ak4114_init_regs(struct ak4114 *chip) 138static void ak4114_init_regs(struct ak4114 *chip)
136{ 139{
@@ -152,15 +155,16 @@ static void ak4114_init_regs(struct ak4114 *chip)
152 155
153void snd_ak4114_reinit(struct ak4114 *chip) 156void snd_ak4114_reinit(struct ak4114 *chip)
154{ 157{
155 chip->init = 1; 158 if (atomic_inc_return(&chip->wq_processing) == 1)
156 mb(); 159 cancel_delayed_work_sync(&chip->work);
157 flush_delayed_work(&chip->work); 160 mutex_lock(&chip->reinit_mutex);
158 ak4114_init_regs(chip); 161 ak4114_init_regs(chip);
162 mutex_unlock(&chip->reinit_mutex);
159 /* bring up statistics / event queing */ 163 /* bring up statistics / event queing */
160 chip->init = 0; 164 if (atomic_dec_and_test(&chip->wq_processing))
161 if (chip->kctls[0])
162 schedule_delayed_work(&chip->work, HZ / 10); 165 schedule_delayed_work(&chip->work, HZ / 10);
163} 166}
167EXPORT_SYMBOL(snd_ak4114_reinit);
164 168
165static unsigned int external_rate(unsigned char rcs1) 169static unsigned int external_rate(unsigned char rcs1)
166{ 170{
@@ -505,6 +509,7 @@ int snd_ak4114_build(struct ak4114 *ak4114,
505 schedule_delayed_work(&ak4114->work, HZ / 10); 509 schedule_delayed_work(&ak4114->work, HZ / 10);
506 return 0; 510 return 0;
507} 511}
512EXPORT_SYMBOL(snd_ak4114_build);
508 513
509/* notify kcontrols if any parameters are changed */ 514/* notify kcontrols if any parameters are changed */
510static void ak4114_notify(struct ak4114 *ak4114, 515static void ak4114_notify(struct ak4114 *ak4114,
@@ -560,6 +565,7 @@ int snd_ak4114_external_rate(struct ak4114 *ak4114)
560 rcs1 = reg_read(ak4114, AK4114_REG_RCS1); 565 rcs1 = reg_read(ak4114, AK4114_REG_RCS1);
561 return external_rate(rcs1); 566 return external_rate(rcs1);
562} 567}
568EXPORT_SYMBOL(snd_ak4114_external_rate);
563 569
564int snd_ak4114_check_rate_and_errors(struct ak4114 *ak4114, unsigned int flags) 570int snd_ak4114_check_rate_and_errors(struct ak4114 *ak4114, unsigned int flags)
565{ 571{
@@ -607,20 +613,30 @@ int snd_ak4114_check_rate_and_errors(struct ak4114 *ak4114, unsigned int flags)
607 } 613 }
608 return res; 614 return res;
609} 615}
616EXPORT_SYMBOL(snd_ak4114_check_rate_and_errors);
610 617
611static void ak4114_stats(struct work_struct *work) 618static void ak4114_stats(struct work_struct *work)
612{ 619{
613 struct ak4114 *chip = container_of(work, struct ak4114, work.work); 620 struct ak4114 *chip = container_of(work, struct ak4114, work.work);
614 621
615 if (!chip->init) 622 if (atomic_inc_return(&chip->wq_processing) == 1)
616 snd_ak4114_check_rate_and_errors(chip, chip->check_flags); 623 snd_ak4114_check_rate_and_errors(chip, chip->check_flags);
624 if (atomic_dec_and_test(&chip->wq_processing))
625 schedule_delayed_work(&chip->work, HZ / 10);
626}
617 627
618 schedule_delayed_work(&chip->work, HZ / 10); 628#ifdef CONFIG_PM
629void snd_ak4114_suspend(struct ak4114 *chip)
630{
631 atomic_inc(&chip->wq_processing); /* don't schedule new work */
632 cancel_delayed_work_sync(&chip->work);
619} 633}
634EXPORT_SYMBOL(snd_ak4114_suspend);
620 635
621EXPORT_SYMBOL(snd_ak4114_create); 636void snd_ak4114_resume(struct ak4114 *chip)
622EXPORT_SYMBOL(snd_ak4114_reg_write); 637{
623EXPORT_SYMBOL(snd_ak4114_reinit); 638 atomic_dec(&chip->wq_processing);
624EXPORT_SYMBOL(snd_ak4114_build); 639 snd_ak4114_reinit(chip);
625EXPORT_SYMBOL(snd_ak4114_external_rate); 640}
626EXPORT_SYMBOL(snd_ak4114_check_rate_and_errors); 641EXPORT_SYMBOL(snd_ak4114_resume);
642#endif
diff --git a/sound/pci/ice1712/juli.c b/sound/pci/ice1712/juli.c
index a1536c1a7ed4..4f0213427152 100644
--- a/sound/pci/ice1712/juli.c
+++ b/sound/pci/ice1712/juli.c
@@ -491,15 +491,17 @@ static int juli_resume(struct snd_ice1712 *ice)
491 /* akm4358 un-reset, un-mute */ 491 /* akm4358 un-reset, un-mute */
492 snd_akm4xxx_reset(ak, 0); 492 snd_akm4xxx_reset(ak, 0);
493 /* reinit ak4114 */ 493 /* reinit ak4114 */
494 snd_ak4114_reinit(spec->ak4114); 494 snd_ak4114_resume(spec->ak4114);
495 return 0; 495 return 0;
496} 496}
497 497
498static int juli_suspend(struct snd_ice1712 *ice) 498static int juli_suspend(struct snd_ice1712 *ice)
499{ 499{
500 struct snd_akm4xxx *ak = ice->akm; 500 struct snd_akm4xxx *ak = ice->akm;
501 struct juli_spec *spec = ice->spec;
501 /* akm4358 reset and soft-mute */ 502 /* akm4358 reset and soft-mute */
502 snd_akm4xxx_reset(ak, 1); 503 snd_akm4xxx_reset(ak, 1);
504 snd_ak4114_suspend(spec->ak4114);
503 return 0; 505 return 0;
504} 506}
505#endif 507#endif