aboutsummaryrefslogtreecommitdiffstats
path: root/sound/core
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2005-11-17 09:55:49 -0500
committerJaroslav Kysela <perex@suse.cz>2006-01-03 06:20:19 -0500
commita381a7a66486f11606eccb8866e29848f995278f (patch)
tree4fcc2f971a1f0d509939181b91096a600454b0d6 /sound/core
parentfd66e0d0591dd12eb0bea1e9f3aa194bb93cebbd (diff)
[ALSA] Decentralize PM control
Modules: ALSA Core,Control Midlevel,/oss/Makefile Remove the centralized PM control in the sound core. Each driver is responsible to get callbacks from bus/driver now. SND_GENERIC_DRIVER is removed together with this action. Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/core')
-rw-r--r--sound/core/Kconfig4
-rw-r--r--sound/core/control.c44
-rw-r--r--sound/core/init.c205
-rw-r--r--sound/core/sound.c22
4 files changed, 3 insertions, 272 deletions
diff --git a/sound/core/Kconfig b/sound/core/Kconfig
index 82718836f937..b46efff2e4c4 100644
--- a/sound/core/Kconfig
+++ b/sound/core/Kconfig
@@ -133,7 +133,3 @@ config SND_DEBUG_DETECT
133 help 133 help
134 Say Y here to enable extra-verbose log messages printed when 134 Say Y here to enable extra-verbose log messages printed when
135 detecting devices. 135 detecting devices.
136
137config SND_GENERIC_DRIVER
138 bool
139 depends on SND
diff --git a/sound/core/control.c b/sound/core/control.c
index 1a14338bd516..03ae9bb7d38e 100644
--- a/sound/core/control.c
+++ b/sound/core/control.c
@@ -1023,36 +1023,6 @@ static int snd_ctl_subscribe_events(struct snd_ctl_file *file, int __user *ptr)
1023 return 0; 1023 return 0;
1024} 1024}
1025 1025
1026#ifdef CONFIG_PM
1027/*
1028 * change the power state
1029 */
1030static int snd_ctl_set_power_state(struct snd_card *card, unsigned int power_state)
1031{
1032 switch (power_state) {
1033 case SNDRV_CTL_POWER_D0:
1034 if (card->power_state != power_state) {
1035 card->pm_resume(card);
1036 snd_power_change_state(card, power_state);
1037 }
1038 break;
1039 case SNDRV_CTL_POWER_D3hot:
1040 if (card->power_state != power_state) {
1041 card->pm_suspend(card, PMSG_SUSPEND);
1042 snd_power_change_state(card, power_state);
1043 }
1044 break;
1045 case SNDRV_CTL_POWER_D1:
1046 case SNDRV_CTL_POWER_D2:
1047 case SNDRV_CTL_POWER_D3cold:
1048 /* not supported yet */
1049 default:
1050 return -EINVAL;
1051 }
1052 return 0;
1053}
1054#endif
1055
1056static long snd_ctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg) 1026static long snd_ctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
1057{ 1027{
1058 struct snd_ctl_file *ctl; 1028 struct snd_ctl_file *ctl;
@@ -1092,19 +1062,7 @@ static long snd_ctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg
1092 case SNDRV_CTL_IOCTL_SUBSCRIBE_EVENTS: 1062 case SNDRV_CTL_IOCTL_SUBSCRIBE_EVENTS:
1093 return snd_ctl_subscribe_events(ctl, ip); 1063 return snd_ctl_subscribe_events(ctl, ip);
1094 case SNDRV_CTL_IOCTL_POWER: 1064 case SNDRV_CTL_IOCTL_POWER:
1095 if (get_user(err, ip)) 1065 return -ENOPROTOOPT;
1096 return -EFAULT;
1097 if (!capable(CAP_SYS_ADMIN))
1098 return -EPERM;
1099#ifdef CONFIG_PM
1100 if (card->pm_suspend && card->pm_resume) {
1101 snd_power_lock(card);
1102 err = snd_ctl_set_power_state(card, err);
1103 snd_power_unlock(card);
1104 } else
1105#endif
1106 err = -ENOPROTOOPT;
1107 return err;
1108 case SNDRV_CTL_IOCTL_POWER_STATE: 1066 case SNDRV_CTL_IOCTL_POWER_STATE:
1109#ifdef CONFIG_PM 1067#ifdef CONFIG_PM
1110 return put_user(card->power_state, ip) ? -EFAULT : 0; 1068 return put_user(card->power_state, ip) ? -EFAULT : 0;
diff --git a/sound/core/init.c b/sound/core/init.c
index dca64d199cbe..728bb2ce0bc7 100644
--- a/sound/core/init.c
+++ b/sound/core/init.c
@@ -28,7 +28,6 @@
28#include <linux/ctype.h> 28#include <linux/ctype.h>
29#include <linux/pci.h> 29#include <linux/pci.h>
30#include <linux/pm.h> 30#include <linux/pm.h>
31#include <linux/platform_device.h>
32 31
33#include <sound/core.h> 32#include <sound/core.h>
34#include <sound/control.h> 33#include <sound/control.h>
@@ -229,12 +228,6 @@ int snd_card_disconnect(struct snd_card *card)
229 return 0; 228 return 0;
230} 229}
231 230
232#ifdef CONFIG_SND_GENERIC_DRIVER
233static void snd_generic_device_unregister(struct snd_card *card);
234#else
235#define snd_generic_device_unregister(x) /*NOP*/
236#endif
237
238/** 231/**
239 * snd_card_free - frees given soundcard structure 232 * snd_card_free - frees given soundcard structure
240 * @card: soundcard structure 233 * @card: soundcard structure
@@ -286,7 +279,6 @@ int snd_card_free(struct snd_card *card)
286 snd_printk(KERN_WARNING "unable to free card info\n"); 279 snd_printk(KERN_WARNING "unable to free card info\n");
287 /* Not fatal error */ 280 /* Not fatal error */
288 } 281 }
289 snd_generic_device_unregister(card);
290 while (card->s_f_ops) { 282 while (card->s_f_ops) {
291 s_f_ops = card->s_f_ops; 283 s_f_ops = card->s_f_ops;
292 card->s_f_ops = s_f_ops->next; 284 card->s_f_ops = s_f_ops->next;
@@ -459,7 +451,8 @@ int snd_card_register(struct snd_card *card)
459 451
460static struct snd_info_entry *snd_card_info_entry = NULL; 452static struct snd_info_entry *snd_card_info_entry = NULL;
461 453
462static void snd_card_info_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer) 454static void snd_card_info_read(struct snd_info_entry *entry,
455 struct snd_info_buffer *buffer)
463{ 456{
464 int idx, count; 457 int idx, count;
465 struct snd_card *card; 458 struct snd_card *card;
@@ -666,97 +659,6 @@ int snd_card_file_remove(struct snd_card *card, struct file *file)
666 return 0; 659 return 0;
667} 660}
668 661
669#ifdef CONFIG_SND_GENERIC_DRIVER
670/*
671 * generic device without a proper bus using platform_device
672 * (e.g. ISA)
673 */
674struct snd_generic_device {
675 struct platform_device pdev;
676 struct snd_card *card;
677};
678
679#define get_snd_generic_card(dev) container_of(dev, struct snd_generic_device, pdev)->card
680
681#define SND_GENERIC_NAME "snd_generic"
682
683#ifdef CONFIG_PM
684static int snd_generic_suspend(struct platform_device *dev, pm_message_t state);
685static int snd_generic_resume(struct platform_device *dev);
686#endif
687
688/* initialized in sound.c */
689struct platform_driver snd_generic_driver = {
690#ifdef CONFIG_PM
691 .suspend = snd_generic_suspend,
692 .resume = snd_generic_resume,
693#endif
694 .driver = {
695 .name = SND_GENERIC_NAME,
696 },
697};
698
699void snd_generic_device_release(struct device *dev)
700{
701}
702
703static int snd_generic_device_register(struct snd_card *card)
704{
705 struct snd_generic_device *dev;
706 int err;
707
708 if (card->generic_dev)
709 return 0; /* already registered */
710
711 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
712 if (! dev) {
713 snd_printk(KERN_ERR "can't allocate generic_device\n");
714 return -ENOMEM;
715 }
716
717 dev->pdev.name = SND_GENERIC_NAME;
718 dev->pdev.id = card->number;
719 dev->pdev.dev.release = snd_generic_device_release;
720 dev->card = card;
721 if ((err = platform_device_register(&dev->pdev)) < 0) {
722 kfree(dev);
723 return err;
724 }
725 card->generic_dev = dev;
726 return 0;
727}
728
729static void snd_generic_device_unregister(struct snd_card *card)
730{
731 struct snd_generic_device *dev = card->generic_dev;
732 if (dev) {
733 platform_device_unregister(&dev->pdev);
734 kfree(dev);
735 card->generic_dev = NULL;
736 }
737}
738
739/**
740 * snd_card_set_generic_dev - assign the generic device to the card
741 * @card: soundcard structure
742 *
743 * Assigns a generic device to the card. This function is provided as the
744 * last resort, for devices without any proper bus. Thus this won't override
745 * the device already assigned to the card.
746 *
747 * Returns zero if successful, or a negative error code.
748 */
749int snd_card_set_generic_dev(struct snd_card *card)
750{
751 int err;
752 if ((err = snd_generic_device_register(card)) < 0)
753 return err;
754 if (! card->dev)
755 snd_card_set_dev(card, &card->generic_dev->pdev.dev);
756 return 0;
757}
758#endif /* CONFIG_SND_GENERIC_DRIVER */
759
760#ifdef CONFIG_PM 662#ifdef CONFIG_PM
761/** 663/**
762 * snd_power_wait - wait until the power-state is changed. 664 * snd_power_wait - wait until the power-state is changed.
@@ -800,107 +702,4 @@ int snd_power_wait(struct snd_card *card, unsigned int power_state, struct file
800 return result; 702 return result;
801} 703}
802 704
803/**
804 * snd_card_set_pm_callback - set the PCI power-management callbacks
805 * @card: soundcard structure
806 * @suspend: suspend callback function
807 * @resume: resume callback function
808 * @private_data: private data to pass to the callback functions
809 *
810 * Sets the power-management callback functions of the card.
811 * These callbacks are called from ALSA's common PCI suspend/resume
812 * handler and from the control API.
813 */
814int snd_card_set_pm_callback(struct snd_card *card,
815 int (*suspend)(struct snd_card *, pm_message_t),
816 int (*resume)(struct snd_card *),
817 void *private_data)
818{
819 card->pm_suspend = suspend;
820 card->pm_resume = resume;
821 card->pm_private_data = private_data;
822 return 0;
823}
824
825#ifdef CONFIG_SND_GENERIC_DRIVER
826/* suspend/resume callbacks for snd_generic platform device */
827static int snd_generic_suspend(struct platform_device *dev, pm_message_t state)
828{
829 struct snd_card *card;
830
831 card = get_snd_generic_card(dev);
832 if (card->power_state == SNDRV_CTL_POWER_D3hot)
833 return 0;
834 if (card->pm_suspend)
835 card->pm_suspend(card, PMSG_SUSPEND);
836 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
837 return 0;
838}
839
840static int snd_generic_resume(struct platform_device *dev)
841{
842 struct snd_card *card;
843
844 card = get_snd_generic_card(dev);
845 if (card->power_state == SNDRV_CTL_POWER_D0)
846 return 0;
847 if (card->pm_resume)
848 card->pm_resume(card);
849 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
850 return 0;
851}
852
853/**
854 * snd_card_set_generic_pm_callback - set the generic power-management callbacks
855 * @card: soundcard structure
856 * @suspend: suspend callback function
857 * @resume: resume callback function
858 * @private_data: private data to pass to the callback functions
859 *
860 * Registers the power-management and sets the lowlevel callbacks for
861 * the given card. These callbacks are called from the ALSA's common
862 * PM handler and from the control API.
863 */
864int snd_card_set_generic_pm_callback(struct snd_card *card,
865 int (*suspend)(struct snd_card *, pm_message_t),
866 int (*resume)(struct snd_card *),
867 void *private_data)
868{
869 int err;
870 if ((err = snd_generic_device_register(card)) < 0)
871 return err;
872 return snd_card_set_pm_callback(card, suspend, resume, private_data);
873}
874#endif /* CONFIG_SND_GENERIC_DRIVER */
875
876#ifdef CONFIG_PCI
877int snd_card_pci_suspend(struct pci_dev *dev, pm_message_t state)
878{
879 struct snd_card *card = pci_get_drvdata(dev);
880 int err;
881 if (! card || ! card->pm_suspend)
882 return 0;
883 if (card->power_state == SNDRV_CTL_POWER_D3hot)
884 return 0;
885 err = card->pm_suspend(card, PMSG_SUSPEND);
886 pci_save_state(dev);
887 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
888 return err;
889}
890
891int snd_card_pci_resume(struct pci_dev *dev)
892{
893 struct snd_card *card = pci_get_drvdata(dev);
894 if (! card || ! card->pm_resume)
895 return 0;
896 if (card->power_state == SNDRV_CTL_POWER_D0)
897 return 0;
898 /* restore the PCI config space */
899 pci_restore_state(dev);
900 card->pm_resume(card);
901 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
902 return 0;
903}
904#endif
905
906#endif /* CONFIG_PM */ 705#endif /* CONFIG_PM */
diff --git a/sound/core/sound.c b/sound/core/sound.c
index 04de0084e42a..fb236a6b9c34 100644
--- a/sound/core/sound.c
+++ b/sound/core/sound.c
@@ -32,7 +32,6 @@
32#include <sound/initval.h> 32#include <sound/initval.h>
33#include <linux/kmod.h> 33#include <linux/kmod.h>
34#include <linux/devfs_fs_kernel.h> 34#include <linux/devfs_fs_kernel.h>
35#include <linux/platform_device.h>
36 35
37#define SNDRV_OS_MINORS 256 36#define SNDRV_OS_MINORS 256
38 37
@@ -328,10 +327,6 @@ int __exit snd_minor_info_done(void)
328 * INIT PART 327 * INIT PART
329 */ 328 */
330 329
331#ifdef CONFIG_SND_GENERIC_DRIVER
332extern struct platform_driver snd_generic_driver;
333#endif
334
335static int __init alsa_sound_init(void) 330static int __init alsa_sound_init(void)
336{ 331{
337 short controlnum; 332 short controlnum;
@@ -356,9 +351,6 @@ static int __init alsa_sound_init(void)
356 return -ENOMEM; 351 return -ENOMEM;
357 } 352 }
358 snd_info_minor_register(); 353 snd_info_minor_register();
359#ifdef CONFIG_SND_GENERIC_DRIVER
360 platform_driver_register(&snd_generic_driver);
361#endif
362 for (controlnum = 0; controlnum < cards_limit; controlnum++) 354 for (controlnum = 0; controlnum < cards_limit; controlnum++)
363 devfs_mk_cdev(MKDEV(major, controlnum<<5), S_IFCHR | device_mode, "snd/controlC%d", controlnum); 355 devfs_mk_cdev(MKDEV(major, controlnum<<5), S_IFCHR | device_mode, "snd/controlC%d", controlnum);
364#ifndef MODULE 356#ifndef MODULE
@@ -374,9 +366,6 @@ static void __exit alsa_sound_exit(void)
374 for (controlnum = 0; controlnum < cards_limit; controlnum++) 366 for (controlnum = 0; controlnum < cards_limit; controlnum++)
375 devfs_remove("snd/controlC%d", controlnum); 367 devfs_remove("snd/controlC%d", controlnum);
376 368
377#ifdef CONFIG_SND_GENERIC_DRIVER
378 platform_driver_unregister(&snd_generic_driver);
379#endif
380 snd_info_minor_unregister(); 369 snd_info_minor_unregister();
381 snd_info_done(); 370 snd_info_done();
382 if (unregister_chrdev(major, "alsa") != 0) 371 if (unregister_chrdev(major, "alsa") != 0)
@@ -415,19 +404,8 @@ EXPORT_SYMBOL(snd_card_register);
415EXPORT_SYMBOL(snd_component_add); 404EXPORT_SYMBOL(snd_component_add);
416EXPORT_SYMBOL(snd_card_file_add); 405EXPORT_SYMBOL(snd_card_file_add);
417EXPORT_SYMBOL(snd_card_file_remove); 406EXPORT_SYMBOL(snd_card_file_remove);
418#ifdef CONFIG_SND_GENERIC_DRIVER
419EXPORT_SYMBOL(snd_card_set_generic_dev);
420#endif
421#ifdef CONFIG_PM 407#ifdef CONFIG_PM
422EXPORT_SYMBOL(snd_power_wait); 408EXPORT_SYMBOL(snd_power_wait);
423EXPORT_SYMBOL(snd_card_set_pm_callback);
424#ifdef CONFIG_SND_GENERIC_DRIVER
425EXPORT_SYMBOL(snd_card_set_generic_pm_callback);
426#endif
427#ifdef CONFIG_PCI
428EXPORT_SYMBOL(snd_card_pci_suspend);
429EXPORT_SYMBOL(snd_card_pci_resume);
430#endif
431#endif 409#endif
432 /* device.c */ 410 /* device.c */
433EXPORT_SYMBOL(snd_device_new); 411EXPORT_SYMBOL(snd_device_new);