#include <linux/interrupt.h>
 #include <mach/dma.h>
+#include <asm/atomic.h>
 #include <asm/blackfin.h>
 #include <asm/page.h>
 
 *        Generic DMA  Declarations
 *
 ****************************************************************************/
-enum dma_chan_status {
-       DMA_CHANNEL_FREE,
-       DMA_CHANNEL_REQUESTED,
-       DMA_CHANNEL_ENABLED,
-};
 
 /*-------------------------
  * config reg bits value
 
 };
 
-struct mutex;
 struct dma_channel {
-       struct mutex dmalock;
        const char *device_id;
-       enum dma_chan_status chan_status;
+       atomic_t chan_status;
        volatile struct dma_register *regs;
        struct dmasg *sg;               /* large mode descriptor */
        unsigned int irq;
 
 static inline int dma_channel_active(unsigned int channel)
 {
-       if (dma_ch[channel].chan_status == DMA_CHANNEL_FREE)
-               return 0;
-       else
-               return 1;
+       return atomic_read(&dma_ch[channel].chan_status);
 }
 
 static inline void disable_dma(unsigned int channel)
 {
        dma_ch[channel].regs->cfg &= ~DMAEN;
        SSYNC();
-       dma_ch[channel].chan_status = DMA_CHANNEL_REQUESTED;
 }
 static inline void enable_dma(unsigned int channel)
 {
        dma_ch[channel].regs->curr_x_count = 0;
        dma_ch[channel].regs->curr_y_count = 0;
        dma_ch[channel].regs->cfg |= DMAEN;
-       dma_ch[channel].chan_status = DMA_CHANNEL_ENABLED;
 }
 void free_dma(unsigned int channel);
 int request_dma(unsigned int channel, const char *device_id);
 
        printk(KERN_INFO "Blackfin DMA Controller\n");
 
        for (i = 0; i < MAX_DMA_CHANNELS; i++) {
-               dma_ch[i].chan_status = DMA_CHANNEL_FREE;
+               atomic_set(&dma_ch[i].chan_status, 0);
                dma_ch[i].regs = dma_io_base_addr[i];
-               mutex_init(&(dma_ch[i].dmalock));
        }
        /* Mark MEMDMA Channel 0 as requested since we're using it internally */
        request_dma(CH_MEM_STREAM0_DEST, "Blackfin dma_memcpy");
        int i;
 
        for (i = 0; i < MAX_DMA_CHANNELS; ++i)
-               if (dma_ch[i].chan_status != DMA_CHANNEL_FREE)
+               if (dma_channel_active(i))
                        seq_printf(m, "%2d: %s\n", i, dma_ch[i].device_id);
 
        return 0;
        }
 #endif
 
-       mutex_lock(&(dma_ch[channel].dmalock));
-
-       if ((dma_ch[channel].chan_status == DMA_CHANNEL_REQUESTED)
-           || (dma_ch[channel].chan_status == DMA_CHANNEL_ENABLED)) {
-               mutex_unlock(&(dma_ch[channel].dmalock));
+       if (atomic_cmpxchg(&dma_ch[channel].chan_status, 0, 1)) {
                pr_debug("DMA CHANNEL IN USE  \n");
                return -EBUSY;
-       } else {
-               dma_ch[channel].chan_status = DMA_CHANNEL_REQUESTED;
-               pr_debug("DMA CHANNEL IS ALLOCATED  \n");
        }
 
-       mutex_unlock(&(dma_ch[channel].dmalock));
-
 #ifdef CONFIG_BF54x
        if (channel >= CH_UART2_RX && channel <= CH_UART3_TX) {
                unsigned int per_map;
 int set_dma_callback(unsigned int channel, irq_handler_t callback, void *data)
 {
        BUG_ON(channel >= MAX_DMA_CHANNELS ||
-                       dma_ch[channel].chan_status == DMA_CHANNEL_FREE);
+                       !atomic_read(&dma_ch[channel].chan_status));
 
        if (callback != NULL) {
                int ret;
 {
        pr_debug("freedma() : BEGIN \n");
        BUG_ON(channel >= MAX_DMA_CHANNELS ||
-                       dma_ch[channel].chan_status == DMA_CHANNEL_FREE);
+                       !atomic_read(&dma_ch[channel].chan_status));
 
        /* Halt the DMA */
        disable_dma(channel);
                free_irq(dma_ch[channel].irq, dma_ch[channel].data);
 
        /* Clear the DMA Variable in the Channel */
-       mutex_lock(&(dma_ch[channel].dmalock));
-       dma_ch[channel].chan_status = DMA_CHANNEL_FREE;
-       mutex_unlock(&(dma_ch[channel].dmalock));
+       atomic_set(&dma_ch[channel].chan_status, 0);
 
        pr_debug("freedma() : END \n");
 }
 {
        int i;
 
-       for (i = 0; i < MAX_DMA_SUSPEND_CHANNELS; ++i) {
-               if (dma_ch[i].chan_status == DMA_CHANNEL_ENABLED) {
+       for (i = 0; i < MAX_DMA_CHANNELS; ++i) {
+               if (dma_ch[i].regs->cfg & DMAEN) {
                        printk(KERN_ERR "DMA Channel %d failed to suspend\n", i);
                        return -EBUSY;
                }
 
-               dma_ch[i].saved_peripheral_map = dma_ch[i].regs->peripheral_map;
+               if (i < MAX_DMA_SUSPEND_CHANNELS)
+                       dma_ch[i].saved_peripheral_map = dma_ch[i].regs->peripheral_map;
        }
 
        return 0;