diff options
author | Takashi Iwai <tiwai@suse.de> | 2005-11-17 09:55:49 -0500 |
---|---|---|
committer | Jaroslav Kysela <perex@suse.cz> | 2006-01-03 06:20:19 -0500 |
commit | a381a7a66486f11606eccb8866e29848f995278f (patch) | |
tree | 4fcc2f971a1f0d509939181b91096a600454b0d6 /sound/core | |
parent | fd66e0d0591dd12eb0bea1e9f3aa194bb93cebbd (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/Kconfig | 4 | ||||
-rw-r--r-- | sound/core/control.c | 44 | ||||
-rw-r--r-- | sound/core/init.c | 205 | ||||
-rw-r--r-- | sound/core/sound.c | 22 |
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 | |||
137 | config 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 | */ | ||
1030 | static 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 | |||
1056 | static long snd_ctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | 1026 | static 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 | ||
233 | static 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 | ||
460 | static struct snd_info_entry *snd_card_info_entry = NULL; | 452 | static struct snd_info_entry *snd_card_info_entry = NULL; |
461 | 453 | ||
462 | static void snd_card_info_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer) | 454 | static 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 | */ | ||
674 | struct 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 | ||
684 | static int snd_generic_suspend(struct platform_device *dev, pm_message_t state); | ||
685 | static int snd_generic_resume(struct platform_device *dev); | ||
686 | #endif | ||
687 | |||
688 | /* initialized in sound.c */ | ||
689 | struct 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 | |||
699 | void snd_generic_device_release(struct device *dev) | ||
700 | { | ||
701 | } | ||
702 | |||
703 | static 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 | |||
729 | static 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 | */ | ||
749 | int 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 | */ | ||
814 | int 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 */ | ||
827 | static 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 | |||
840 | static 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 | */ | ||
864 | int 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 | ||
877 | int 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 | |||
891 | int 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 | ||
332 | extern struct platform_driver snd_generic_driver; | ||
333 | #endif | ||
334 | |||
335 | static int __init alsa_sound_init(void) | 330 | static 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); | |||
415 | EXPORT_SYMBOL(snd_component_add); | 404 | EXPORT_SYMBOL(snd_component_add); |
416 | EXPORT_SYMBOL(snd_card_file_add); | 405 | EXPORT_SYMBOL(snd_card_file_add); |
417 | EXPORT_SYMBOL(snd_card_file_remove); | 406 | EXPORT_SYMBOL(snd_card_file_remove); |
418 | #ifdef CONFIG_SND_GENERIC_DRIVER | ||
419 | EXPORT_SYMBOL(snd_card_set_generic_dev); | ||
420 | #endif | ||
421 | #ifdef CONFIG_PM | 407 | #ifdef CONFIG_PM |
422 | EXPORT_SYMBOL(snd_power_wait); | 408 | EXPORT_SYMBOL(snd_power_wait); |
423 | EXPORT_SYMBOL(snd_card_set_pm_callback); | ||
424 | #ifdef CONFIG_SND_GENERIC_DRIVER | ||
425 | EXPORT_SYMBOL(snd_card_set_generic_pm_callback); | ||
426 | #endif | ||
427 | #ifdef CONFIG_PCI | ||
428 | EXPORT_SYMBOL(snd_card_pci_suspend); | ||
429 | EXPORT_SYMBOL(snd_card_pci_resume); | ||
430 | #endif | ||
431 | #endif | 409 | #endif |
432 | /* device.c */ | 410 | /* device.c */ |
433 | EXPORT_SYMBOL(snd_device_new); | 411 | EXPORT_SYMBOL(snd_device_new); |