aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2017-08-30 10:13:25 -0400
committerTakashi Iwai <tiwai@suse.de>2017-08-30 14:44:29 -0400
commit7d8e8292013ab72ae1f1500cbc91f198ccb1826d (patch)
tree5586c0e3b0483c98d1fe210a87246fd70131ba35
parent3454a476f2f5d6d3cac3b3f907190ffc58c4fd6f (diff)
ALSA: Get rid of card power_lock
Currently we're taking power_lock at each card component for assuring the power-up sequence, but it doesn't help anything in the implementation at the moment: it just serializes unnecessarily the callers, but it doesn't protect about the power state change itself. It used to have some usefulness in the early days where we managed the PM manually. But now the suspend/resume core procedure is beyond our hands, and power_lock lost its meaning. This patch drops the power_lock from allover the places. There shouldn't be any issues by this change, as it's no helper regarding the power state change. Rather we'll get better performance by removing the serialization; which is the only slight concern of any behavior change, but it can't be a showstopper, after all. Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r--include/sound/core.h13
-rw-r--r--sound/core/control.c58
-rw-r--r--sound/core/control_compat.c34
-rw-r--r--sound/core/init.c5
-rw-r--r--sound/core/pcm_native.c30
-rw-r--r--sound/soc/soc-core.c2
6 files changed, 53 insertions, 89 deletions
diff --git a/include/sound/core.h b/include/sound/core.h
index 357f36b5ee80..4104a9d1001f 100644
--- a/include/sound/core.h
+++ b/include/sound/core.h
@@ -136,7 +136,6 @@ struct snd_card {
136 136
137#ifdef CONFIG_PM 137#ifdef CONFIG_PM
138 unsigned int power_state; /* power state */ 138 unsigned int power_state; /* power state */
139 struct mutex power_lock; /* power lock */
140 wait_queue_head_t power_sleep; 139 wait_queue_head_t power_sleep;
141#endif 140#endif
142 141
@@ -149,16 +148,6 @@ struct snd_card {
149#define dev_to_snd_card(p) container_of(p, struct snd_card, card_dev) 148#define dev_to_snd_card(p) container_of(p, struct snd_card, card_dev)
150 149
151#ifdef CONFIG_PM 150#ifdef CONFIG_PM
152static inline void snd_power_lock(struct snd_card *card)
153{
154 mutex_lock(&card->power_lock);
155}
156
157static inline void snd_power_unlock(struct snd_card *card)
158{
159 mutex_unlock(&card->power_lock);
160}
161
162static inline unsigned int snd_power_get_state(struct snd_card *card) 151static inline unsigned int snd_power_get_state(struct snd_card *card)
163{ 152{
164 return card->power_state; 153 return card->power_state;
@@ -175,8 +164,6 @@ int snd_power_wait(struct snd_card *card, unsigned int power_state);
175 164
176#else /* ! CONFIG_PM */ 165#else /* ! CONFIG_PM */
177 166
178#define snd_power_lock(card) do { (void)(card); } while (0)
179#define snd_power_unlock(card) do { (void)(card); } while (0)
180static inline int snd_power_wait(struct snd_card *card, unsigned int state) { return 0; } 167static inline int snd_power_wait(struct snd_card *card, unsigned int state) { return 0; }
181#define snd_power_get_state(card) ({ (void)(card); SNDRV_CTL_POWER_D0; }) 168#define snd_power_get_state(card) ({ (void)(card); SNDRV_CTL_POWER_D0; })
182#define snd_power_change_state(card, state) do { (void)(card); } while (0) 169#define snd_power_change_state(card, state) do { (void)(card); } while (0)
diff --git a/sound/core/control.c b/sound/core/control.c
index 51d4b4ad3e1d..56b3e2d49c82 100644
--- a/sound/core/control.c
+++ b/sound/core/control.c
@@ -864,14 +864,14 @@ static int snd_ctl_elem_info_user(struct snd_ctl_file *ctl,
864 864
865 if (copy_from_user(&info, _info, sizeof(info))) 865 if (copy_from_user(&info, _info, sizeof(info)))
866 return -EFAULT; 866 return -EFAULT;
867 snd_power_lock(ctl->card);
868 result = snd_power_wait(ctl->card, SNDRV_CTL_POWER_D0); 867 result = snd_power_wait(ctl->card, SNDRV_CTL_POWER_D0);
869 if (result >= 0) 868 if (result < 0)
870 result = snd_ctl_elem_info(ctl, &info); 869 return result;
871 snd_power_unlock(ctl->card); 870 result = snd_ctl_elem_info(ctl, &info);
872 if (result >= 0) 871 if (result < 0)
873 if (copy_to_user(_info, &info, sizeof(info))) 872 return result;
874 return -EFAULT; 873 if (copy_to_user(_info, &info, sizeof(info)))
874 return -EFAULT;
875 return result; 875 return result;
876} 876}
877 877
@@ -905,17 +905,19 @@ static int snd_ctl_elem_read_user(struct snd_card *card,
905 if (IS_ERR(control)) 905 if (IS_ERR(control))
906 return PTR_ERR(control); 906 return PTR_ERR(control);
907 907
908 snd_power_lock(card);
909 result = snd_power_wait(card, SNDRV_CTL_POWER_D0); 908 result = snd_power_wait(card, SNDRV_CTL_POWER_D0);
910 if (result >= 0) { 909 if (result < 0)
911 down_read(&card->controls_rwsem); 910 goto error;
912 result = snd_ctl_elem_read(card, control); 911
913 up_read(&card->controls_rwsem); 912 down_read(&card->controls_rwsem);
914 } 913 result = snd_ctl_elem_read(card, control);
915 snd_power_unlock(card); 914 up_read(&card->controls_rwsem);
916 if (result >= 0) 915 if (result < 0)
917 if (copy_to_user(_control, control, sizeof(*control))) 916 goto error;
918 result = -EFAULT; 917
918 if (copy_to_user(_control, control, sizeof(*control)))
919 result = -EFAULT;
920 error:
919 kfree(control); 921 kfree(control);
920 return result; 922 return result;
921} 923}
@@ -964,17 +966,19 @@ static int snd_ctl_elem_write_user(struct snd_ctl_file *file,
964 return PTR_ERR(control); 966 return PTR_ERR(control);
965 967
966 card = file->card; 968 card = file->card;
967 snd_power_lock(card);
968 result = snd_power_wait(card, SNDRV_CTL_POWER_D0); 969 result = snd_power_wait(card, SNDRV_CTL_POWER_D0);
969 if (result >= 0) { 970 if (result < 0)
970 down_write(&card->controls_rwsem); 971 goto error;
971 result = snd_ctl_elem_write(card, file, control); 972
972 up_write(&card->controls_rwsem); 973 down_write(&card->controls_rwsem);
973 } 974 result = snd_ctl_elem_write(card, file, control);
974 snd_power_unlock(card); 975 up_write(&card->controls_rwsem);
975 if (result >= 0) 976 if (result < 0)
976 if (copy_to_user(_control, control, sizeof(*control))) 977 goto error;
977 result = -EFAULT; 978
979 if (copy_to_user(_control, control, sizeof(*control)))
980 result = -EFAULT;
981 error:
978 kfree(control); 982 kfree(control);
979 return result; 983 return result;
980} 984}
diff --git a/sound/core/control_compat.c b/sound/core/control_compat.c
index 1fa70766ffab..a848836a5de0 100644
--- a/sound/core/control_compat.c
+++ b/sound/core/control_compat.c
@@ -111,12 +111,10 @@ static int snd_ctl_elem_info_compat(struct snd_ctl_file *ctl,
111 if (get_user(data->value.enumerated.item, &data32->value.enumerated.item)) 111 if (get_user(data->value.enumerated.item, &data32->value.enumerated.item))
112 goto error; 112 goto error;
113 113
114 snd_power_lock(ctl->card);
115 err = snd_power_wait(ctl->card, SNDRV_CTL_POWER_D0); 114 err = snd_power_wait(ctl->card, SNDRV_CTL_POWER_D0);
116 if (err >= 0) 115 if (err < 0)
117 err = snd_ctl_elem_info(ctl, data); 116 goto error;
118 snd_power_unlock(ctl->card); 117 err = snd_ctl_elem_info(ctl, data);
119
120 if (err < 0) 118 if (err < 0)
121 goto error; 119 goto error;
122 /* restore info to 32bit */ 120 /* restore info to 32bit */
@@ -315,14 +313,13 @@ static int ctl_elem_read_user(struct snd_card *card,
315 if (err < 0) 313 if (err < 0)
316 goto error; 314 goto error;
317 315
318 snd_power_lock(card);
319 err = snd_power_wait(card, SNDRV_CTL_POWER_D0); 316 err = snd_power_wait(card, SNDRV_CTL_POWER_D0);
320 if (err >= 0) 317 if (err < 0)
321 err = snd_ctl_elem_read(card, data); 318 goto error;
322 snd_power_unlock(card); 319 err = snd_ctl_elem_read(card, data);
323 if (err >= 0) 320 if (err < 0)
324 err = copy_ctl_value_to_user(userdata, valuep, data, 321 goto error;
325 type, count); 322 err = copy_ctl_value_to_user(userdata, valuep, data, type, count);
326 error: 323 error:
327 kfree(data); 324 kfree(data);
328 return err; 325 return err;
@@ -344,14 +341,13 @@ static int ctl_elem_write_user(struct snd_ctl_file *file,
344 if (err < 0) 341 if (err < 0)
345 goto error; 342 goto error;
346 343
347 snd_power_lock(card);
348 err = snd_power_wait(card, SNDRV_CTL_POWER_D0); 344 err = snd_power_wait(card, SNDRV_CTL_POWER_D0);
349 if (err >= 0) 345 if (err < 0)
350 err = snd_ctl_elem_write(card, file, data); 346 goto error;
351 snd_power_unlock(card); 347 err = snd_ctl_elem_write(card, file, data);
352 if (err >= 0) 348 if (err < 0)
353 err = copy_ctl_value_to_user(userdata, valuep, data, 349 goto error;
354 type, count); 350 err = copy_ctl_value_to_user(userdata, valuep, data, type, count);
355 error: 351 error:
356 kfree(data); 352 kfree(data);
357 return err; 353 return err;
diff --git a/sound/core/init.c b/sound/core/init.c
index 6e219dc23f96..32ebe2f6bc59 100644
--- a/sound/core/init.c
+++ b/sound/core/init.c
@@ -253,7 +253,6 @@ int snd_card_new(struct device *parent, int idx, const char *xid,
253 spin_lock_init(&card->files_lock); 253 spin_lock_init(&card->files_lock);
254 INIT_LIST_HEAD(&card->files_list); 254 INIT_LIST_HEAD(&card->files_list);
255#ifdef CONFIG_PM 255#ifdef CONFIG_PM
256 mutex_init(&card->power_lock);
257 init_waitqueue_head(&card->power_sleep); 256 init_waitqueue_head(&card->power_sleep);
258#endif 257#endif
259 258
@@ -978,8 +977,6 @@ EXPORT_SYMBOL(snd_card_file_remove);
978 * Waits until the power-state is changed. 977 * Waits until the power-state is changed.
979 * 978 *
980 * Return: Zero if successful, or a negative error code. 979 * Return: Zero if successful, or a negative error code.
981 *
982 * Note: the power lock must be active before call.
983 */ 980 */
984int snd_power_wait(struct snd_card *card, unsigned int power_state) 981int snd_power_wait(struct snd_card *card, unsigned int power_state)
985{ 982{
@@ -999,9 +996,7 @@ int snd_power_wait(struct snd_card *card, unsigned int power_state)
999 if (snd_power_get_state(card) == power_state) 996 if (snd_power_get_state(card) == power_state)
1000 break; 997 break;
1001 set_current_state(TASK_UNINTERRUPTIBLE); 998 set_current_state(TASK_UNINTERRUPTIBLE);
1002 snd_power_unlock(card);
1003 schedule_timeout(30 * HZ); 999 schedule_timeout(30 * HZ);
1004 snd_power_lock(card);
1005 } 1000 }
1006 remove_wait_queue(&card->power_sleep, &wait); 1001 remove_wait_queue(&card->power_sleep, &wait);
1007 return result; 1002 return result;
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index cf0433f80067..621142ea9ec6 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -1830,7 +1830,6 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream,
1830 add_wait_queue(&to_check->sleep, &wait); 1830 add_wait_queue(&to_check->sleep, &wait);
1831 snd_pcm_stream_unlock_irq(substream); 1831 snd_pcm_stream_unlock_irq(substream);
1832 up_read(&snd_pcm_link_rwsem); 1832 up_read(&snd_pcm_link_rwsem);
1833 snd_power_unlock(card);
1834 if (runtime->no_period_wakeup) 1833 if (runtime->no_period_wakeup)
1835 tout = MAX_SCHEDULE_TIMEOUT; 1834 tout = MAX_SCHEDULE_TIMEOUT;
1836 else { 1835 else {
@@ -1842,7 +1841,6 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream,
1842 tout = msecs_to_jiffies(tout * 1000); 1841 tout = msecs_to_jiffies(tout * 1000);
1843 } 1842 }
1844 tout = schedule_timeout_interruptible(tout); 1843 tout = schedule_timeout_interruptible(tout);
1845 snd_power_lock(card);
1846 down_read(&snd_pcm_link_rwsem); 1844 down_read(&snd_pcm_link_rwsem);
1847 snd_pcm_stream_lock_irq(substream); 1845 snd_pcm_stream_lock_irq(substream);
1848 remove_wait_queue(&to_check->sleep, &wait); 1846 remove_wait_queue(&to_check->sleep, &wait);
@@ -2764,11 +2762,16 @@ static int snd_pcm_tstamp(struct snd_pcm_substream *substream, int __user *_arg)
2764 return 0; 2762 return 0;
2765} 2763}
2766 2764
2767static int snd_pcm_common_ioctl(struct file *file, 2765static int snd_pcm_common_ioctl1(struct file *file,
2768 struct snd_pcm_substream *substream, 2766 struct snd_pcm_substream *substream,
2769 unsigned int cmd, void __user *arg) 2767 unsigned int cmd, void __user *arg)
2770{ 2768{
2771 struct snd_pcm_file *pcm_file = file->private_data; 2769 struct snd_pcm_file *pcm_file = file->private_data;
2770 int res;
2771
2772 res = snd_power_wait(substream->pcm->card, SNDRV_CTL_POWER_D0);
2773 if (res < 0)
2774 return res;
2772 2775
2773 switch (cmd) { 2776 switch (cmd) {
2774 case SNDRV_PCM_IOCTL_PVERSION: 2777 case SNDRV_PCM_IOCTL_PVERSION:
@@ -2846,21 +2849,6 @@ static int snd_pcm_common_ioctl(struct file *file,
2846 return -ENOTTY; 2849 return -ENOTTY;
2847} 2850}
2848 2851
2849static int snd_pcm_common_ioctl1(struct file *file,
2850 struct snd_pcm_substream *substream,
2851 unsigned int cmd, void __user *arg)
2852{
2853 struct snd_card *card = substream->pcm->card;
2854 int res;
2855
2856 snd_power_lock(card);
2857 res = snd_power_wait(card, SNDRV_CTL_POWER_D0);
2858 if (res >= 0)
2859 res = snd_pcm_common_ioctl(file, substream, cmd, arg);
2860 snd_power_unlock(card);
2861 return res;
2862}
2863
2864static int snd_pcm_playback_ioctl1(struct file *file, 2852static int snd_pcm_playback_ioctl1(struct file *file,
2865 struct snd_pcm_substream *substream, 2853 struct snd_pcm_substream *substream,
2866 unsigned int cmd, void __user *arg) 2854 unsigned int cmd, void __user *arg)
@@ -3064,7 +3052,6 @@ int snd_pcm_kernel_ioctl(struct snd_pcm_substream *substream,
3064{ 3052{
3065 snd_pcm_uframes_t *frames = arg; 3053 snd_pcm_uframes_t *frames = arg;
3066 snd_pcm_sframes_t result; 3054 snd_pcm_sframes_t result;
3067 int err;
3068 3055
3069 switch (cmd) { 3056 switch (cmd) {
3070 case SNDRV_PCM_IOCTL_FORWARD: 3057 case SNDRV_PCM_IOCTL_FORWARD:
@@ -3084,10 +3071,7 @@ int snd_pcm_kernel_ioctl(struct snd_pcm_substream *substream,
3084 case SNDRV_PCM_IOCTL_START: 3071 case SNDRV_PCM_IOCTL_START:
3085 return snd_pcm_start_lock_irq(substream); 3072 return snd_pcm_start_lock_irq(substream);
3086 case SNDRV_PCM_IOCTL_DRAIN: 3073 case SNDRV_PCM_IOCTL_DRAIN:
3087 snd_power_lock(substream->pcm->card); 3074 return snd_pcm_drain(substream, NULL);
3088 err = snd_pcm_drain(substream, NULL);
3089 snd_power_unlock(substream->pcm->card);
3090 return err;
3091 case SNDRV_PCM_IOCTL_DROP: 3075 case SNDRV_PCM_IOCTL_DROP:
3092 return snd_pcm_drop(substream); 3076 return snd_pcm_drop(substream);
3093 case SNDRV_PCM_IOCTL_DELAY: 3077 case SNDRV_PCM_IOCTL_DELAY:
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 13c875e2392a..62c11e26ce5c 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -653,9 +653,7 @@ int snd_soc_suspend(struct device *dev)
653 /* Due to the resume being scheduled into a workqueue we could 653 /* Due to the resume being scheduled into a workqueue we could
654 * suspend before that's finished - wait for it to complete. 654 * suspend before that's finished - wait for it to complete.
655 */ 655 */
656 snd_power_lock(card->snd_card);
657 snd_power_wait(card->snd_card, SNDRV_CTL_POWER_D0); 656 snd_power_wait(card->snd_card, SNDRV_CTL_POWER_D0);
658 snd_power_unlock(card->snd_card);
659 657
660 /* we're going to block userspace touching us until resume completes */ 658 /* we're going to block userspace touching us until resume completes */
661 snd_power_change_state(card->snd_card, SNDRV_CTL_POWER_D3hot); 659 snd_power_change_state(card->snd_card, SNDRV_CTL_POWER_D3hot);