ALSA: pcm: Embed struct device
Like previous patches, at this time we embed the struct device into PCM object. However, this needs a bit more caution: struct snd_pcm doesn't own one device but two, for both playback and capture! Thus not struct snd_pcm but struct snd_pcm_str object contains the device. Along with this change, pcm->dev field is dropped for avoiding confusion. It was meant to point to a non-standard parent. But, since now we can touch each struct device directly, we can manipulate the parent field easily there, too. Reviewed-by: Jaroslav Kysela <perex@perex.cz> Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
parent
7b46160000
commit
ef46c7af93
|
@ -449,6 +449,7 @@ struct snd_pcm_str {
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
struct snd_kcontrol *chmap_kctl; /* channel-mapping controls */
|
struct snd_kcontrol *chmap_kctl; /* channel-mapping controls */
|
||||||
|
struct device dev;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct snd_pcm {
|
struct snd_pcm {
|
||||||
|
@ -465,7 +466,6 @@ struct snd_pcm {
|
||||||
wait_queue_head_t open_wait;
|
wait_queue_head_t open_wait;
|
||||||
void *private_data;
|
void *private_data;
|
||||||
void (*private_free) (struct snd_pcm *pcm);
|
void (*private_free) (struct snd_pcm *pcm);
|
||||||
struct device *dev; /* actual hw device this belongs to */
|
|
||||||
bool internal; /* pcm is for internal use only */
|
bool internal; /* pcm is for internal use only */
|
||||||
bool nonatomic; /* whole PCM operations are in non-atomic context */
|
bool nonatomic; /* whole PCM operations are in non-atomic context */
|
||||||
#if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE)
|
#if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE)
|
||||||
|
|
|
@ -968,7 +968,6 @@ i2sbus_attach_codec(struct soundbus_dev *dev, struct snd_card *card,
|
||||||
printk(KERN_DEBUG "i2sbus: failed to create pcm\n");
|
printk(KERN_DEBUG "i2sbus: failed to create pcm\n");
|
||||||
goto out_put_ci_module;
|
goto out_put_ci_module;
|
||||||
}
|
}
|
||||||
dev->pcm->dev = &dev->ofdev.dev;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ALSA yet again sucks.
|
/* ALSA yet again sucks.
|
||||||
|
@ -988,6 +987,8 @@ i2sbus_attach_codec(struct soundbus_dev *dev, struct snd_card *card,
|
||||||
goto out_put_ci_module;
|
goto out_put_ci_module;
|
||||||
snd_pcm_set_ops(dev->pcm, SNDRV_PCM_STREAM_PLAYBACK,
|
snd_pcm_set_ops(dev->pcm, SNDRV_PCM_STREAM_PLAYBACK,
|
||||||
&i2sbus_playback_ops);
|
&i2sbus_playback_ops);
|
||||||
|
dev->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].dev.parent =
|
||||||
|
&dev->ofdev.dev;
|
||||||
i2sdev->out.created = 1;
|
i2sdev->out.created = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1003,6 +1004,8 @@ i2sbus_attach_codec(struct soundbus_dev *dev, struct snd_card *card,
|
||||||
goto out_put_ci_module;
|
goto out_put_ci_module;
|
||||||
snd_pcm_set_ops(dev->pcm, SNDRV_PCM_STREAM_CAPTURE,
|
snd_pcm_set_ops(dev->pcm, SNDRV_PCM_STREAM_CAPTURE,
|
||||||
&i2sbus_record_ops);
|
&i2sbus_record_ops);
|
||||||
|
dev->pcm->streams[SNDRV_PCM_STREAM_CAPTURE].dev.parent =
|
||||||
|
&dev->ofdev.dev;
|
||||||
i2sdev->in.created = 1;
|
i2sdev->in.created = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -673,6 +673,8 @@ static inline int snd_pcm_substream_proc_init(struct snd_pcm_substream *substrea
|
||||||
static inline int snd_pcm_substream_proc_done(struct snd_pcm_substream *substream) { return 0; }
|
static inline int snd_pcm_substream_proc_done(struct snd_pcm_substream *substream) { return 0; }
|
||||||
#endif /* CONFIG_SND_VERBOSE_PROCFS */
|
#endif /* CONFIG_SND_VERBOSE_PROCFS */
|
||||||
|
|
||||||
|
static const struct attribute_group *pcm_dev_attr_groups[];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* snd_pcm_new_stream - create a new PCM stream
|
* snd_pcm_new_stream - create a new PCM stream
|
||||||
* @pcm: the pcm instance
|
* @pcm: the pcm instance
|
||||||
|
@ -698,7 +700,15 @@ int snd_pcm_new_stream(struct snd_pcm *pcm, int stream, int substream_count)
|
||||||
pstr->stream = stream;
|
pstr->stream = stream;
|
||||||
pstr->pcm = pcm;
|
pstr->pcm = pcm;
|
||||||
pstr->substream_count = substream_count;
|
pstr->substream_count = substream_count;
|
||||||
if (substream_count > 0 && !pcm->internal) {
|
if (!substream_count)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
snd_device_initialize(&pstr->dev, pcm->card);
|
||||||
|
pstr->dev.groups = pcm_dev_attr_groups;
|
||||||
|
dev_set_name(&pstr->dev, "pcmC%iD%i%c", pcm->card->number, pcm->device,
|
||||||
|
stream == SNDRV_PCM_STREAM_PLAYBACK ? 'p' : 'c');
|
||||||
|
|
||||||
|
if (!pcm->internal) {
|
||||||
err = snd_pcm_stream_proc_init(pstr);
|
err = snd_pcm_stream_proc_init(pstr);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
pcm_err(pcm, "Error in snd_pcm_stream_proc_init\n");
|
pcm_err(pcm, "Error in snd_pcm_stream_proc_init\n");
|
||||||
|
@ -868,6 +878,8 @@ static void snd_pcm_free_stream(struct snd_pcm_str * pstr)
|
||||||
kfree(setup);
|
kfree(setup);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
if (pstr->substream_count)
|
||||||
|
put_device(&pstr->dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int snd_pcm_free(struct snd_pcm *pcm)
|
static int snd_pcm_free(struct snd_pcm *pcm)
|
||||||
|
@ -1069,9 +1081,7 @@ static int snd_pcm_dev_register(struct snd_device *device)
|
||||||
int cidx, err;
|
int cidx, err;
|
||||||
struct snd_pcm_substream *substream;
|
struct snd_pcm_substream *substream;
|
||||||
struct snd_pcm_notify *notify;
|
struct snd_pcm_notify *notify;
|
||||||
char str[16];
|
|
||||||
struct snd_pcm *pcm;
|
struct snd_pcm *pcm;
|
||||||
struct device *dev;
|
|
||||||
|
|
||||||
if (snd_BUG_ON(!device || !device->device_data))
|
if (snd_BUG_ON(!device || !device->device_data))
|
||||||
return -ENXIO;
|
return -ENXIO;
|
||||||
|
@ -1088,42 +1098,24 @@ static int snd_pcm_dev_register(struct snd_device *device)
|
||||||
continue;
|
continue;
|
||||||
switch (cidx) {
|
switch (cidx) {
|
||||||
case SNDRV_PCM_STREAM_PLAYBACK:
|
case SNDRV_PCM_STREAM_PLAYBACK:
|
||||||
sprintf(str, "pcmC%iD%ip", pcm->card->number, pcm->device);
|
|
||||||
devtype = SNDRV_DEVICE_TYPE_PCM_PLAYBACK;
|
devtype = SNDRV_DEVICE_TYPE_PCM_PLAYBACK;
|
||||||
break;
|
break;
|
||||||
case SNDRV_PCM_STREAM_CAPTURE:
|
case SNDRV_PCM_STREAM_CAPTURE:
|
||||||
sprintf(str, "pcmC%iD%ic", pcm->card->number, pcm->device);
|
|
||||||
devtype = SNDRV_DEVICE_TYPE_PCM_CAPTURE;
|
devtype = SNDRV_DEVICE_TYPE_PCM_CAPTURE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* device pointer to use, pcm->dev takes precedence if
|
|
||||||
* it is assigned, otherwise fall back to card's device
|
|
||||||
* if possible */
|
|
||||||
dev = pcm->dev;
|
|
||||||
if (!dev)
|
|
||||||
dev = snd_card_get_device_link(pcm->card);
|
|
||||||
/* register pcm */
|
/* register pcm */
|
||||||
err = snd_register_device_for_dev(devtype, pcm->card,
|
err = snd_register_device_for_dev(devtype, pcm->card,
|
||||||
pcm->device,
|
pcm->device,
|
||||||
&snd_pcm_f_ops[cidx],
|
&snd_pcm_f_ops[cidx],
|
||||||
pcm, NULL, dev, str);
|
pcm, &pcm->streams[cidx].dev,
|
||||||
|
NULL, NULL);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
list_del(&pcm->list);
|
list_del(&pcm->list);
|
||||||
mutex_unlock(®ister_mutex);
|
mutex_unlock(®ister_mutex);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
dev = snd_get_device(devtype, pcm->card, pcm->device);
|
|
||||||
if (dev) {
|
|
||||||
err = sysfs_create_groups(&dev->kobj,
|
|
||||||
pcm_dev_attr_groups);
|
|
||||||
if (err < 0)
|
|
||||||
dev_warn(dev,
|
|
||||||
"pcm %d:%d: cannot create sysfs groups\n",
|
|
||||||
pcm->card->number, pcm->device);
|
|
||||||
put_device(dev);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (substream = pcm->streams[cidx].substream; substream; substream = substream->next)
|
for (substream = pcm->streams[cidx].substream; substream; substream = substream->next)
|
||||||
snd_pcm_timer_init(substream);
|
snd_pcm_timer_init(substream);
|
||||||
}
|
}
|
||||||
|
|
|
@ -939,7 +939,8 @@ static int azx_attach_pcm_stream(struct hda_bus *bus, struct hda_codec *codec,
|
||||||
chip->card->dev,
|
chip->card->dev,
|
||||||
size, MAX_PREALLOC_SIZE);
|
size, MAX_PREALLOC_SIZE);
|
||||||
/* link to codec */
|
/* link to codec */
|
||||||
pcm->dev = &codec->dev;
|
for (s = 0; s < 2; s++)
|
||||||
|
pcm->streams[s].dev.parent = &codec->dev;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -645,7 +645,6 @@ static struct snd_pcm_ops sst_platform_ops = {
|
||||||
|
|
||||||
static void sst_pcm_free(struct snd_pcm *pcm)
|
static void sst_pcm_free(struct snd_pcm *pcm)
|
||||||
{
|
{
|
||||||
dev_dbg(pcm->dev, "sst_pcm_free called\n");
|
|
||||||
snd_pcm_lib_preallocate_free_for_all(pcm);
|
snd_pcm_lib_preallocate_free_for_all(pcm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue