Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ARM: OMAP: Sync DMA with linux-omap tree

This patch syncs OMAP DMA code with linux-omap tree.
Mostly allow changing DMA callback function and set
OMAP2 specific transfer mode.

Signed-off-by: Tony Lindgren <tony@atomide.com>

+75 -22
+64 -21
arch/arm/plat-omap/dma.c
··· 119 119 omap_writew(0, lch_base + i); 120 120 } 121 121 122 - void omap_set_dma_priority(int dst_port, int priority) 122 + void omap_set_dma_priority(int lch, int dst_port, int priority) 123 123 { 124 124 unsigned long reg; 125 125 u32 l; 126 126 127 - switch (dst_port) { 128 - case OMAP_DMA_PORT_OCP_T1: /* FFFECC00 */ 129 - reg = OMAP_TC_OCPT1_PRIOR; 130 - break; 131 - case OMAP_DMA_PORT_OCP_T2: /* FFFECCD0 */ 132 - reg = OMAP_TC_OCPT2_PRIOR; 133 - break; 134 - case OMAP_DMA_PORT_EMIFF: /* FFFECC08 */ 135 - reg = OMAP_TC_EMIFF_PRIOR; 136 - break; 137 - case OMAP_DMA_PORT_EMIFS: /* FFFECC04 */ 138 - reg = OMAP_TC_EMIFS_PRIOR; 139 - break; 140 - default: 141 - BUG(); 142 - return; 127 + if (cpu_class_is_omap1()) { 128 + switch (dst_port) { 129 + case OMAP_DMA_PORT_OCP_T1: /* FFFECC00 */ 130 + reg = OMAP_TC_OCPT1_PRIOR; 131 + break; 132 + case OMAP_DMA_PORT_OCP_T2: /* FFFECCD0 */ 133 + reg = OMAP_TC_OCPT2_PRIOR; 134 + break; 135 + case OMAP_DMA_PORT_EMIFF: /* FFFECC08 */ 136 + reg = OMAP_TC_EMIFF_PRIOR; 137 + break; 138 + case OMAP_DMA_PORT_EMIFS: /* FFFECC04 */ 139 + reg = OMAP_TC_EMIFS_PRIOR; 140 + break; 141 + default: 142 + BUG(); 143 + return; 144 + } 145 + l = omap_readl(reg); 146 + l &= ~(0xf << 8); 147 + l |= (priority & 0xf) << 8; 148 + omap_writel(l, reg); 143 149 } 144 - l = omap_readl(reg); 145 - l &= ~(0xf << 8); 146 - l |= (priority & 0xf) << 8; 147 - omap_writel(l, reg); 150 + 151 + if (cpu_is_omap24xx()) { 152 + if (priority) 153 + OMAP_DMA_CCR_REG(lch) |= (1 << 6); 154 + else 155 + OMAP_DMA_CCR_REG(lch) &= ~(1 << 6); 156 + } 148 157 } 149 158 150 159 void omap_set_dma_transfer_params(int lch, int data_type, int elem_count, ··· 241 232 w |= 1; /* Channel type G */ 242 233 } 243 234 OMAP1_DMA_LCH_CTRL_REG(lch) = w; 235 + } 236 + 237 + void omap_set_dma_write_mode(int lch, enum omap_dma_write_mode mode) 238 + { 239 + if (cpu_is_omap24xx()) { 240 + OMAP_DMA_CSDP_REG(lch) &= ~(0x3 << 16); 241 + OMAP_DMA_CSDP_REG(lch) |= (mode << 16); 242 + } 244 243 } 245 244 246 245 /* Note that src_port is only for omap1 */ ··· 712 695 713 696 OMAP_DMA_CCR_REG(lch) &= ~OMAP_DMA_CCR_EN; 714 697 dma_chan[lch].flags &= ~OMAP_DMA_ACTIVE; 698 + } 699 + 700 + /* 701 + * Allows changing the DMA callback function or data. This may be needed if 702 + * the driver shares a single DMA channel for multiple dma triggers. 703 + */ 704 + int omap_set_dma_callback(int lch, 705 + void (* callback)(int lch, u16 ch_status, void *data), 706 + void *data) 707 + { 708 + unsigned long flags; 709 + 710 + if (lch < 0) 711 + return -ENODEV; 712 + 713 + spin_lock_irqsave(&dma_chan_lock, flags); 714 + if (dma_chan[lch].dev_id == -1) { 715 + printk(KERN_ERR "DMA callback for not set for free channel\n"); 716 + spin_unlock_irqrestore(&dma_chan_lock, flags); 717 + return -EINVAL; 718 + } 719 + dma_chan[lch].callback = callback; 720 + dma_chan[lch].data = data; 721 + spin_unlock_irqrestore(&dma_chan_lock, flags); 722 + 723 + return 0; 715 724 } 716 725 717 726 /*
+11 -1
include/asm-arm/arch-omap/dma.h
··· 331 331 OMAP_DMA_TRANSPARENT_COPY 332 332 }; 333 333 334 + enum omap_dma_write_mode { 335 + OMAP_DMA_WRITE_NON_POSTED = 0, 336 + OMAP_DMA_WRITE_POSTED, 337 + OMAP_DMA_WRITE_LAST_NON_POSTED 338 + }; 339 + 334 340 struct omap_dma_channel_params { 335 341 int data_type; /* data type 8,16,32 */ 336 342 int elem_count; /* number of elements in a frame */ ··· 362 356 }; 363 357 364 358 365 - extern void omap_set_dma_priority(int dst_port, int priority); 359 + extern void omap_set_dma_priority(int lch, int dst_port, int priority); 366 360 extern int omap_request_dma(int dev_id, const char *dev_name, 367 361 void (* callback)(int lch, u16 ch_status, void *data), 368 362 void *data, int *dma_ch); ··· 377 371 int dma_trigger, int src_or_dst_synch); 378 372 extern void omap_set_dma_color_mode(int lch, enum omap_dma_color_mode mode, 379 373 u32 color); 374 + extern void omap_set_dma_write_mode(int lch, enum omap_dma_write_mode mode); 380 375 381 376 extern void omap_set_dma_src_params(int lch, int src_port, int src_amode, 382 377 unsigned long src_start, ··· 401 394 extern void omap_dma_link_lch (int lch_head, int lch_queue); 402 395 extern void omap_dma_unlink_lch (int lch_head, int lch_queue); 403 396 397 + extern int omap_set_dma_callback(int lch, 398 + void (* callback)(int lch, u16 ch_status, void *data), 399 + void *data); 404 400 extern dma_addr_t omap_get_dma_src_pos(int lch); 405 401 extern dma_addr_t omap_get_dma_dst_pos(int lch); 406 402 extern int omap_get_dma_src_addr_counter(int lch);