From: David Brownell <[email protected]> Remove more needless complexity from the EDMA code: the bitmap recording whether a given master channel's IRQ is in use. This is redundant with respect to the flag saying whether that channel is itself in use.
Plus minor bugfixes: actually disable the IRQ; scrub out old IRQ status before enabling; handle TCC more consistently. Saves about 270 bytes. Signed-off-by: David Brownell <[email protected]> --- arch/arm/mach-davinci/dma.c | 145 ++++++++---------------------------------- 1 file changed, 31 insertions(+), 114 deletions(-) --- a/arch/arm/mach-davinci/dma.c +++ b/arch/arm/mach-davinci/dma.c @@ -257,7 +257,7 @@ static struct davinci_dma_lch { static struct dma_interrupt_data { void (*callback) (int lch, unsigned short ch_status, void *data); void *data; -} intr_data[64]; +} intr_data[DAVINCI_EDMA_NUM_DMACH]; /* Each bit field of the elements below indicates corresponding EDMA channel @@ -292,17 +292,6 @@ static unsigned long param_entry_use_sta 0xffffffff }; -/* - Each bit field of the elements below indicates whether an interrupt - is free or in use - 1 - free - 0 - in use -*/ -static unsigned long dma_intr_use_status[] = { - 0xffffffff, - 0xffffffff -}; - /* The edma_noevent bit for each master channel is clear unless * it doesn't trigger DMA events on this platform. It uses a * bit of SOC-specific initialization code. @@ -443,85 +432,25 @@ static void free_param(int param_no) } } -/****************************************************************************** - * - * DMA interrupt requests: Requests for the interrupt on the free channel - * - * Arguments: - * lch - logical channel number for which the interrupt is to be requested - * for the free channel. - * callback - callback function registered for the requested interrupt - * channel - * data - channel private data. - * - * Return: free interrupt channel number on success, or negative error number - * on failure - * - *****************************************************************************/ -static int request_dma_interrupt(int lch, - void (*callback) (int lch, - unsigned short ch_status, - void *data), - void *data, int param_no, int requested_tcc) +static inline void +setup_dma_interrupt(unsigned lch, + void (*callback)(int lch, unsigned short ch_status, void *data), + void *data) { - signed int free_intr_no = -1; - - /* edma channels */ - if (lch >= 0 && lch < DAVINCI_EDMA_NUM_DMACH) { - /* Bitmap dma_intr_use_status is used to identify availabe tcc - for interrupt purpose. This could be modified by several - thread and same structure is checked availabilty as well as - updated once it's found that resource is avialable */ - LOCK; - if (dma_intr_use_status[lch / 32] & (1 << (lch % 32))) { - /* in use */ - dma_intr_use_status[lch / 32] &= (~(1 << (lch % 32))); - UNLOCK; - free_intr_no = lch; - dev_dbg(&edma_dev.dev, "interrupt no=%d\r\n", - free_intr_no); - } else { - UNLOCK; - dev_dbg(&edma_dev.dev, "EDMA:Error\r\n"); - return -1; - } + if (!callback) { + edma_shadow0_write_array(SH_IECR, lch >> 5, + (1 << (lch & 0x1f))); } - if (free_intr_no < 0) { - dev_dbg(&edma_dev.dev, "no IRQ for channel %d\n", lch); - return -EIO; - } - if (free_intr_no >= 0 && free_intr_no < 64) { - intr_data[free_intr_no].callback = callback; - intr_data[free_intr_no].data = data; - edma_shadow0_write_array(SH_IESR, free_intr_no >> 5, - (1 << (free_intr_no & 0x1f))); - } - return free_intr_no; -} - -/****************************************************************************** - * - * Free the dma interrupt: Releases the dma interrupt on the channel - * - * Arguments: - * intr_no - interrupt number on the channel to be released or freed out - * - * Return: N/A - * - *****************************************************************************/ -static void free_dma_interrupt(int intr_no) -{ - if (intr_no >= 0 && intr_no < 64) { - edma_shadow0_write_array(SH_ICR, intr_no >> 5, - (1 << (intr_no & 0x1f))); - LOCK; - /* Global structure and could be modified by several task */ - dma_intr_use_status[intr_no >> 5] |= (1 << (intr_no & 0x1f)); - UNLOCK; - intr_data[intr_no].callback = NULL; - intr_data[intr_no].data = NULL; + intr_data[lch].callback = callback; + intr_data[lch].data = data; + if (callback) { + dma_chan[lch].tcc = lch; + edma_shadow0_write_array(SH_ICR, lch >> 5, + (1 << (lch & 0x1f))); + edma_shadow0_write_array(SH_IESR, lch >> 5, + (1 << (lch & 0x1f))); } } @@ -545,6 +474,7 @@ void davinci_dma_getposition(int lch, dm *dst = temp.dst; } EXPORT_SYMBOL(davinci_dma_getposition); + /****************************************************************************** * * DMA interrupt handler @@ -850,19 +780,10 @@ int davinci_request_dma(int dev_id, cons } else dev_dbg(&edma_dev.dev, "param_no=%d\r\n", dma_chan[*lch].param_no); - if (callback) { - dma_chan[*lch].tcc = - request_dma_interrupt(*lch, callback, data, - dma_chan[*lch]. - param_no, *tcc); - if (dma_chan[*lch].tcc == -1) { - return -EINVAL; - } else { - *tcc = dma_chan[*lch].tcc; - dev_dbg(&edma_dev.dev, "tcc_no=%d\r\n", - dma_chan[*lch].tcc); - } - } else + + if (callback) + setup_dma_interrupt(dev_id, callback, data); + else dma_chan[*lch].tcc = -1; map_dmach_queue(dev_id, eventq_no); @@ -892,17 +813,12 @@ int davinci_request_dma(int dev_id, cons dev_dbg(&edma_dev.dev, "param_no=%d\r\n", j); edma_or_array2(EDMA_DRAE, 0, j >> 5, 1 << (j & 0x1f)); - if (callback) { - dma_chan[*lch].tcc = - request_dma_interrupt(*lch, - callback, data, - j, *tcc); - if (dma_chan[*lch].tcc == -1) - return -EINVAL; - *tcc = dma_chan[*lch].tcc; - } else { + + if (callback) + setup_dma_interrupt(i, callback, data); + else dma_chan[*lch].tcc = -1; - } + map_dmach_queue(*lch, eventq_no); ret_val = 0; break; @@ -928,10 +844,8 @@ int davinci_request_dma(int dev_id, cons "param_no=%d\r\n", dma_chan[*lch].param_no); } - if (*tcc != -1) + if (tcc) dma_chan[*lch].tcc = *tcc; - else - dma_chan[*lch].tcc = -1; ret_val = 0; break; } @@ -958,6 +872,9 @@ int davinci_request_dma(int dev_id, cons } /* assign the link field to no link. i.e 0xffff */ edma_parm_or(PARM_LINK_BCNTRLD, j, 0xffff); + + if (tcc) + *tcc = dma_chan[*lch].tcc; } return ret_val; } @@ -980,7 +897,7 @@ void davinci_free_dma(int lch) free_param(dma_chan[lch].param_no); if ((lch >= 0) && (lch < DAVINCI_EDMA_NUM_DMACH)) - free_dma_interrupt(dma_chan[lch].tcc); + setup_dma_interrupt(lch, NULL, NULL); } EXPORT_SYMBOL(davinci_free_dma); _______________________________________________ Davinci-linux-open-source mailing list [email protected] http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
