mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2025-03-01 12:39:06 +07:00
[ALSA] Introduce snd_card_set_generic_dev()
ALSA Core A new function snd_card_set_generic_dev() is introduced to add the 'generic device' support for devices without proper bus on sysfs. It's a last resort, and should be removed in future when they have a proper bus, instead. Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
parent
6243008b82
commit
ecbcfe36fa
@ -168,6 +168,9 @@ struct _snd_card {
|
|||||||
wait_queue_head_t shutdown_sleep;
|
wait_queue_head_t shutdown_sleep;
|
||||||
struct work_struct free_workq; /* for free in workqueue */
|
struct work_struct free_workq; /* for free in workqueue */
|
||||||
struct device *dev;
|
struct device *dev;
|
||||||
|
#ifdef CONFIG_SND_GENERIC_DRIVER
|
||||||
|
struct snd_generic_device *generic_dev;
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_PM
|
#ifdef CONFIG_PM
|
||||||
int (*pm_suspend)(snd_card_t *card, pm_message_t state);
|
int (*pm_suspend)(snd_card_t *card, pm_message_t state);
|
||||||
@ -176,9 +179,6 @@ struct _snd_card {
|
|||||||
unsigned int power_state; /* power state */
|
unsigned int power_state; /* power state */
|
||||||
struct semaphore power_lock; /* power lock */
|
struct semaphore power_lock; /* power lock */
|
||||||
wait_queue_head_t power_sleep;
|
wait_queue_head_t power_sleep;
|
||||||
#ifdef CONFIG_SND_GENERIC_PM
|
|
||||||
struct snd_generic_device *pm_dev; /* for ISA */
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE)
|
#if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE)
|
||||||
@ -348,6 +348,8 @@ int snd_card_file_remove(snd_card_t *card, struct file *file);
|
|||||||
#ifndef snd_card_set_dev
|
#ifndef snd_card_set_dev
|
||||||
#define snd_card_set_dev(card,devptr) ((card)->dev = (devptr))
|
#define snd_card_set_dev(card,devptr) ((card)->dev = (devptr))
|
||||||
#endif
|
#endif
|
||||||
|
/* register a generic device (for ISA, etc) */
|
||||||
|
int snd_card_set_generic_dev(snd_card_t *card);
|
||||||
|
|
||||||
/* device.c */
|
/* device.c */
|
||||||
|
|
||||||
|
@ -128,6 +128,6 @@ config SND_DEBUG_DETECT
|
|||||||
Say Y here to enable extra-verbose log messages printed when
|
Say Y here to enable extra-verbose log messages printed when
|
||||||
detecting devices.
|
detecting devices.
|
||||||
|
|
||||||
config SND_GENERIC_PM
|
config SND_GENERIC_DRIVER
|
||||||
bool
|
bool
|
||||||
depends on SND
|
depends on SND
|
||||||
|
@ -226,8 +226,10 @@ int snd_card_disconnect(snd_card_t * card)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(CONFIG_PM) && defined(CONFIG_SND_GENERIC_PM)
|
#ifdef CONFIG_SND_GENERIC_DRIVER
|
||||||
static void snd_generic_device_unregister(struct snd_generic_device *dev);
|
static void snd_generic_device_unregister(snd_card_t *card);
|
||||||
|
#else
|
||||||
|
#define snd_generic_device_unregister(x) /*NOP*/
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -253,14 +255,7 @@ int snd_card_free(snd_card_t * card)
|
|||||||
|
|
||||||
#ifdef CONFIG_PM
|
#ifdef CONFIG_PM
|
||||||
wake_up(&card->power_sleep);
|
wake_up(&card->power_sleep);
|
||||||
#ifdef CONFIG_SND_GENERIC_PM
|
|
||||||
if (card->pm_dev) {
|
|
||||||
snd_generic_device_unregister(card->pm_dev);
|
|
||||||
card->pm_dev = NULL;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
|
|
||||||
/* wait, until all devices are ready for the free operation */
|
/* wait, until all devices are ready for the free operation */
|
||||||
wait_event(card->shutdown_sleep, card->files == NULL);
|
wait_event(card->shutdown_sleep, card->files == NULL);
|
||||||
|
|
||||||
@ -288,6 +283,7 @@ int snd_card_free(snd_card_t * card)
|
|||||||
snd_printk(KERN_WARNING "unable to free card info\n");
|
snd_printk(KERN_WARNING "unable to free card info\n");
|
||||||
/* Not fatal error */
|
/* Not fatal error */
|
||||||
}
|
}
|
||||||
|
snd_generic_device_unregister(card);
|
||||||
while (card->s_f_ops) {
|
while (card->s_f_ops) {
|
||||||
s_f_ops = card->s_f_ops;
|
s_f_ops = card->s_f_ops;
|
||||||
card->s_f_ops = s_f_ops->next;
|
card->s_f_ops = s_f_ops->next;
|
||||||
@ -665,6 +661,96 @@ int snd_card_file_remove(snd_card_t *card, struct file *file)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_SND_GENERIC_DRIVER
|
||||||
|
/*
|
||||||
|
* generic device without a proper bus using platform_device
|
||||||
|
* (e.g. ISA)
|
||||||
|
*/
|
||||||
|
struct snd_generic_device {
|
||||||
|
struct platform_device pdev;
|
||||||
|
snd_card_t *card;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define get_snd_generic_card(dev) container_of(to_platform_device(dev), struct snd_generic_device, pdev)->card
|
||||||
|
|
||||||
|
#define SND_GENERIC_NAME "snd_generic"
|
||||||
|
|
||||||
|
#ifdef CONFIG_PM
|
||||||
|
static int snd_generic_suspend(struct device *dev, pm_message_t state, u32 level);
|
||||||
|
static int snd_generic_resume(struct device *dev, u32 level);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* initialized in sound.c */
|
||||||
|
struct device_driver snd_generic_driver = {
|
||||||
|
.name = SND_GENERIC_NAME,
|
||||||
|
.bus = &platform_bus_type,
|
||||||
|
#ifdef CONFIG_PM
|
||||||
|
.suspend = snd_generic_suspend,
|
||||||
|
.resume = snd_generic_resume,
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
void snd_generic_device_release(struct device *dev)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static int snd_generic_device_register(snd_card_t *card)
|
||||||
|
{
|
||||||
|
struct snd_generic_device *dev;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
if (card->generic_dev)
|
||||||
|
return 0; /* already registered */
|
||||||
|
|
||||||
|
dev = kcalloc(1, sizeof(*dev), GFP_KERNEL);
|
||||||
|
if (! dev) {
|
||||||
|
snd_printk(KERN_ERR "can't allocate generic_device\n");
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
dev->pdev.name = SND_GENERIC_NAME;
|
||||||
|
dev->pdev.id = card->number;
|
||||||
|
dev->pdev.dev.release = snd_generic_device_release;
|
||||||
|
dev->card = card;
|
||||||
|
if ((err = platform_device_register(&dev->pdev)) < 0) {
|
||||||
|
kfree(dev);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
card->generic_dev = dev;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void snd_generic_device_unregister(snd_card_t *card)
|
||||||
|
{
|
||||||
|
struct snd_generic_device *dev = card->generic_dev;
|
||||||
|
if (dev) {
|
||||||
|
platform_device_unregister(&dev->pdev);
|
||||||
|
kfree(dev);
|
||||||
|
card->generic_dev = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* snd_card_set_generic_dev - assign the generic device to the card
|
||||||
|
* @card: soundcard structure
|
||||||
|
*
|
||||||
|
* Assigns a generic device to the card. This function is provided as the
|
||||||
|
* last resort, for devices without any proper bus. Thus this won't override
|
||||||
|
* the device already assigned to the card.
|
||||||
|
*
|
||||||
|
* Returns zero if successful, or a negative error code.
|
||||||
|
*/
|
||||||
|
int snd_card_set_generic_dev(snd_card_t *card)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
if ((err = snd_generic_device_register(card)) < 0)
|
||||||
|
return err;
|
||||||
|
if (! card->dev)
|
||||||
|
snd_card_set_dev(card, &card->generic_dev->pdev.dev);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_SND_GENERIC_DRIVER */
|
||||||
|
|
||||||
#ifdef CONFIG_PM
|
#ifdef CONFIG_PM
|
||||||
/**
|
/**
|
||||||
* snd_power_wait - wait until the power-state is changed.
|
* snd_power_wait - wait until the power-state is changed.
|
||||||
@ -730,75 +816,7 @@ int snd_card_set_pm_callback(snd_card_t *card,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_SND_GENERIC_PM
|
#ifdef CONFIG_SND_GENERIC_DRIVER
|
||||||
/*
|
|
||||||
* use platform_device for generic power-management without a proper bus
|
|
||||||
* (e.g. ISA)
|
|
||||||
*/
|
|
||||||
struct snd_generic_device {
|
|
||||||
struct platform_device pdev;
|
|
||||||
snd_card_t *card;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define get_snd_generic_card(dev) container_of(to_platform_device(dev), struct snd_generic_device, pdev)->card
|
|
||||||
|
|
||||||
#define SND_GENERIC_NAME "snd_generic_pm"
|
|
||||||
|
|
||||||
static int snd_generic_suspend(struct device *dev, pm_message_t state, u32 level);
|
|
||||||
static int snd_generic_resume(struct device *dev, u32 level);
|
|
||||||
|
|
||||||
static struct device_driver snd_generic_driver = {
|
|
||||||
.name = SND_GENERIC_NAME,
|
|
||||||
.bus = &platform_bus_type,
|
|
||||||
.suspend = snd_generic_suspend,
|
|
||||||
.resume = snd_generic_resume,
|
|
||||||
};
|
|
||||||
|
|
||||||
static int generic_driver_registered;
|
|
||||||
|
|
||||||
static void generic_driver_unregister(void)
|
|
||||||
{
|
|
||||||
if (generic_driver_registered) {
|
|
||||||
generic_driver_registered--;
|
|
||||||
if (! generic_driver_registered)
|
|
||||||
driver_unregister(&snd_generic_driver);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct snd_generic_device *snd_generic_device_register(snd_card_t *card)
|
|
||||||
{
|
|
||||||
struct snd_generic_device *dev;
|
|
||||||
|
|
||||||
if (! generic_driver_registered) {
|
|
||||||
if (driver_register(&snd_generic_driver) < 0)
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
generic_driver_registered++;
|
|
||||||
|
|
||||||
dev = kcalloc(1, sizeof(*dev), GFP_KERNEL);
|
|
||||||
if (! dev) {
|
|
||||||
generic_driver_unregister();
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
dev->pdev.name = SND_GENERIC_NAME;
|
|
||||||
dev->pdev.id = card->number;
|
|
||||||
dev->card = card;
|
|
||||||
if (platform_device_register(&dev->pdev) < 0) {
|
|
||||||
kfree(dev);
|
|
||||||
generic_driver_unregister();
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
return dev;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void snd_generic_device_unregister(struct snd_generic_device *dev)
|
|
||||||
{
|
|
||||||
platform_device_unregister(&dev->pdev);
|
|
||||||
kfree(dev);
|
|
||||||
generic_driver_unregister();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* suspend/resume callbacks for snd_generic platform device */
|
/* suspend/resume callbacks for snd_generic platform device */
|
||||||
static int snd_generic_suspend(struct device *dev, pm_message_t state, u32 level)
|
static int snd_generic_suspend(struct device *dev, pm_message_t state, u32 level)
|
||||||
{
|
{
|
||||||
@ -846,13 +864,12 @@ int snd_card_set_generic_pm_callback(snd_card_t *card,
|
|||||||
int (*resume)(snd_card_t *),
|
int (*resume)(snd_card_t *),
|
||||||
void *private_data)
|
void *private_data)
|
||||||
{
|
{
|
||||||
card->pm_dev = snd_generic_device_register(card);
|
int err;
|
||||||
if (! card->pm_dev)
|
if ((err = snd_generic_device_register(card)) < 0)
|
||||||
return -ENOMEM;
|
return err;
|
||||||
snd_card_set_pm_callback(card, suspend, resume, private_data);
|
return snd_card_set_pm_callback(card, suspend, resume, private_data);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_SND_GENERIC_PM */
|
#endif /* CONFIG_SND_GENERIC_DRIVER */
|
||||||
|
|
||||||
#ifdef CONFIG_PCI
|
#ifdef CONFIG_PCI
|
||||||
int snd_card_pci_suspend(struct pci_dev *dev, pm_message_t state)
|
int snd_card_pci_suspend(struct pci_dev *dev, pm_message_t state)
|
||||||
|
@ -328,6 +328,10 @@ int __exit snd_minor_info_done(void)
|
|||||||
* INIT PART
|
* INIT PART
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef CONFIG_SND_GENERIC_DRIVER
|
||||||
|
extern struct device_driver snd_generic_driver;
|
||||||
|
#endif
|
||||||
|
|
||||||
static int __init alsa_sound_init(void)
|
static int __init alsa_sound_init(void)
|
||||||
{
|
{
|
||||||
short controlnum;
|
short controlnum;
|
||||||
@ -354,6 +358,9 @@ static int __init alsa_sound_init(void)
|
|||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
snd_info_minor_register();
|
snd_info_minor_register();
|
||||||
|
#ifdef CONFIG_SND_GENERIC_DRIVER
|
||||||
|
driver_register(&snd_generic_driver);
|
||||||
|
#endif
|
||||||
for (controlnum = 0; controlnum < cards_limit; controlnum++)
|
for (controlnum = 0; controlnum < cards_limit; controlnum++)
|
||||||
devfs_mk_cdev(MKDEV(major, controlnum<<5), S_IFCHR | device_mode, "snd/controlC%d", controlnum);
|
devfs_mk_cdev(MKDEV(major, controlnum<<5), S_IFCHR | device_mode, "snd/controlC%d", controlnum);
|
||||||
#ifndef MODULE
|
#ifndef MODULE
|
||||||
@ -369,6 +376,9 @@ static void __exit alsa_sound_exit(void)
|
|||||||
for (controlnum = 0; controlnum < cards_limit; controlnum++)
|
for (controlnum = 0; controlnum < cards_limit; controlnum++)
|
||||||
devfs_remove("snd/controlC%d", controlnum);
|
devfs_remove("snd/controlC%d", controlnum);
|
||||||
|
|
||||||
|
#ifdef CONFIG_SND_GENERIC_DRIVER
|
||||||
|
driver_unregister(&snd_generic_driver);
|
||||||
|
#endif
|
||||||
snd_info_minor_unregister();
|
snd_info_minor_unregister();
|
||||||
snd_info_done();
|
snd_info_done();
|
||||||
snd_memory_done();
|
snd_memory_done();
|
||||||
@ -416,10 +426,13 @@ EXPORT_SYMBOL(snd_card_register);
|
|||||||
EXPORT_SYMBOL(snd_component_add);
|
EXPORT_SYMBOL(snd_component_add);
|
||||||
EXPORT_SYMBOL(snd_card_file_add);
|
EXPORT_SYMBOL(snd_card_file_add);
|
||||||
EXPORT_SYMBOL(snd_card_file_remove);
|
EXPORT_SYMBOL(snd_card_file_remove);
|
||||||
|
#ifdef CONFIG_SND_GENERIC_DRIVER
|
||||||
|
EXPORT_SYMBOL(snd_card_set_generic_dev);
|
||||||
|
#endif
|
||||||
#ifdef CONFIG_PM
|
#ifdef CONFIG_PM
|
||||||
EXPORT_SYMBOL(snd_power_wait);
|
EXPORT_SYMBOL(snd_power_wait);
|
||||||
EXPORT_SYMBOL(snd_card_set_pm_callback);
|
EXPORT_SYMBOL(snd_card_set_pm_callback);
|
||||||
#if defined(CONFIG_PM) && defined(CONFIG_SND_GENERIC_PM)
|
#ifdef CONFIG_SND_GENERIC_DRIVER
|
||||||
EXPORT_SYMBOL(snd_card_set_generic_pm_callback);
|
EXPORT_SYMBOL(snd_card_set_generic_pm_callback);
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_PCI
|
#ifdef CONFIG_PCI
|
||||||
|
Loading…
Reference in New Issue
Block a user