#else
#define MAX_DMA_ADDRESS (PAGE_OFFSET + ARM_DMA_ZONE_SIZE)
#endif
+
+#ifdef CONFIG_ISA_DMA_API
/*
* This is used to support drivers written for the x86 ISA DMA API.
* It should not be re-used except for that purpose.
#include <asm/system.h>
#include <asm/scatterlist.h>
-
-#define RK28_DMA_CH0 0
-#define RK28_DMA_CH1 1
-#define RK28_DMA_CH2 2
-#define RK28_DMA_CH3 3
-#define RK28_DMA_CH4 4
-#define RK28_DMA_CH5 5
-
-#define MAX_DMA_CHANNELS 6
-
-
-/*
-"sd_mmc",
-"uart_2",
-"uart_3",
-"sdio",
-"i2s",
-"spi_m",
-"spi_s",
-"uart_0",
-"uart_1",
-*/
+#include <mach/isa-dma.h>
/*
* The DMA modes reflect the settings for the ISA DMA controller
#define DMA_MODE_CASCADE 0xc0
#define DMA_AUTOINIT 0x10
+extern spinlock_t dma_spin_lock;
-/*
- * The DMA irq modes
+static inline unsigned long claim_dma_lock(void)
+{
+ unsigned long flags;
+ spin_lock_irqsave(&dma_spin_lock, flags);
+ return flags;
+}
+
+static inline void release_dma_lock(unsigned long flags)
+{
+ spin_unlock_irqrestore(&dma_spin_lock, flags);
+}
+
+/* Clear the 'DMA Pointer Flip Flop'.
+ * Write 0 for LSB/MSB, 1 for MSB/LSB access.
*/
-#define DMA_IRQ_DELAY_MODE 0x00 /*performan in software irq handleer*/
-#define DMA_IRQ_RIGHTNOW_MODE 0x01 /*performan in dwdma irq handleer*/
+#define clear_dma_ff(chan)
+/* Set only the page register bits of the transfer address.
+ *
+ * NOTE: This is an architecture specific function, and should
+ * be hidden from the drivers
+ */
+extern void set_dma_page(unsigned int chan, char pagenr);
/* Request a DMA channel
*
*
* Some architectures may need to do free an interrupt
*/
-extern int free_dma(unsigned int chan);
+extern void free_dma(unsigned int chan);
/* Enable DMA for this channel
*
* On some architectures, this may have other side effects like
* enabling an interrupt and setting the DMA registers.
*/
-extern int enable_dma(unsigned int chan);
+extern void enable_dma(unsigned int chan);
/* Disable DMA for this channel
*
* On some architectures, this may have other side effects like
* disabling an interrupt or whatever.
*/
-extern int disable_dma(unsigned int chan);
+extern void disable_dma(unsigned int chan);
/* Test whether the specified channel has an active DMA transfer
*/
* DMA address immediately, but defer it to the enable_dma().
*/
extern void __set_dma_addr(unsigned int chan, void *addr);
-
-#define set_dma_addr(chan, addr) __set_dma_addr(chan, addr)//__set_dma_addr(chan, bus_to_virt(addr))
+#define set_dma_addr(chan, addr) \
+ __set_dma_addr(chan, bus_to_virt(addr))
/* Set the DMA byte count for this channel
*
* enable_dma().
*/
extern void set_dma_mode(unsigned int chan, unsigned int mode);
-#if 0
+
/* Set the transfer speed for this channel
*/
extern void set_dma_speed(unsigned int chan, int cycle_ns);
* Otherwise, it returns the number of _bytes_ left to transfer.
*/
extern int get_dma_residue(unsigned int chan);
+
+#ifndef NO_DMA
+#define NO_DMA 255
#endif
-/* Set dam irq callback that perform when dma transfer has completed
- */
-extern void set_dma_handler (unsigned int chan, void (*irq_handler) (int, void *), void *data, unsigned int irq_mode);
-/*
- * get dma transfer position
- */
-extern void get_dma_position(unsigned int chan, dma_addr_t *src_pos, dma_addr_t *dst_pos);
+#endif /* CONFIG_ISA_DMA_API */
#ifdef CONFIG_PCI
extern int isa_dma_bridge_buggy;
struct dma_ops {
int (*request)(unsigned int, dma_t *); /* optional */
- int (*free)(unsigned int, dma_t *); /* optional */
- int (*enable)(unsigned int, dma_t *); /* mandatory */
- int (*disable)(unsigned int, dma_t *); /* mandatory */
- void (*position)(unsigned int, dma_t *);
-#if 0
+ void (*free)(unsigned int, dma_t *); /* optional */
+ void (*enable)(unsigned int, dma_t *); /* mandatory */
+ void (*disable)(unsigned int, dma_t *); /* mandatory */
int (*residue)(unsigned int, dma_t *); /* optional */
int (*setspeed)(unsigned int, dma_t *, int); /* optional */
const char *type;
-#endif
};
struct dma_struct {
unsigned int lock; /* Device is allocated */
const char *device_id; /* Device name */
- void (*irqHandle)(int irq, void *dev_id); /*irq callback*/
- void *data;
- unsigned int irq_mode;
-
- dma_addr_t src_pos;
- dma_addr_t dst_pos;
-
const struct dma_ops *d_ops;
};
/*
* isa_dma_add - add an ISA-style DMA channel
*/
-extern int dma_add(unsigned int, dma_t *dma);
+extern int isa_dma_add(unsigned int, dma_t *dma);
+/*
+ * Add the ISA DMA controller. Always takes channels 0-7.
+ */
+extern void isa_init_dma(void);
obj-y := elf.o entry-armv.o entry-common.o irq.o \
process.o ptrace.o return_address.o setup.o signal.o \
- sys_arm.o stacktrace.o time.o traps.o dma.o
+ sys_arm.o stacktrace.o time.o traps.o
obj-$(CONFIG_DEPRECATED_PARAM_STRUCT) += compat.o
return dma_chan[chan];
}
-int __init dma_add(unsigned int chan, dma_t *dma)
+int __init isa_dma_add(unsigned int chan, dma_t *dma)
{
if (!dma->d_ops)
return -EINVAL;
*
* On certain platforms, we have to free interrupt as well...
*/
-int free_dma(unsigned int chan)
+void free_dma(unsigned int chan)
{
dma_t *dma = dma_channel(chan);
- int ret;
-
+
if (!dma)
goto bad_dma;
if (dma->active) {
printk(KERN_ERR "dma%d: freeing active DMA\n", chan);
- ret = dma->d_ops->disable(chan, dma);
+ dma->d_ops->disable(chan, dma);
dma->active = 0;
- if (ret)
- goto free_dma;
}
if (xchg(&dma->lock, 0) != 0) {
if (dma->d_ops->free)
- ret = dma->d_ops->free(chan, dma);
- return ret ;
+ dma->d_ops->free(chan, dma);
+ return;
}
-
-free_dma:
+
printk(KERN_ERR "dma%d: trying to free free DMA\n", chan);
- return -ENODEV;
+ return;
bad_dma:
printk(KERN_ERR "dma: trying to free DMA%d\n", chan);
- return -EINVAL;
}
EXPORT_SYMBOL(free_dma);
-/* Set DMA irq handler
- *
- * Copy irq handler to the structure
- */
- void set_dma_handler (unsigned int chan, void (*irq_handler) (int, void *), void *data, unsigned int irq_mode)
-{
- dma_t *dma = dma_channel(chan);
-
- if (dma->active)
- printk(KERN_ERR "dma%d: altering DMA irq handler while "
- "DMA active\n", chan);
-
- dma->irqHandle = irq_handler;
- dma->data = data;
- dma->irq_mode = irq_mode;
-}
-EXPORT_SYMBOL(set_dma_handler);
-
/* Set DMA Scatter-Gather list
*/
void set_dma_sg (unsigned int chan, struct scatterlist *sg, int nr_sg)
/* Enable DMA channel
*/
-int enable_dma (unsigned int chan)
+void enable_dma (unsigned int chan)
{
dma_t *dma = dma_channel(chan);
- int ret;
-
+
if (!dma->lock)
goto free_dma;
if (dma->active == 0) {
dma->active = 1;
- ret = dma->d_ops->enable(chan, dma);
- return ret;
+ dma->d_ops->enable(chan, dma);
}
-
- return -EBUSY;
+ return;
free_dma:
printk(KERN_ERR "dma%d: trying to enable free DMA\n", chan);
BUG();
- return -ENODEV;
}
EXPORT_SYMBOL(enable_dma);
/* Disable DMA channel
*/
-int disable_dma (unsigned int chan)
+void disable_dma (unsigned int chan)
{
dma_t *dma = dma_channel(chan);
- int ret;
if (!dma->lock)
goto free_dma;
if (dma->active == 1) {
dma->active = 0;
- ret = dma->d_ops->disable(chan, dma);
- return ret;
+ dma->d_ops->disable(chan, dma);
}
-
- return -EBUSY;
+ return;
free_dma:
printk(KERN_ERR "dma%d: trying to disable free DMA\n", chan);
BUG();
- return -ENODEV;
}
EXPORT_SYMBOL(disable_dma);
dma_t *dma = dma_channel(chan);
return dma->active;
}
-
-/*
- * get dma transfer position
- */
-void get_dma_position(unsigned int chan, dma_addr_t *src_pos, dma_addr_t *dst_pos)
-{
- dma_t *dma = dma_channel(chan);
-
- if (dma->d_ops->position)
- dma->d_ops->position(chan, dma);
-
- if (src_pos) {
- *src_pos = dma->src_pos;
- }
-
- if (dst_pos) {
- *dst_pos = dma->dst_pos;
- }
-}
-
EXPORT_SYMBOL(dma_channel_active);
-#if 0
void set_dma_page(unsigned int chan, char pagenr)
{
printk(KERN_ERR "dma%d: trying to set_dma_page\n", chan);
return ret;
}
EXPORT_SYMBOL(get_dma_residue);
-#endif
#ifdef CONFIG_PROC_FS
static int proc_dma_show(struct seq_file *m, void *v)