Skip to content

Commit d27c6a2

Browse files
committed
Merge remote-tracking branch 'takashi/for-next' into sound/upstream-20210719
2 parents 50159ee + 3a1e341 commit d27c6a2

128 files changed

Lines changed: 2037 additions & 5639 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

Documentation/sound/kernel-api/writing-an-alsa-driver.rst

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4172,6 +4172,39 @@ module license as GPL, etc., otherwise the system is shown as “tainted”.
41724172
MODULE_LICENSE("GPL");
41734173

41744174

4175+
Device-Managed Resources
4176+
========================
4177+
4178+
In the examples above, all resources are allocated and released
4179+
manually. But human beings are lazy in nature, especially developers
4180+
are lazier. So there are some ways to automate the release part; it's
4181+
the (device-)managed resources aka devres or devm family. For
4182+
example, an object allocated via :c:func:`devm_kmalloc()` will be
4183+
freed automatically at unbinding the device.
4184+
4185+
ALSA core provides also the device-managed helper, namely,
4186+
:c:func:`snd_devm_card_new()` for creating a card object.
4187+
Call this functions instead of the normal :c:func:`snd_card_new()`,
4188+
and you can forget the explicit :c:func:`snd_card_free()` call, as
4189+
it's called automagically at error and removal paths.
4190+
4191+
One caveat is that the call of :c:func:`snd_card_free()` would be put
4192+
at the beginning of the call chain only after you call
4193+
:c:func:`snd_card_register()`.
4194+
4195+
Also, the ``private_free`` callback is always called at the card free,
4196+
so be careful to put the hardware clean-up procedure in
4197+
``private_free`` callback. It might be called even before you
4198+
actually set up at an earlier error path. For avoiding such an
4199+
invalid initialization, you can set ``private_free`` callback after
4200+
:c:func:`snd_card_register()` call succeeds.
4201+
4202+
Another thing to be remarked is that you should use device-managed
4203+
helpers for each component as much as possible once when you manage
4204+
the card in that way. Mixing up with the normal and the managed
4205+
resources may screw up the release order.
4206+
4207+
41754208
How To Put Your Driver Into ALSA Tree
41764209
=====================================
41774210

include/sound/compress_driver.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -165,8 +165,6 @@ struct snd_compr {
165165
};
166166

167167
/* compress device register APIs */
168-
int snd_compress_register(struct snd_compr *device);
169-
int snd_compress_deregister(struct snd_compr *device);
170168
int snd_compress_new(struct snd_card *card, int device,
171169
int type, const char *id, struct snd_compr *compr);
172170

include/sound/core.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,8 @@ struct snd_card {
117117
struct device card_dev; /* cardX object for sysfs */
118118
const struct attribute_group *dev_groups[4]; /* assigned sysfs attr */
119119
bool registered; /* card_dev is registered? */
120+
bool managed; /* managed via devres */
121+
bool releasing; /* during card free process */
120122
int sync_irq; /* assigned irq, used for PCM sync */
121123
wait_queue_head_t remove_sleep;
122124

@@ -274,6 +276,9 @@ extern int (*snd_mixer_oss_notify_callback)(struct snd_card *card, int cmd);
274276
int snd_card_new(struct device *parent, int idx, const char *xid,
275277
struct module *module, int extra_size,
276278
struct snd_card **card_ret);
279+
int snd_devm_card_new(struct device *parent, int idx, const char *xid,
280+
struct module *module, size_t extra_size,
281+
struct snd_card **card_ret);
277282

278283
int snd_card_disconnect(struct snd_card *card);
279284
void snd_card_disconnect_sync(struct snd_card *card);
@@ -324,6 +329,7 @@ int snd_device_get_state(struct snd_card *card, void *device_data);
324329
void snd_dma_program(unsigned long dma, unsigned long addr, unsigned int size, unsigned short mode);
325330
void snd_dma_disable(unsigned long dma);
326331
unsigned int snd_dma_pointer(unsigned long dma, unsigned int size);
332+
int snd_devm_request_dma(struct device *dev, int dma, const char *name);
327333
#endif
328334

329335
/* misc.c */

include/sound/emu10k1.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1701,7 +1701,7 @@ struct snd_emu10k1 {
17011701
struct snd_dma_buffer silent_page; /* silent page */
17021702
struct snd_dma_buffer ptb_pages; /* page table pages */
17031703
struct snd_dma_device p16v_dma_dev;
1704-
struct snd_dma_buffer p16v_buffer;
1704+
struct snd_dma_buffer *p16v_buffer;
17051705

17061706
struct snd_util_memhdr *memhdr; /* page allocation list */
17071707

@@ -1796,14 +1796,12 @@ int snd_emu10k1_create(struct snd_card *card,
17961796
unsigned short extout_mask,
17971797
long max_cache_bytes,
17981798
int enable_ir,
1799-
uint subsystem,
1800-
struct snd_emu10k1 ** remu);
1799+
uint subsystem);
18011800

18021801
int snd_emu10k1_pcm(struct snd_emu10k1 *emu, int device);
18031802
int snd_emu10k1_pcm_mic(struct snd_emu10k1 *emu, int device);
18041803
int snd_emu10k1_pcm_efx(struct snd_emu10k1 *emu, int device);
18051804
int snd_p16v_pcm(struct snd_emu10k1 *emu, int device);
1806-
int snd_p16v_free(struct snd_emu10k1 * emu);
18071805
int snd_p16v_mixer(struct snd_emu10k1 * emu);
18081806
int snd_emu10k1_pcm_multi(struct snd_emu10k1 *emu, int device);
18091807
int snd_emu10k1_fx8010_pcm(struct snd_emu10k1 *emu, int device);

include/sound/emu8000.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,6 @@ struct snd_emu8000 {
5656
unsigned long port1; /* Port usually base+0 */
5757
unsigned long port2; /* Port usually at base+0x400 */
5858
unsigned long port3; /* Port usually at base+0x800 */
59-
struct resource *res_port1;
60-
struct resource *res_port2;
61-
struct resource *res_port3;
6259
unsigned short last_reg;/* Last register command */
6360
spinlock_t reg_lock;
6461

include/sound/es1688.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818

1919
struct snd_es1688 {
2020
unsigned long port; /* port of ESS chip */
21-
struct resource *res_port;
2221
unsigned long mpu_port; /* MPU-401 port of ESS chip */
2322
int irq; /* IRQ number of ESS chip */
2423
int mpu_irq; /* MPU IRQ */

include/sound/memalloc.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,5 +79,9 @@ struct page *snd_sgbuf_get_page(struct snd_dma_buffer *dmab, size_t offset);
7979
unsigned int snd_sgbuf_get_chunk_size(struct snd_dma_buffer *dmab,
8080
unsigned int ofs, unsigned int size);
8181

82+
/* device-managed memory allocator */
83+
struct snd_dma_buffer *snd_devm_alloc_pages(struct device *dev, int type,
84+
size_t size);
85+
8286
#endif /* __SOUND_MEMALLOC_H */
8387

sound/core/compress_offload.c

Lines changed: 1 addition & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,6 @@
4747
* driver should be able to register multiple nodes
4848
*/
4949

50-
static DEFINE_MUTEX(device_mutex);
51-
5250
struct snd_compr_file {
5351
unsigned long caps;
5452
struct snd_compr_stream stream;
@@ -1179,6 +1177,7 @@ int snd_compress_new(struct snd_card *card, int device,
11791177
compr->card = card;
11801178
compr->device = device;
11811179
compr->direction = dirn;
1180+
mutex_init(&compr->lock);
11821181

11831182
snd_compress_set_id(compr, id);
11841183

@@ -1193,72 +1192,6 @@ int snd_compress_new(struct snd_card *card, int device,
11931192
}
11941193
EXPORT_SYMBOL_GPL(snd_compress_new);
11951194

1196-
static int snd_compress_add_device(struct snd_compr *device)
1197-
{
1198-
int ret;
1199-
1200-
if (!device->card)
1201-
return -EINVAL;
1202-
1203-
/* register the card */
1204-
ret = snd_card_register(device->card);
1205-
if (ret)
1206-
goto out;
1207-
return 0;
1208-
1209-
out:
1210-
pr_err("failed with %d\n", ret);
1211-
return ret;
1212-
1213-
}
1214-
1215-
static int snd_compress_remove_device(struct snd_compr *device)
1216-
{
1217-
return snd_card_free(device->card);
1218-
}
1219-
1220-
/**
1221-
* snd_compress_register - register compressed device
1222-
*
1223-
* @device: compressed device to register
1224-
*/
1225-
int snd_compress_register(struct snd_compr *device)
1226-
{
1227-
int retval;
1228-
1229-
if (device->name == NULL || device->ops == NULL)
1230-
return -EINVAL;
1231-
1232-
pr_debug("Registering compressed device %s\n", device->name);
1233-
if (snd_BUG_ON(!device->ops->open))
1234-
return -EINVAL;
1235-
if (snd_BUG_ON(!device->ops->free))
1236-
return -EINVAL;
1237-
if (snd_BUG_ON(!device->ops->set_params))
1238-
return -EINVAL;
1239-
if (snd_BUG_ON(!device->ops->trigger))
1240-
return -EINVAL;
1241-
1242-
mutex_init(&device->lock);
1243-
1244-
/* register a compressed card */
1245-
mutex_lock(&device_mutex);
1246-
retval = snd_compress_add_device(device);
1247-
mutex_unlock(&device_mutex);
1248-
return retval;
1249-
}
1250-
EXPORT_SYMBOL_GPL(snd_compress_register);
1251-
1252-
int snd_compress_deregister(struct snd_compr *device)
1253-
{
1254-
pr_debug("Removing compressed device %s\n", device->name);
1255-
mutex_lock(&device_mutex);
1256-
snd_compress_remove_device(device);
1257-
mutex_unlock(&device_mutex);
1258-
return 0;
1259-
}
1260-
EXPORT_SYMBOL_GPL(snd_compress_deregister);
1261-
12621195
MODULE_DESCRIPTION("ALSA Compressed offload framework");
12631196
MODULE_AUTHOR("Vinod Koul <vinod.koul@linux.intel.com>");
12641197
MODULE_LICENSE("GPL v2");

sound/core/init.c

Lines changed: 91 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,9 @@ void snd_device_initialize(struct device *dev, struct snd_card *card)
134134
}
135135
EXPORT_SYMBOL_GPL(snd_device_initialize);
136136

137+
static int snd_card_init(struct snd_card *card, struct device *parent,
138+
int idx, const char *xid, struct module *module,
139+
size_t extra_size);
137140
static int snd_card_do_free(struct snd_card *card);
138141
static const struct attribute_group card_dev_attr_group;
139142

@@ -163,9 +166,6 @@ int snd_card_new(struct device *parent, int idx, const char *xid,
163166
{
164167
struct snd_card *card;
165168
int err;
166-
#ifdef CONFIG_SND_DEBUG
167-
char name[8];
168-
#endif
169169

170170
if (snd_BUG_ON(!card_ret))
171171
return -EINVAL;
@@ -176,6 +176,74 @@ int snd_card_new(struct device *parent, int idx, const char *xid,
176176
card = kzalloc(sizeof(*card) + extra_size, GFP_KERNEL);
177177
if (!card)
178178
return -ENOMEM;
179+
180+
err = snd_card_init(card, parent, idx, xid, module, extra_size);
181+
if (err < 0) {
182+
kfree(card);
183+
return err;
184+
}
185+
186+
*card_ret = card;
187+
return 0;
188+
}
189+
EXPORT_SYMBOL(snd_card_new);
190+
191+
static void __snd_card_release(struct device *dev, void *data)
192+
{
193+
snd_card_free(data);
194+
}
195+
196+
/**
197+
* snd_devm_card_new - managed snd_card object creation
198+
* @parent: the parent device object
199+
* @idx: card index (address) [0 ... (SNDRV_CARDS-1)]
200+
* @xid: card identification (ASCII string)
201+
* @module: top level module for locking
202+
* @extra_size: allocate this extra size after the main soundcard structure
203+
* @card_ret: the pointer to store the created card instance
204+
*
205+
* This function works like snd_card_new() but manages the allocated resource
206+
* via devres, i.e. you don't need to free explicitly.
207+
*
208+
* When a snd_card object is created with this function and registered via
209+
* snd_card_register(), the very first devres action to call snd_card_free()
210+
* is added automatically. In that way, the resource disconnection is assured
211+
* at first, then released in the expected order.
212+
*/
213+
int snd_devm_card_new(struct device *parent, int idx, const char *xid,
214+
struct module *module, size_t extra_size,
215+
struct snd_card **card_ret)
216+
{
217+
struct snd_card *card;
218+
int err;
219+
220+
*card_ret = NULL;
221+
card = devres_alloc(__snd_card_release, sizeof(*card) + extra_size,
222+
GFP_KERNEL);
223+
if (!card)
224+
return -ENOMEM;
225+
card->managed = true;
226+
err = snd_card_init(card, parent, idx, xid, module, extra_size);
227+
if (err < 0) {
228+
devres_free(card);
229+
return err;
230+
}
231+
232+
devres_add(parent, card);
233+
*card_ret = card;
234+
return 0;
235+
}
236+
EXPORT_SYMBOL_GPL(snd_devm_card_new);
237+
238+
static int snd_card_init(struct snd_card *card, struct device *parent,
239+
int idx, const char *xid, struct module *module,
240+
size_t extra_size)
241+
{
242+
int err;
243+
#ifdef CONFIG_SND_DEBUG
244+
char name[8];
245+
#endif
246+
179247
if (extra_size > 0)
180248
card->private_data = (char *)card + sizeof(struct snd_card);
181249
if (xid)
@@ -197,7 +265,6 @@ int snd_card_new(struct device *parent, int idx, const char *xid,
197265
mutex_unlock(&snd_card_mutex);
198266
dev_err(parent, "cannot find the slot for index %d (range 0-%i), error: %d\n",
199267
idx, snd_ecards_limit - 1, err);
200-
kfree(card);
201268
return err;
202269
}
203270
set_bit(idx, snd_cards_lock); /* lock it */
@@ -256,8 +323,6 @@ int snd_card_new(struct device *parent, int idx, const char *xid,
256323
sprintf(name, "card%d", idx);
257324
card->debugfs_root = debugfs_create_dir(name, sound_debugfs_root);
258325
#endif
259-
260-
*card_ret = card;
261326
return 0;
262327

263328
__error_ctl:
@@ -266,7 +331,6 @@ int snd_card_new(struct device *parent, int idx, const char *xid,
266331
put_device(&card->card_dev);
267332
return err;
268333
}
269-
EXPORT_SYMBOL(snd_card_new);
270334

271335
/**
272336
* snd_card_ref - Get the card object from the index
@@ -481,6 +545,7 @@ EXPORT_SYMBOL_GPL(snd_card_disconnect_sync);
481545

482546
static int snd_card_do_free(struct snd_card *card)
483547
{
548+
card->releasing = true;
484549
#if IS_ENABLED(CONFIG_SND_MIXER_OSS)
485550
if (snd_mixer_oss_notify_callback)
486551
snd_mixer_oss_notify_callback(card, SND_MIXER_OSS_NOTIFY_FREE);
@@ -498,7 +563,8 @@ static int snd_card_do_free(struct snd_card *card)
498563
#endif
499564
if (card->release_completion)
500565
complete(card->release_completion);
501-
kfree(card);
566+
if (!card->managed)
567+
kfree(card);
502568
return 0;
503569
}
504570

@@ -745,6 +811,14 @@ int snd_card_add_dev_attr(struct snd_card *card,
745811
}
746812
EXPORT_SYMBOL_GPL(snd_card_add_dev_attr);
747813

814+
static void trigger_card_free(void *data)
815+
{
816+
struct snd_card *card = data;
817+
818+
if (!card->releasing)
819+
snd_card_free(data);
820+
}
821+
748822
/**
749823
* snd_card_register - register the soundcard
750824
* @card: soundcard structure
@@ -768,6 +842,15 @@ int snd_card_register(struct snd_card *card)
768842
if (err < 0)
769843
return err;
770844
card->registered = true;
845+
} else {
846+
if (card->managed)
847+
devm_remove_action(card->dev, trigger_card_free, card);
848+
}
849+
850+
if (card->managed) {
851+
err = devm_add_action(card->dev, trigger_card_free, card);
852+
if (err < 0)
853+
return err;
771854
}
772855

773856
err = snd_device_register_all(card);

0 commit comments

Comments
 (0)