/*
 *  Initialization routines
 *  Copyright (c) by Jaroslav Kysela <perex@suse.cz>
 *
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation; either version 2 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program; if not, write to the Free Software
 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 *
 */

#include <sound/driver.h>
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/file.h>
#include <linux/slab.h>
#include <linux/time.h>
#include <linux/ctype.h>
#include <linux/pci.h>
#include <linux/pm.h>
#include <sound/core.h>
#include <sound/control.h>
#include <sound/info.h>

struct snd_shutdown_f_ops {
	struct file_operations f_ops;
	struct snd_shutdown_f_ops *next;
};

unsigned int snd_cards_lock = 0;	/* locked for registering/using */
snd_card_t *snd_cards[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = NULL};
DEFINE_RWLOCK(snd_card_rwlock);

#if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE)
int (*snd_mixer_oss_notify_callback)(snd_card_t *card, int free_flag);
#endif

static void snd_card_id_read(snd_info_entry_t *entry, snd_info_buffer_t * buffer)
{
	snd_iprintf(buffer, "%s\n", entry->card->id);
}

static void snd_card_free_thread(void * __card);

/**
 *  snd_card_new - create and initialize a soundcard structure
 *  @idx: card index (address) [0 ... (SNDRV_CARDS-1)]
 *  @xid: card identification (ASCII string)
 *  @module: top level module for locking
 *  @extra_size: allocate this extra size after the main soundcard structure
 *
 *  Creates and initializes a soundcard structure.
 *
 *  Returns kmallocated snd_card_t structure. Creates the ALSA control interface
 *  (which is blocked until snd_card_register function is called).
 */
snd_card_t *snd_card_new(int idx, const char *xid,
			 struct module *module, int extra_size)
{
	snd_card_t *card;
	int err;

	if (extra_size < 0)
		extra_size = 0;
	card = kcalloc(1, sizeof(*card) + extra_size, GFP_KERNEL);
	if (card == NULL)
		return NULL;
	if (xid) {
		if (!snd_info_check_reserved_words(xid))
			goto __error;
		strlcpy(card->id, xid, sizeof(card->id));
	}
	err = 0;
	write_lock(&snd_card_rwlock);
	if (idx < 0) {
		int idx2;
		for (idx2 = 0; idx2 < SNDRV_CARDS; idx2++)
			if (~snd_cards_lock & idx & 1<<idx2) {
				idx = idx2;
				if (idx >= snd_ecards_limit)
					snd_ecards_limit = idx + 1;
				break;
			}
	} else if (idx < snd_ecards_limit) {
		if (snd_cards_lock & (1 << idx))
			err = -ENODEV;	/* invalid */
	} else if (idx < SNDRV_CARDS)
		snd_ecards_limit = idx + 1; /* increase the limit */
	else
		err = -ENODEV;
	if (idx < 0 || err < 0) {
		write_unlock(&snd_card_rwlock);
		snd_printk(KERN_ERR "cannot find the slot for index %d (range 0-%i)\n", idx, snd_ecards_limit - 1);
		goto __error;
	}
	snd_cards_lock |= 1 << idx;		/* lock it */
	write_unlock(&snd_card_rwlock);
	card->number = idx;
	card->module = module;
	INIT_LIST_HEAD(&card->devices);
	init_rwsem(&card->controls_rwsem);
	rwlock_init(&card->ctl_files_rwlock);
	INIT_LIST_HEAD(&card->controls);
	INIT_LIST_HEAD(&card->ctl_files);
	spin_lock_init(&card->files_lock);
	init_waitqueue_head(&card->shutdown_sleep);
	INIT_WORK(&card->free_workq, snd_card_free_thread, card);
#ifdef CONFIG_PM
	init_MUTEX(&card->power_lock);
	init_waitqueue_head(&card->power_sleep);
#endif
	/* the control interface cannot be accessed from the user space until */
	/* snd_cards_bitmask and snd_cards are set with snd_card_register */
	if ((err = snd_ctl_create(card)) < 0) {
		snd_printd("unable to register control minors\n");
		goto __error;
	}
	if ((err = snd_info_card_create(card)) < 0) {
		snd_printd("unable to create card info\n");
		goto __error_ctl;
	}
	if (extra_size > 0)
		card->private_data = (char *)card + sizeof(snd_card_t);
	return card;

      __error_ctl:
	snd_device_free_all(card, SNDRV_DEV_CMD_PRE);
      __error:
	kfree(card);
      	return NULL;
}

static unsigned int snd_disconnect_poll(struct file * file, poll_table * wait)
{
	return POLLERR | POLLNVAL;
}

/**
 *  snd_card_disconnect - disconnect all APIs from the file-operations (user space)
 *  @card: soundcard structure
 *
 *  Disconnects all APIs from the file-operations (user space).
 *
 *  Returns zero, otherwise a negative error code.
 *
 *  Note: The current implementation replaces all active file->f_op with special
 *        dummy file operations (they do nothing except release).
 */
int snd_card_disconnect(snd_card_t * card)
{
	struct snd_monitor_file *mfile;
	struct file *file;
	struct snd_shutdown_f_ops *s_f_ops;
	struct file_operations *f_ops, *old_f_ops;
	int err;

	spin_lock(&card->files_lock);
	if (card->shutdown) {
		spin_unlock(&card->files_lock);
		return 0;
	}
	card->shutdown = 1;
	spin_unlock(&card->files_lock);

	/* phase 1: disable fops (user space) operations for ALSA API */
	write_lock(&snd_card_rwlock);
	snd_cards[card->number] = NULL;
	write_unlock(&snd_card_rwlock);
	
	/* phase 2: replace file->f_op with special dummy operations */
	
	spin_lock(&card->files_lock);
	mfile = card->files;
	while (mfile) {
		file = mfile->file;

		/* it's critical part, use endless loop */
		/* we have no room to fail */
		s_f_ops = kmalloc(sizeof(struct snd_shutdown_f_ops), GFP_ATOMIC);
		if (s_f_ops == NULL)
			panic("Atomic allocation failed for snd_shutdown_f_ops!");

		f_ops = &s_f_ops->f_ops;

		memset(f_ops, 0, sizeof(*f_ops));
		f_ops->owner = file->f_op->owner;
		f_ops->release = file->f_op->release;
		f_ops->poll = snd_disconnect_poll;

		s_f_ops->next = card->s_f_ops;
		card->s_f_ops = s_f_ops;
		
		f_ops = fops_get(f_ops);

		old_f_ops = file->f_op;
		file->f_op = f_ops;	/* must be atomic */
		fops_put(old_f_ops);
		
		mfile = mfile->next;
	}
	spin_unlock(&card->files_lock);	

	/* phase 3: notify all connected devices about disconnection */
	/* at this point, they cannot respond to any calls except release() */

#if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE)
	if (snd_mixer_oss_notify_callback)
		snd_mixer_oss_notify_callback(card, SND_MIXER_OSS_NOTIFY_DISCONNECT);
#endif

	/* notify all devices that we are disconnected */
	err = snd_device_disconnect_all(card);
	if (err < 0)
		snd_printk(KERN_ERR "not all devices for card %i can be disconnected\n", card->number);

	return 0;	
}

#if defined(CONFIG_PM) && defined(CONFIG_SND_GENERIC_PM)
static void snd_generic_device_unregister(struct snd_generic_device *dev);
#endif

/**
 *  snd_card_free - frees given soundcard structure
 *  @card: soundcard structure
 *
 *  This function releases the soundcard structure and the all assigned
 *  devices automatically.  That is, you don't have to release the devices
 *  by yourself.
 *
 *  Returns zero. Frees all associated devices and frees the control
 *  interface associated to given soundcard.
 */
int snd_card_free(snd_card_t * card)
{
	struct snd_shutdown_f_ops *s_f_ops;

	if (card == NULL)
		return -EINVAL;
	write_lock(&snd_card_rwlock);
	snd_cards[card->number] = NULL;
	write_unlock(&snd_card_rwlock);

#ifdef CONFIG_PM
	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

	/* wait, until all devices are ready for the free operation */
	wait_event(card->shutdown_sleep, card->files == NULL);

#if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE)
	if (snd_mixer_oss_notify_callback)
		snd_mixer_oss_notify_callback(card, SND_MIXER_OSS_NOTIFY_FREE);
#endif
	if (snd_device_free_all(card, SNDRV_DEV_CMD_PRE) < 0) {
		snd_printk(KERN_ERR "unable to free all devices (pre)\n");
		/* Fatal, but this situation should never occur */
	}
	if (snd_device_free_all(card, SNDRV_DEV_CMD_NORMAL) < 0) {
		snd_printk(KERN_ERR "unable to free all devices (normal)\n");
		/* Fatal, but this situation should never occur */
	}
	if (snd_device_free_all(card, SNDRV_DEV_CMD_POST) < 0) {
		snd_printk(KERN_ERR "unable to free all devices (post)\n");
		/* Fatal, but this situation should never occur */
	}
	if (card->private_free)
		card->private_free(card);
	if (card->proc_id)
		snd_info_unregister(card->proc_id);
	if (snd_info_card_free(card) < 0) {
		snd_printk(KERN_WARNING "unable to free card info\n");
		/* Not fatal error */
	}
	while (card->s_f_ops) {
		s_f_ops = card->s_f_ops;
		card->s_f_ops = s_f_ops->next;
		kfree(s_f_ops);
	}
	write_lock(&snd_card_rwlock);
	snd_cards_lock &= ~(1 << card->number);
	write_unlock(&snd_card_rwlock);
	kfree(card);
	return 0;
}

static void snd_card_free_thread(void * __card)
{
	snd_card_t *card = __card;
	struct module * module = card->module;

	if (!try_module_get(module)) {
		snd_printk(KERN_ERR "unable to lock toplevel module for card %i in free thread\n", card->number);
		module = NULL;
	}

	snd_card_free(card);

	module_put(module);
}

/**
 *  snd_card_free_in_thread - call snd_card_free() in thread
 *  @card: soundcard structure
 *
 *  This function schedules the call of snd_card_free() function in a
 *  work queue.  When all devices are released (non-busy), the work
 *  is woken up and calls snd_card_free().
 *
 *  When a card can be disconnected at any time by hotplug service,
 *  this function should be used in disconnect (or detach) callback
 *  instead of calling snd_card_free() directly.
 *  
 *  Returns - zero otherwise a negative error code if the start of thread failed.
 */
int snd_card_free_in_thread(snd_card_t * card)
{
	if (card->files == NULL) {
		snd_card_free(card);
		return 0;
	}

	if (schedule_work(&card->free_workq))
		return 0;

	snd_printk(KERN_ERR "schedule_work() failed in snd_card_free_in_thread for card %i\n", card->number);
	/* try to free the structure immediately */
	snd_card_free(card);
	return -EFAULT;
}

static void choose_default_id(snd_card_t * card)
{
	int i, len, idx_flag = 0, loops = 8;
	char *id, *spos;
	
	id = spos = card->shortname;	
	while (*id != '\0') {
		if (*id == ' ')
			spos = id + 1;
		id++;
	}
	id = card->id;
	while (*spos != '\0' && !isalnum(*spos))
		spos++;
	if (isdigit(*spos))
		*id++ = isalpha(card->shortname[0]) ? card->shortname[0] : 'D';
	while (*spos != '\0' && (size_t)(id - card->id) < sizeof(card->id) - 1) {
		if (isalnum(*spos))
			*id++ = *spos;
		spos++;
	}
	*id = '\0';

	id = card->id;
	
	if (*id == '\0')
		strcpy(id, "default");

	while (1) {
	      	if (loops-- == 0) {
      			snd_printk(KERN_ERR "unable to choose default card id (%s)\n", id);
      			strcpy(card->id, card->proc_root->name);
      			return;
      		}
	      	if (!snd_info_check_reserved_words(id))
      			goto __change;
		for (i = 0; i < snd_ecards_limit; i++) {
			if (snd_cards[i] && !strcmp(snd_cards[i]->id, id))
				goto __change;
		}
		break;

	      __change:
		len = strlen(id);
		if (idx_flag)
			id[len-1]++;
		else if ((size_t)len <= sizeof(card->id) - 3) {
			strcat(id, "_1");
			idx_flag++;
		} else {
			spos = id + len - 2;
			if ((size_t)len <= sizeof(card->id) - 2)
				spos++;
			*spos++ = '_';
			*spos++ = '1';
			*spos++ = '\0';
			idx_flag++;
		}
	}
}

/**
 *  snd_card_register - register the soundcard
 *  @card: soundcard structure
 *
 *  This function registers all the devices assigned to the soundcard.
 *  Until calling this, the ALSA control interface is blocked from the
 *  external accesses.  Thus, you should call this function at the end
 *  of the initialization of the card.
 *
 *  Returns zero otherwise a negative error code if the registrain failed.
 */
int snd_card_register(snd_card_t * card)
{
	int err;
	snd_info_entry_t *entry;

	snd_runtime_check(card != NULL, return -EINVAL);
	if ((err = snd_device_register_all(card)) < 0)
		return err;
	write_lock(&snd_card_rwlock);
	if (snd_cards[card->number]) {
		/* already registered */
		write_unlock(&snd_card_rwlock);
		return 0;
	}
	if (card->id[0] == '\0')
		choose_default_id(card);
	snd_cards[card->number] = card;
	write_unlock(&snd_card_rwlock);
	if ((err = snd_info_card_register(card)) < 0) {
		snd_printd("unable to create card info\n");
		goto __skip_info;
	}
	if ((entry = snd_info_create_card_entry(card, "id", card->proc_root)) == NULL) {
		snd_printd("unable to create card entry\n");
		goto __skip_info;
	}
	entry->c.text.read_size = PAGE_SIZE;
	entry->c.text.read = snd_card_id_read;
	if (snd_info_register(entry) < 0) {
		snd_info_free_entry(entry);
		entry = NULL;
	}
	card->proc_id = entry;
      __skip_info:
#if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE)
	if (snd_mixer_oss_notify_callback)
		snd_mixer_oss_notify_callback(card, SND_MIXER_OSS_NOTIFY_REGISTER);
#endif
	return 0;
}

static snd_info_entry_t *snd_card_info_entry = NULL;

static void snd_card_info_read(snd_info_entry_t *entry, snd_info_buffer_t * buffer)
{
	int idx, count;
	snd_card_t *card;

	for (idx = count = 0; idx < SNDRV_CARDS; idx++) {
		read_lock(&snd_card_rwlock);
		if ((card = snd_cards[idx]) != NULL) {
			count++;
			snd_iprintf(buffer, "%i [%-15s]: %s - %s\n",
					idx,
					card->id,
					card->driver,
					card->shortname);
			snd_iprintf(buffer, "                     %s\n",
					card->longname);
		}
		read_unlock(&snd_card_rwlock);
	}
	if (!count)
		snd_iprintf(buffer, "--- no soundcards ---\n");
}

#if defined(CONFIG_SND_OSSEMUL) && defined(CONFIG_PROC_FS)

void snd_card_info_read_oss(snd_info_buffer_t * buffer)
{
	int idx, count;
	snd_card_t *card;

	for (idx = count = 0; idx < SNDRV_CARDS; idx++) {
		read_lock(&snd_card_rwlock);
		if ((card = snd_cards[idx]) != NULL) {
			count++;
			snd_iprintf(buffer, "%s\n", card->longname);
		}
		read_unlock(&snd_card_rwlock);
	}
	if (!count) {
		snd_iprintf(buffer, "--- no soundcards ---\n");
	}
}

#endif

#ifdef MODULE
static snd_info_entry_t *snd_card_module_info_entry;
static void snd_card_module_info_read(snd_info_entry_t *entry, snd_info_buffer_t * buffer)
{
	int idx;
	snd_card_t *card;

	for (idx = 0; idx < SNDRV_CARDS; idx++) {
		read_lock(&snd_card_rwlock);
		if ((card = snd_cards[idx]) != NULL)
			snd_iprintf(buffer, "%i %s\n", idx, card->module->name);
		read_unlock(&snd_card_rwlock);
	}
}
#endif

int __init snd_card_info_init(void)
{
	snd_info_entry_t *entry;

	entry = snd_info_create_module_entry(THIS_MODULE, "cards", NULL);
	snd_runtime_check(entry != NULL, return -ENOMEM);
	entry->c.text.read_size = PAGE_SIZE;
	entry->c.text.read = snd_card_info_read;
	if (snd_info_register(entry) < 0) {
		snd_info_free_entry(entry);
		return -ENOMEM;
	}
	snd_card_info_entry = entry;

#ifdef MODULE
	entry = snd_info_create_module_entry(THIS_MODULE, "modules", NULL);
	if (entry) {
		entry->c.text.read_size = PAGE_SIZE;
		entry->c.text.read = snd_card_module_info_read;
		if (snd_info_register(entry) < 0)
			snd_info_free_entry(entry);
		else
			snd_card_module_info_entry = entry;
	}
#endif

	return 0;
}

int __exit snd_card_info_done(void)
{
	if (snd_card_info_entry)
		snd_info_unregister(snd_card_info_entry);
#ifdef MODULE
	if (snd_card_module_info_entry)
		snd_info_unregister(snd_card_module_info_entry);
#endif
	return 0;
}

/**
 *  snd_component_add - add a component string
 *  @card: soundcard structure
 *  @component: the component id string
 *
 *  This function adds the component id string to the supported list.
 *  The component can be referred from the alsa-lib.
 *
 *  Returns zero otherwise a negative error code.
 */
  
int snd_component_add(snd_card_t *card, const char *component)
{
	char *ptr;
	int len = strlen(component);

	ptr = strstr(card->components, component);
	if (ptr != NULL) {
		if (ptr[len] == '\0' || ptr[len] == ' ')	/* already there */
			return 1;
	}
	if (strlen(card->components) + 1 + len + 1 > sizeof(card->components)) {
		snd_BUG();
		return -ENOMEM;
	}
	if (card->components[0] != '\0')
		strcat(card->components, " ");
	strcat(card->components, component);
	return 0;
}

/**
 *  snd_card_file_add - add the file to the file list of the card
 *  @card: soundcard structure
 *  @file: file pointer
 *
 *  This function adds the file to the file linked-list of the card.
 *  This linked-list is used to keep tracking the connection state,
 *  and to avoid the release of busy resources by hotplug.
 *
 *  Returns zero or a negative error code.
 */
int snd_card_file_add(snd_card_t *card, struct file *file)
{
	struct snd_monitor_file *mfile;

	mfile = kmalloc(sizeof(*mfile), GFP_KERNEL);
	if (mfile == NULL)
		return -ENOMEM;
	mfile->file = file;
	mfile->next = NULL;
	spin_lock(&card->files_lock);
	if (card->shutdown) {
		spin_unlock(&card->files_lock);
		kfree(mfile);
		return -ENODEV;
	}
	mfile->next = card->files;
	card->files = mfile;
	spin_unlock(&card->files_lock);
	return 0;
}

/**
 *  snd_card_file_remove - remove the file from the file list
 *  @card: soundcard structure
 *  @file: file pointer
 *
 *  This function removes the file formerly added to the card via
 *  snd_card_file_add() function.
 *  If all files are removed and the release of the card is
 *  scheduled, it will wake up the the thread to call snd_card_free()
 *  (see snd_card_free_in_thread() function).
 *
 *  Returns zero or a negative error code.
 */
int snd_card_file_remove(snd_card_t *card, struct file *file)
{
	struct snd_monitor_file *mfile, *pfile = NULL;

	spin_lock(&card->files_lock);
	mfile = card->files;
	while (mfile) {
		if (mfile->file == file) {
			if (pfile)
				pfile->next = mfile->next;
			else
				card->files = mfile->next;
			break;
		}
		pfile = mfile;
		mfile = mfile->next;
	}
	spin_unlock(&card->files_lock);
	if (card->files == NULL)
		wake_up(&card->shutdown_sleep);
	if (!mfile) {
		snd_printk(KERN_ERR "ALSA card file remove problem (%p)\n", file);
		return -ENOENT;
	}
	kfree(mfile);
	return 0;
}

#ifdef CONFIG_PM
/**
 *  snd_power_wait - wait until the power-state is changed.
 *  @card: soundcard structure
 *  @power_state: expected power state
 *  @file: file structure for the O_NONBLOCK check (optional)
 *
 *  Waits until the power-state is changed.
 *
 *  Note: the power lock must be active before call.
 */
int snd_power_wait(snd_card_t *card, unsigned int power_state, struct file *file)
{
	wait_queue_t wait;
	int result = 0;

	/* fastpath */
	if (snd_power_get_state(card) == power_state)
		return 0;
	init_waitqueue_entry(&wait, current);
	add_wait_queue(&card->power_sleep, &wait);
	while (1) {
		if (card->shutdown) {
			result = -ENODEV;
			break;
		}
		if (snd_power_get_state(card) == power_state)
			break;
#if 0 /* block all devices */
		if (file && (file->f_flags & O_NONBLOCK)) {
			result = -EAGAIN;
			break;
		}
#endif
		set_current_state(TASK_UNINTERRUPTIBLE);
		snd_power_unlock(card);
		schedule_timeout(30 * HZ);
		snd_power_lock(card);
	}
	remove_wait_queue(&card->power_sleep, &wait);
	return result;
}

/**
 * snd_card_set_pm_callback - set the PCI power-management callbacks
 * @card: soundcard structure
 * @suspend: suspend callback function
 * @resume: resume callback function
 * @private_data: private data to pass to the callback functions
 *
 * Sets the power-management callback functions of the card.
 * These callbacks are called from ALSA's common PCI suspend/resume
 * handler and from the control API.
 */
int snd_card_set_pm_callback(snd_card_t *card,
			     int (*suspend)(snd_card_t *, pm_message_t),
			     int (*resume)(snd_card_t *),
			     void *private_data)
{
	card->pm_suspend = suspend;
	card->pm_resume = resume;
	card->pm_private_data = private_data;
	return 0;
}

#ifdef CONFIG_SND_GENERIC_PM
/*
 * 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 */
static int snd_generic_suspend(struct device *dev, pm_message_t state, u32 level)
{
	snd_card_t *card;

	if (level != SUSPEND_DISABLE)
		return 0;

	card = get_snd_generic_card(dev);
	if (card->power_state == SNDRV_CTL_POWER_D3hot)
		return 0;
	card->pm_suspend(card, PMSG_SUSPEND);
	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
	return 0;
}

static int snd_generic_resume(struct device *dev, u32 level)
{
	snd_card_t *card;

	if (level != RESUME_ENABLE)
		return 0;

	card = get_snd_generic_card(dev);
	if (card->power_state == SNDRV_CTL_POWER_D0)
		return 0;
	card->pm_resume(card);
	snd_power_change_state(card, SNDRV_CTL_POWER_D0);
	return 0;
}

/**
 * snd_card_set_generic_pm_callback - set the generic power-management callbacks
 * @card: soundcard structure
 * @suspend: suspend callback function
 * @resume: resume callback function
 * @private_data: private data to pass to the callback functions
 *
 * Registers the power-management and sets the lowlevel callbacks for
 * the given card.  These callbacks are called from the ALSA's common
 * PM handler and from the control API.
 */
int snd_card_set_generic_pm_callback(snd_card_t *card,
				 int (*suspend)(snd_card_t *, pm_message_t),
				 int (*resume)(snd_card_t *),
				 void *private_data)
{
	card->pm_dev = snd_generic_device_register(card);
	if (! card->pm_dev)
		return -ENOMEM;
	snd_card_set_pm_callback(card, suspend, resume, private_data);
	return 0;
}
#endif /* CONFIG_SND_GENERIC_PM */

#ifdef CONFIG_PCI
int snd_card_pci_suspend(struct pci_dev *dev, pm_message_t state)
{
	snd_card_t *card = pci_get_drvdata(dev);
	int err;
	if (! card || ! card->pm_suspend)
		return 0;
	if (card->power_state == SNDRV_CTL_POWER_D3hot)
		return 0;
	err = card->pm_suspend(card, PMSG_SUSPEND);
	pci_save_state(dev);
	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
	return err;
}

int snd_card_pci_resume(struct pci_dev *dev)
{
	snd_card_t *card = pci_get_drvdata(dev);
	if (! card || ! card->pm_resume)
		return 0;
	if (card->power_state == SNDRV_CTL_POWER_D0)
		return 0;
	/* restore the PCI config space */
	pci_restore_state(dev);
	card->pm_resume(card);
	snd_power_change_state(card, SNDRV_CTL_POWER_D0);
	return 0;
}
#endif

#endif /* CONFIG_PM */
