tangled
alpha
login
or
join now
tjh.dev
/
kernel
1
fork
atom
Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
1
fork
atom
overview
issues
pulls
pipelines
Merge branch 'topic/ak411x-fix' into for-next
Takashi Iwai
11 years ago
d832f3dc
5da7f924
+82
-28
5 changed files
expand all
collapse all
unified
split
include
sound
ak4113.h
ak4114.h
sound
i2c
other
ak4113.c
ak4114.c
pci
ice1712
juli.c
+10
-1
include/sound/ak4113.h
reviewed
···
286
286
ak4113_write_t *write;
287
287
ak4113_read_t *read;
288
288
void *private_data;
289
289
-
unsigned int init:1;
289
289
+
atomic_t wq_processing;
290
290
+
struct mutex reinit_mutex;
290
291
spinlock_t lock;
291
292
unsigned char regmap[AK4113_WRITABLE_REGS];
292
293
struct snd_kcontrol *kctls[AK4113_CONTROLS];
···
317
316
struct snd_pcm_substream *capture_substream);
318
317
int snd_ak4113_external_rate(struct ak4113 *ak4113);
319
318
int snd_ak4113_check_rate_and_errors(struct ak4113 *ak4113, unsigned int flags);
319
319
+
320
320
+
#ifdef CONFIG_PM
321
321
+
void snd_ak4113_suspend(struct ak4113 *chip);
322
322
+
void snd_ak4113_resume(struct ak4113 *chip);
323
323
+
#else
324
324
+
static inline void snd_ak4113_suspend(struct ak4113 *chip) {}
325
325
+
static inline void snd_ak4113_resume(struct ak4113 *chip) {}
326
326
+
#endif
320
327
321
328
#endif /* __SOUND_AK4113_H */
322
329
+10
-1
include/sound/ak4114.h
reviewed
···
168
168
ak4114_write_t * write;
169
169
ak4114_read_t * read;
170
170
void * private_data;
171
171
-
unsigned int init: 1;
171
171
+
atomic_t wq_processing;
172
172
+
struct mutex reinit_mutex;
172
173
spinlock_t lock;
173
174
unsigned char regmap[6];
174
175
unsigned char txcsb[5];
···
199
198
struct snd_pcm_substream *capture_substream);
200
199
int snd_ak4114_external_rate(struct ak4114 *ak4114);
201
200
int snd_ak4114_check_rate_and_errors(struct ak4114 *ak4114, unsigned int flags);
201
201
+
202
202
+
#ifdef CONFIG_PM
203
203
+
void snd_ak4114_suspend(struct ak4114 *chip);
204
204
+
void snd_ak4114_resume(struct ak4114 *chip);
205
205
+
#else
206
206
+
static inline void snd_ak4114_suspend(struct ak4114 *chip) {}
207
207
+
static inline void snd_ak4114_resume(struct ak4114 *chip) {}
208
208
+
#endif
202
209
203
210
#endif /* __SOUND_AK4114_H */
204
211
+27
-9
sound/i2c/other/ak4113.c
reviewed
···
56
56
57
57
static void snd_ak4113_free(struct ak4113 *chip)
58
58
{
59
59
-
chip->init = 1; /* don't schedule new work */
60
60
-
mb();
59
59
+
atomic_inc(&chip->wq_processing); /* don't schedule new work */
61
60
cancel_delayed_work_sync(&chip->work);
62
61
kfree(chip);
63
62
}
···
88
89
chip->write = write;
89
90
chip->private_data = private_data;
90
91
INIT_DELAYED_WORK(&chip->work, ak4113_stats);
92
92
+
atomic_set(&chip->wq_processing, 0);
93
93
+
mutex_init(&chip->reinit_mutex);
91
94
92
95
for (reg = 0; reg < AK4113_WRITABLE_REGS ; reg++)
93
96
chip->regmap[reg] = pgm[reg];
···
140
139
141
140
void snd_ak4113_reinit(struct ak4113 *chip)
142
141
{
143
143
-
chip->init = 1;
144
144
-
mb();
145
145
-
flush_delayed_work(&chip->work);
142
142
+
if (atomic_inc_return(&chip->wq_processing) == 1)
143
143
+
cancel_delayed_work_sync(&chip->work);
144
144
+
mutex_lock(&chip->reinit_mutex);
146
145
ak4113_init_regs(chip);
146
146
+
mutex_unlock(&chip->reinit_mutex);
147
147
/* bring up statistics / event queing */
148
148
-
chip->init = 0;
149
149
-
if (chip->kctls[0])
148
148
+
if (atomic_dec_and_test(&chip->wq_processing))
150
149
schedule_delayed_work(&chip->work, HZ / 10);
151
150
}
152
151
EXPORT_SYMBOL_GPL(snd_ak4113_reinit);
···
633
632
{
634
633
struct ak4113 *chip = container_of(work, struct ak4113, work.work);
635
634
636
636
-
if (!chip->init)
635
635
+
if (atomic_inc_return(&chip->wq_processing) == 1)
637
636
snd_ak4113_check_rate_and_errors(chip, chip->check_flags);
638
637
639
639
-
schedule_delayed_work(&chip->work, HZ / 10);
638
638
+
if (atomic_dec_and_test(&chip->wq_processing))
639
639
+
schedule_delayed_work(&chip->work, HZ / 10);
640
640
}
641
641
+
642
642
+
#ifdef CONFIG_PM
643
643
+
void snd_ak4113_suspend(struct ak4113 *chip)
644
644
+
{
645
645
+
atomic_inc(&chip->wq_processing); /* don't schedule new work */
646
646
+
cancel_delayed_work_sync(&chip->work);
647
647
+
}
648
648
+
EXPORT_SYMBOL(snd_ak4113_suspend);
649
649
+
650
650
+
void snd_ak4113_resume(struct ak4113 *chip)
651
651
+
{
652
652
+
atomic_dec(&chip->wq_processing);
653
653
+
snd_ak4113_reinit(chip);
654
654
+
}
655
655
+
EXPORT_SYMBOL(snd_ak4113_resume);
656
656
+
#endif
+32
-16
sound/i2c/other/ak4114.c
reviewed
···
66
66
67
67
static void snd_ak4114_free(struct ak4114 *chip)
68
68
{
69
69
-
chip->init = 1; /* don't schedule new work */
70
70
-
mb();
69
69
+
atomic_inc(&chip->wq_processing); /* don't schedule new work */
71
70
cancel_delayed_work_sync(&chip->work);
72
71
kfree(chip);
73
72
}
···
99
100
chip->write = write;
100
101
chip->private_data = private_data;
101
102
INIT_DELAYED_WORK(&chip->work, ak4114_stats);
103
103
+
atomic_set(&chip->wq_processing, 0);
104
104
+
mutex_init(&chip->reinit_mutex);
102
105
103
106
for (reg = 0; reg < 6; reg++)
104
107
chip->regmap[reg] = pgm[reg];
···
123
122
snd_ak4114_free(chip);
124
123
return err < 0 ? err : -EIO;
125
124
}
125
125
+
EXPORT_SYMBOL(snd_ak4114_create);
126
126
127
127
void snd_ak4114_reg_write(struct ak4114 *chip, unsigned char reg, unsigned char mask, unsigned char val)
128
128
{
···
133
131
reg_write(chip, reg,
134
132
(chip->txcsb[reg-AK4114_REG_TXCSB0] & ~mask) | val);
135
133
}
134
134
+
EXPORT_SYMBOL(snd_ak4114_reg_write);
136
135
137
136
static void ak4114_init_regs(struct ak4114 *chip)
138
137
{
···
155
152
156
153
void snd_ak4114_reinit(struct ak4114 *chip)
157
154
{
158
158
-
chip->init = 1;
159
159
-
mb();
160
160
-
flush_delayed_work(&chip->work);
155
155
+
if (atomic_inc_return(&chip->wq_processing) == 1)
156
156
+
cancel_delayed_work_sync(&chip->work);
157
157
+
mutex_lock(&chip->reinit_mutex);
161
158
ak4114_init_regs(chip);
159
159
+
mutex_unlock(&chip->reinit_mutex);
162
160
/* bring up statistics / event queing */
163
163
-
chip->init = 0;
164
164
-
if (chip->kctls[0])
161
161
+
if (atomic_dec_and_test(&chip->wq_processing))
165
162
schedule_delayed_work(&chip->work, HZ / 10);
166
163
}
164
164
+
EXPORT_SYMBOL(snd_ak4114_reinit);
167
165
168
166
static unsigned int external_rate(unsigned char rcs1)
169
167
{
···
509
505
schedule_delayed_work(&ak4114->work, HZ / 10);
510
506
return 0;
511
507
}
508
508
+
EXPORT_SYMBOL(snd_ak4114_build);
512
509
513
510
/* notify kcontrols if any parameters are changed */
514
511
static void ak4114_notify(struct ak4114 *ak4114,
···
565
560
rcs1 = reg_read(ak4114, AK4114_REG_RCS1);
566
561
return external_rate(rcs1);
567
562
}
563
563
+
EXPORT_SYMBOL(snd_ak4114_external_rate);
568
564
569
565
int snd_ak4114_check_rate_and_errors(struct ak4114 *ak4114, unsigned int flags)
570
566
{
···
613
607
}
614
608
return res;
615
609
}
610
610
+
EXPORT_SYMBOL(snd_ak4114_check_rate_and_errors);
616
611
617
612
static void ak4114_stats(struct work_struct *work)
618
613
{
619
614
struct ak4114 *chip = container_of(work, struct ak4114, work.work);
620
615
621
621
-
if (!chip->init)
616
616
+
if (atomic_inc_return(&chip->wq_processing) == 1)
622
617
snd_ak4114_check_rate_and_errors(chip, chip->check_flags);
623
623
-
624
624
-
schedule_delayed_work(&chip->work, HZ / 10);
618
618
+
if (atomic_dec_and_test(&chip->wq_processing))
619
619
+
schedule_delayed_work(&chip->work, HZ / 10);
625
620
}
626
621
627
627
-
EXPORT_SYMBOL(snd_ak4114_create);
628
628
-
EXPORT_SYMBOL(snd_ak4114_reg_write);
629
629
-
EXPORT_SYMBOL(snd_ak4114_reinit);
630
630
-
EXPORT_SYMBOL(snd_ak4114_build);
631
631
-
EXPORT_SYMBOL(snd_ak4114_external_rate);
632
632
-
EXPORT_SYMBOL(snd_ak4114_check_rate_and_errors);
622
622
+
#ifdef CONFIG_PM
623
623
+
void snd_ak4114_suspend(struct ak4114 *chip)
624
624
+
{
625
625
+
atomic_inc(&chip->wq_processing); /* don't schedule new work */
626
626
+
cancel_delayed_work_sync(&chip->work);
627
627
+
}
628
628
+
EXPORT_SYMBOL(snd_ak4114_suspend);
629
629
+
630
630
+
void snd_ak4114_resume(struct ak4114 *chip)
631
631
+
{
632
632
+
atomic_dec(&chip->wq_processing);
633
633
+
snd_ak4114_reinit(chip);
634
634
+
}
635
635
+
EXPORT_SYMBOL(snd_ak4114_resume);
636
636
+
#endif
+3
-1
sound/pci/ice1712/juli.c
reviewed
···
491
491
/* akm4358 un-reset, un-mute */
492
492
snd_akm4xxx_reset(ak, 0);
493
493
/* reinit ak4114 */
494
494
-
snd_ak4114_reinit(spec->ak4114);
494
494
+
snd_ak4114_resume(spec->ak4114);
495
495
return 0;
496
496
}
497
497
498
498
static int juli_suspend(struct snd_ice1712 *ice)
499
499
{
500
500
struct snd_akm4xxx *ak = ice->akm;
501
501
+
struct juli_spec *spec = ice->spec;
501
502
/* akm4358 reset and soft-mute */
502
503
snd_akm4xxx_reset(ak, 1);
504
504
+
snd_ak4114_suspend(spec->ak4114);
503
505
return 0;
504
506
}
505
507
#endif