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/init.c | |
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/init.c')
-rw-r--r-- | sound/core/init.c | 205 |
1 files changed, 2 insertions, 203 deletions
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 */ |