Merge branch 'devel' of master.kernel.org:/home/rmk/linux-2.6-arm
[pandora-kernel.git] / sound / core / memalloc.c
index 0213256..bc0bd09 100644 (file)
@@ -21,7 +21,6 @@
  *
  */
 
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/proc_fs.h>
 #include <linux/init.h>
@@ -31,7 +30,7 @@
 #include <asm/uaccess.h>
 #include <linux/dma-mapping.h>
 #include <linux/moduleparam.h>
-#include <asm/semaphore.h>
+#include <linux/mutex.h>
 #include <sound/memalloc.h>
 #ifdef CONFIG_SBUS
 #include <asm/sbus.h>
@@ -43,10 +42,6 @@ MODULE_DESCRIPTION("Memory allocator for ALSA system.");
 MODULE_LICENSE("GPL");
 
 
-#ifndef SNDRV_CARDS
-#define SNDRV_CARDS    8
-#endif
-
 /*
  */
 
@@ -58,7 +53,7 @@ int snd_free_sgbuf_pages(struct snd_dma_buffer *dmab);
 /*
  */
 
-static DECLARE_MUTEX(list_mutex);
+static DEFINE_MUTEX(list_mutex);
 static LIST_HEAD(mem_list_head);
 
 /* buffer preservation list */
@@ -87,7 +82,7 @@ struct snd_mem_list {
  *  Hacks
  */
 
-#if defined(__i386__) || defined(__ppc__) || defined(__x86_64__)
+#if defined(__i386__)
 /*
  * A hack to allocate large buffers via dma_alloc_coherent()
  *
@@ -106,7 +101,7 @@ struct snd_mem_list {
 
 static void *snd_dma_hack_alloc_coherent(struct device *dev, size_t size,
                                         dma_addr_t *dma_handle,
-                                        unsigned int __nocast flags)
+                                        gfp_t flags)
 {
        void *ret;
        u64 dma_mask, coherent_dma_mask;
@@ -145,10 +140,6 @@ static void *snd_dma_hack_alloc_coherent(struct device *dev, size_t size,
 
 #endif /* arch */
 
-#if ! defined(__arm__)
-#define NEED_RESERVE_PAGES
-#endif
-
 /*
  *
  *  Generic memory allocators
@@ -167,20 +158,6 @@ static inline void dec_snd_pages(int order)
        snd_allocated_pages -= 1 << order;
 }
 
-static void mark_pages(struct page *page, int order)
-{
-       struct page *last_page = page + (1 << order);
-       while (page < last_page)
-               SetPageReserved(page++);
-}
-
-static void unmark_pages(struct page *page, int order)
-{
-       struct page *last_page = page + (1 << order);
-       while (page < last_page)
-               ClearPageReserved(page++);
-}
-
 /**
  * snd_malloc_pages - allocate pages with the given size
  * @size: the size to allocate in bytes
@@ -190,18 +167,17 @@ static void unmark_pages(struct page *page, int order)
  *
  * Returns the pointer of the buffer, or NULL if no enoguh memory.
  */
-void *snd_malloc_pages(size_t size, unsigned int gfp_flags)
+void *snd_malloc_pages(size_t size, gfp_t gfp_flags)
 {
        int pg;
        void *res;
 
        snd_assert(size > 0, return NULL);
        snd_assert(gfp_flags != 0, return NULL);
+       gfp_flags |= __GFP_COMP;        /* compound page lets parts be mapped */
        pg = get_order(size);
-       if ((res = (void *) __get_free_pages(gfp_flags, pg)) != NULL) {
-               mark_pages(virt_to_page(res), pg);
+       if ((res = (void *) __get_free_pages(gfp_flags, pg)) != NULL)
                inc_snd_pages(pg);
-       }
        return res;
 }
 
@@ -220,7 +196,6 @@ void snd_free_pages(void *ptr, size_t size)
                return;
        pg = get_order(size);
        dec_snd_pages(pg);
-       unmark_pages(virt_to_page(ptr), pg);
        free_pages((unsigned long) ptr, pg);
 }
 
@@ -235,21 +210,18 @@ static void *snd_malloc_dev_pages(struct device *dev, size_t size, dma_addr_t *d
 {
        int pg;
        void *res;
-       unsigned int gfp_flags;
+       gfp_t gfp_flags;
 
        snd_assert(size > 0, return NULL);
        snd_assert(dma != NULL, return NULL);
        pg = get_order(size);
        gfp_flags = GFP_KERNEL
+               | __GFP_COMP    /* compound page lets parts be mapped */
                | __GFP_NORETRY /* don't trigger OOM-killer */
                | __GFP_NOWARN; /* no stack trace print - this call is non-critical */
        res = dma_alloc_coherent(dev, PAGE_SIZE << pg, dma, gfp_flags);
-       if (res != NULL) {
-#ifdef NEED_RESERVE_PAGES
-               mark_pages(virt_to_page(res), pg); /* should be dma_to_page() */
-#endif
+       if (res != NULL)
                inc_snd_pages(pg);
-       }
 
        return res;
 }
@@ -264,9 +236,6 @@ static void snd_free_dev_pages(struct device *dev, size_t size, void *ptr,
                return;
        pg = get_order(size);
        dec_snd_pages(pg);
-#ifdef NEED_RESERVE_PAGES
-       unmark_pages(virt_to_page(ptr), pg); /* should be dma_to_page() */
-#endif
        dma_free_coherent(dev, PAGE_SIZE << pg, ptr, dma);
 }
 
@@ -442,7 +411,7 @@ size_t snd_dma_get_reserved_buf(struct snd_dma_buffer *dmab, unsigned int id)
 
        snd_assert(dmab, return 0);
 
-       down(&list_mutex);
+       mutex_lock(&list_mutex);
        list_for_each(p, &mem_list_head) {
                mem = list_entry(p, struct snd_mem_list, list);
                if (mem->id == id &&
@@ -454,11 +423,11 @@ size_t snd_dma_get_reserved_buf(struct snd_dma_buffer *dmab, unsigned int id)
                        if (dmab->dev.dev == NULL)
                                dmab->dev.dev = dev;
                        kfree(mem);
-                       up(&list_mutex);
+                       mutex_unlock(&list_mutex);
                        return dmab->bytes;
                }
        }
-       up(&list_mutex);
+       mutex_unlock(&list_mutex);
        return 0;
 }
 
@@ -479,11 +448,11 @@ int snd_dma_reserve_buf(struct snd_dma_buffer *dmab, unsigned int id)
        mem = kmalloc(sizeof(*mem), GFP_KERNEL);
        if (! mem)
                return -ENOMEM;
-       down(&list_mutex);
+       mutex_lock(&list_mutex);
        mem->buffer = *dmab;
        mem->id = id;
        list_add_tail(&mem->list, &mem_list_head);
-       up(&list_mutex);
+       mutex_unlock(&list_mutex);
        return 0;
 }
 
@@ -495,7 +464,7 @@ static void free_all_reserved_pages(void)
        struct list_head *p;
        struct snd_mem_list *mem;
 
-       down(&list_mutex);
+       mutex_lock(&list_mutex);
        while (! list_empty(&mem_list_head)) {
                p = mem_list_head.next;
                mem = list_entry(p, struct snd_mem_list, list);
@@ -503,7 +472,7 @@ static void free_all_reserved_pages(void)
                snd_dma_free_pages(&mem->buffer);
                kfree(mem);
        }
-       up(&list_mutex);
+       mutex_unlock(&list_mutex);
 }
 
 
@@ -512,7 +481,7 @@ static void free_all_reserved_pages(void)
  * proc file interface
  */
 #define SND_MEM_PROC_FILE      "driver/snd-page-alloc"
-struct proc_dir_entry *snd_mem_proc;
+static struct proc_dir_entry *snd_mem_proc;
 
 static int snd_mem_proc_read(char *page, char **start, off_t off,
                             int count, int *eof, void *data)
@@ -524,7 +493,7 @@ static int snd_mem_proc_read(char *page, char **start, off_t off,
        int devno;
        static char *types[] = { "UNKNOWN", "CONT", "DEV", "DEV-SG", "SBUS" };
 
-       down(&list_mutex);
+       mutex_lock(&list_mutex);
        len += snprintf(page + len, count - len,
                        "pages  : %li bytes (%li pages per %likB)\n",
                        pages * PAGE_SIZE, pages, PAGE_SIZE / 1024);
@@ -539,7 +508,7 @@ static int snd_mem_proc_read(char *page, char **start, off_t off,
                                "  addr = 0x%lx, size = %d bytes\n",
                                (unsigned long)mem->buffer.addr, (int)mem->buffer.bytes);
        }
-       up(&list_mutex);
+       mutex_unlock(&list_mutex);
        return len;
 }
 
@@ -590,7 +559,7 @@ static int snd_mem_proc_write(struct file *file, const char __user *buffer,
 
                alloced = 0;
                pci = NULL;
-               while ((pci = pci_find_device(vendor, device, pci)) != NULL) {
+               while ((pci = pci_get_device(vendor, device, pci)) != NULL) {
                        if (mask > 0 && mask < 0xffffffff) {
                                if (pci_set_dma_mask(pci, mask) < 0 ||
                                    pci_set_consistent_dma_mask(pci, mask) < 0) {
@@ -604,6 +573,7 @@ static int snd_mem_proc_write(struct file *file, const char __user *buffer,
                                if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
                                                        size, &dmab) < 0) {
                                        printk(KERN_ERR "snd-page-alloc: cannot allocate buffer pages (size = %d)\n", size);
+                                       pci_dev_put(pci);
                                        return (int)count;
                                }
                                snd_dma_reserve_buf(&dmab, snd_dma_pci_buf_id(pci));
@@ -655,8 +625,7 @@ static int __init snd_mem_init(void)
 
 static void __exit snd_mem_exit(void)
 {
-       if (snd_mem_proc)
-               remove_proc_entry(SND_MEM_PROC_FILE, NULL);
+       remove_proc_entry(SND_MEM_PROC_FILE, NULL);
        free_all_reserved_pages();
        if (snd_allocated_pages > 0)
                printk(KERN_ERR "snd-malloc: Memory leak?  pages not freed = %li\n", snd_allocated_pages);