@@ -226,8 +226,10 @@ int snd_card_disconnect(snd_card_t * card)
226226 return 0 ;
227227}
228228
229- #if defined(CONFIG_PM ) && defined(CONFIG_SND_GENERIC_PM )
230- static void snd_generic_device_unregister (struct snd_generic_device * dev );
229+ #ifdef CONFIG_SND_GENERIC_DRIVER
230+ static void snd_generic_device_unregister (snd_card_t * card );
231+ #else
232+ #define snd_generic_device_unregister (x ) /*NOP*/
231233#endif
232234
233235/**
@@ -253,14 +255,7 @@ int snd_card_free(snd_card_t * card)
253255
254256#ifdef CONFIG_PM
255257 wake_up (& card -> power_sleep );
256- #ifdef CONFIG_SND_GENERIC_PM
257- if (card -> pm_dev ) {
258- snd_generic_device_unregister (card -> pm_dev );
259- card -> pm_dev = NULL ;
260- }
261- #endif
262258#endif
263-
264259 /* wait, until all devices are ready for the free operation */
265260 wait_event (card -> shutdown_sleep , card -> files == NULL );
266261
@@ -288,6 +283,7 @@ int snd_card_free(snd_card_t * card)
288283 snd_printk (KERN_WARNING "unable to free card info\n" );
289284 /* Not fatal error */
290285 }
286+ snd_generic_device_unregister (card );
291287 while (card -> s_f_ops ) {
292288 s_f_ops = card -> s_f_ops ;
293289 card -> s_f_ops = s_f_ops -> next ;
@@ -665,6 +661,96 @@ int snd_card_file_remove(snd_card_t *card, struct file *file)
665661 return 0 ;
666662}
667663
664+ #ifdef CONFIG_SND_GENERIC_DRIVER
665+ /*
666+ * generic device without a proper bus using platform_device
667+ * (e.g. ISA)
668+ */
669+ struct snd_generic_device {
670+ struct platform_device pdev ;
671+ snd_card_t * card ;
672+ };
673+
674+ #define get_snd_generic_card (dev ) container_of(to_platform_device(dev), struct snd_generic_device, pdev)->card
675+
676+ #define SND_GENERIC_NAME "snd_generic"
677+
678+ #ifdef CONFIG_PM
679+ static int snd_generic_suspend (struct device * dev , pm_message_t state , u32 level );
680+ static int snd_generic_resume (struct device * dev , u32 level );
681+ #endif
682+
683+ /* initialized in sound.c */
684+ struct device_driver snd_generic_driver = {
685+ .name = SND_GENERIC_NAME ,
686+ .bus = & platform_bus_type ,
687+ #ifdef CONFIG_PM
688+ .suspend = snd_generic_suspend ,
689+ .resume = snd_generic_resume ,
690+ #endif
691+ };
692+
693+ void snd_generic_device_release (struct device * dev )
694+ {
695+ }
696+
697+ static int snd_generic_device_register (snd_card_t * card )
698+ {
699+ struct snd_generic_device * dev ;
700+ int err ;
701+
702+ if (card -> generic_dev )
703+ return 0 ; /* already registered */
704+
705+ dev = kcalloc (1 , sizeof (* dev ), GFP_KERNEL );
706+ if (! dev ) {
707+ snd_printk (KERN_ERR "can't allocate generic_device\n" );
708+ return - ENOMEM ;
709+ }
710+
711+ dev -> pdev .name = SND_GENERIC_NAME ;
712+ dev -> pdev .id = card -> number ;
713+ dev -> pdev .dev .release = snd_generic_device_release ;
714+ dev -> card = card ;
715+ if ((err = platform_device_register (& dev -> pdev )) < 0 ) {
716+ kfree (dev );
717+ return err ;
718+ }
719+ card -> generic_dev = dev ;
720+ return 0 ;
721+ }
722+
723+ static void snd_generic_device_unregister (snd_card_t * card )
724+ {
725+ struct snd_generic_device * dev = card -> generic_dev ;
726+ if (dev ) {
727+ platform_device_unregister (& dev -> pdev );
728+ kfree (dev );
729+ card -> generic_dev = NULL ;
730+ }
731+ }
732+
733+ /**
734+ * snd_card_set_generic_dev - assign the generic device to the card
735+ * @card: soundcard structure
736+ *
737+ * Assigns a generic device to the card. This function is provided as the
738+ * last resort, for devices without any proper bus. Thus this won't override
739+ * the device already assigned to the card.
740+ *
741+ * Returns zero if successful, or a negative error code.
742+ */
743+ int snd_card_set_generic_dev (snd_card_t * card )
744+ {
745+ int err ;
746+ if ((err = snd_generic_device_register (card )) < 0 )
747+ return err ;
748+ if (! card -> dev )
749+ snd_card_set_dev (card , & card -> generic_dev -> pdev .dev );
750+ return 0 ;
751+ }
752+ #endif /* CONFIG_SND_GENERIC_DRIVER */
753+
668754#ifdef CONFIG_PM
669755/**
670756 * snd_power_wait - wait until the power-state is changed.
@@ -730,75 +816,7 @@ int snd_card_set_pm_callback(snd_card_t *card,
730816 return 0 ;
731817}
732818
733- #ifdef CONFIG_SND_GENERIC_PM
734- /*
735- * use platform_device for generic power-management without a proper bus
736- * (e.g. ISA)
737- */
738- struct snd_generic_device {
739- struct platform_device pdev ;
740- snd_card_t * card ;
741- };
742-
743- #define get_snd_generic_card (dev ) container_of(to_platform_device(dev), struct snd_generic_device, pdev)->card
744-
745- #define SND_GENERIC_NAME "snd_generic_pm"
746-
747- static int snd_generic_suspend (struct device * dev , pm_message_t state , u32 level );
748- static int snd_generic_resume (struct device * dev , u32 level );
749-
750- static struct device_driver snd_generic_driver = {
751- .name = SND_GENERIC_NAME ,
752- .bus = & platform_bus_type ,
753- .suspend = snd_generic_suspend ,
754- .resume = snd_generic_resume ,
755- };
756-
757- static int generic_driver_registered ;
758-
759- static void generic_driver_unregister (void )
760- {
761- if (generic_driver_registered ) {
762- generic_driver_registered -- ;
763- if (! generic_driver_registered )
764- driver_unregister (& snd_generic_driver );
765- }
766- }
767-
768- static struct snd_generic_device * snd_generic_device_register (snd_card_t * card )
769- {
770- struct snd_generic_device * dev ;
771-
772- if (! generic_driver_registered ) {
773- if (driver_register (& snd_generic_driver ) < 0 )
774- return NULL ;
775- }
776- generic_driver_registered ++ ;
777-
778- dev = kcalloc (1 , sizeof (* dev ), GFP_KERNEL );
779- if (! dev ) {
780- generic_driver_unregister ();
781- return NULL ;
782- }
783-
784- dev -> pdev .name = SND_GENERIC_NAME ;
785- dev -> pdev .id = card -> number ;
786- dev -> card = card ;
787- if (platform_device_register (& dev -> pdev ) < 0 ) {
788- kfree (dev );
789- generic_driver_unregister ();
790- return NULL ;
791- }
792- return dev ;
793- }
794-
795- static void snd_generic_device_unregister (struct snd_generic_device * dev )
796- {
797- platform_device_unregister (& dev -> pdev );
798- kfree (dev );
799- generic_driver_unregister ();
800- }
801-
819+ #ifdef CONFIG_SND_GENERIC_DRIVER
802820/* suspend/resume callbacks for snd_generic platform device */
803821static int snd_generic_suspend (struct device * dev , pm_message_t state , u32 level )
804822{
@@ -846,13 +864,12 @@ int snd_card_set_generic_pm_callback(snd_card_t *card,
846864 int (* resume )(snd_card_t * ),
847865 void * private_data )
848866{
849- card -> pm_dev = snd_generic_device_register (card );
850- if (! card -> pm_dev )
851- return - ENOMEM ;
852- snd_card_set_pm_callback (card , suspend , resume , private_data );
853- return 0 ;
867+ int err ;
868+ if ((err = snd_generic_device_register (card )) < 0 )
869+ return err ;
870+ return snd_card_set_pm_callback (card , suspend , resume , private_data );
854871}
855- #endif /* CONFIG_SND_GENERIC_PM */
872+ #endif /* CONFIG_SND_GENERIC_DRIVER */
856873
857874#ifdef CONFIG_PCI
858875int snd_card_pci_suspend (struct pci_dev * dev , pm_message_t state )
0 commit comments