diff options
author | Takashi Iwai <tiwai@suse.de> | 2015-01-29 11:32:26 -0500 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2015-02-02 08:42:42 -0500 |
commit | ef46c7af93f98d07cd0ed891f93a26d135785526 (patch) | |
tree | 6635fa69835d0de4fbc5e1449f70095d9d4817f0 /sound/core | |
parent | 7b46160000197209f7ebca8b92bdbb75795c473f (diff) |
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>
Diffstat (limited to 'sound/core')
-rw-r--r-- | sound/core/pcm.c | 38 |
1 files changed, 15 insertions, 23 deletions
diff --git a/sound/core/pcm.c b/sound/core/pcm.c index 1b7c473720fa..4d5120f7a8ab 100644 --- a/sound/core/pcm.c +++ b/sound/core/pcm.c | |||
@@ -673,6 +673,8 @@ static inline int snd_pcm_substream_proc_init(struct snd_pcm_substream *substrea | |||
673 | static inline int snd_pcm_substream_proc_done(struct snd_pcm_substream *substream) { return 0; } | 673 | static inline int snd_pcm_substream_proc_done(struct snd_pcm_substream *substream) { return 0; } |
674 | #endif /* CONFIG_SND_VERBOSE_PROCFS */ | 674 | #endif /* CONFIG_SND_VERBOSE_PROCFS */ |
675 | 675 | ||
676 | static const struct attribute_group *pcm_dev_attr_groups[]; | ||
677 | |||
676 | /** | 678 | /** |
677 | * snd_pcm_new_stream - create a new PCM stream | 679 | * snd_pcm_new_stream - create a new PCM stream |
678 | * @pcm: the pcm instance | 680 | * @pcm: the pcm instance |
@@ -698,7 +700,15 @@ int snd_pcm_new_stream(struct snd_pcm *pcm, int stream, int substream_count) | |||
698 | pstr->stream = stream; | 700 | pstr->stream = stream; |
699 | pstr->pcm = pcm; | 701 | pstr->pcm = pcm; |
700 | pstr->substream_count = substream_count; | 702 | pstr->substream_count = substream_count; |
701 | if (substream_count > 0 && !pcm->internal) { | 703 | if (!substream_count) |
704 | return 0; | ||
705 | |||
706 | snd_device_initialize(&pstr->dev, pcm->card); | ||
707 | pstr->dev.groups = pcm_dev_attr_groups; | ||
708 | dev_set_name(&pstr->dev, "pcmC%iD%i%c", pcm->card->number, pcm->device, | ||
709 | stream == SNDRV_PCM_STREAM_PLAYBACK ? 'p' : 'c'); | ||
710 | |||
711 | if (!pcm->internal) { | ||
702 | err = snd_pcm_stream_proc_init(pstr); | 712 | err = snd_pcm_stream_proc_init(pstr); |
703 | if (err < 0) { | 713 | if (err < 0) { |
704 | pcm_err(pcm, "Error in snd_pcm_stream_proc_init\n"); | 714 | 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) | |||
868 | kfree(setup); | 878 | kfree(setup); |
869 | } | 879 | } |
870 | #endif | 880 | #endif |
881 | if (pstr->substream_count) | ||
882 | put_device(&pstr->dev); | ||
871 | } | 883 | } |
872 | 884 | ||
873 | static int snd_pcm_free(struct snd_pcm *pcm) | 885 | static int snd_pcm_free(struct snd_pcm *pcm) |
@@ -1069,9 +1081,7 @@ static int snd_pcm_dev_register(struct snd_device *device) | |||
1069 | int cidx, err; | 1081 | int cidx, err; |
1070 | struct snd_pcm_substream *substream; | 1082 | struct snd_pcm_substream *substream; |
1071 | struct snd_pcm_notify *notify; | 1083 | struct snd_pcm_notify *notify; |
1072 | char str[16]; | ||
1073 | struct snd_pcm *pcm; | 1084 | struct snd_pcm *pcm; |
1074 | struct device *dev; | ||
1075 | 1085 | ||
1076 | if (snd_BUG_ON(!device || !device->device_data)) | 1086 | if (snd_BUG_ON(!device || !device->device_data)) |
1077 | return -ENXIO; | 1087 | return -ENXIO; |
@@ -1088,42 +1098,24 @@ static int snd_pcm_dev_register(struct snd_device *device) | |||
1088 | continue; | 1098 | continue; |
1089 | switch (cidx) { | 1099 | switch (cidx) { |
1090 | case SNDRV_PCM_STREAM_PLAYBACK: | 1100 | case SNDRV_PCM_STREAM_PLAYBACK: |
1091 | sprintf(str, "pcmC%iD%ip", pcm->card->number, pcm->device); | ||
1092 | devtype = SNDRV_DEVICE_TYPE_PCM_PLAYBACK; | 1101 | devtype = SNDRV_DEVICE_TYPE_PCM_PLAYBACK; |
1093 | break; | 1102 | break; |
1094 | case SNDRV_PCM_STREAM_CAPTURE: | 1103 | case SNDRV_PCM_STREAM_CAPTURE: |
1095 | sprintf(str, "pcmC%iD%ic", pcm->card->number, pcm->device); | ||
1096 | devtype = SNDRV_DEVICE_TYPE_PCM_CAPTURE; | 1104 | devtype = SNDRV_DEVICE_TYPE_PCM_CAPTURE; |
1097 | break; | 1105 | break; |
1098 | } | 1106 | } |
1099 | /* device pointer to use, pcm->dev takes precedence if | ||
1100 | * it is assigned, otherwise fall back to card's device | ||
1101 | * if possible */ | ||
1102 | dev = pcm->dev; | ||
1103 | if (!dev) | ||
1104 | dev = snd_card_get_device_link(pcm->card); | ||
1105 | /* register pcm */ | 1107 | /* register pcm */ |
1106 | err = snd_register_device_for_dev(devtype, pcm->card, | 1108 | err = snd_register_device_for_dev(devtype, pcm->card, |
1107 | pcm->device, | 1109 | pcm->device, |
1108 | &snd_pcm_f_ops[cidx], | 1110 | &snd_pcm_f_ops[cidx], |
1109 | pcm, NULL, dev, str); | 1111 | pcm, &pcm->streams[cidx].dev, |
1112 | NULL, NULL); | ||
1110 | if (err < 0) { | 1113 | if (err < 0) { |
1111 | list_del(&pcm->list); | 1114 | list_del(&pcm->list); |
1112 | mutex_unlock(®ister_mutex); | 1115 | mutex_unlock(®ister_mutex); |
1113 | return err; | 1116 | return err; |
1114 | } | 1117 | } |
1115 | 1118 | ||
1116 | dev = snd_get_device(devtype, pcm->card, pcm->device); | ||
1117 | if (dev) { | ||
1118 | err = sysfs_create_groups(&dev->kobj, | ||
1119 | pcm_dev_attr_groups); | ||
1120 | if (err < 0) | ||
1121 | dev_warn(dev, | ||
1122 | "pcm %d:%d: cannot create sysfs groups\n", | ||
1123 | pcm->card->number, pcm->device); | ||
1124 | put_device(dev); | ||
1125 | } | ||
1126 | |||
1127 | for (substream = pcm->streams[cidx].substream; substream; substream = substream->next) | 1119 | for (substream = pcm->streams[cidx].substream; substream; substream = substream->next) |
1128 | snd_pcm_timer_init(substream); | 1120 | snd_pcm_timer_init(substream); |
1129 | } | 1121 | } |