各位专家好:
我在使用spi flash是发现写数据会卡死,经初步定位到DMA的中断处理函数没有调用DMA完成回调函数,
请问各位下面这两个中断处理函数分别用来做什么的, 希望能够帮我注释一下, 谢谢!
/******************************************************************************
*
* DMA interrupt handler
*
*****************************************************************************/
static irqreturn_t dma_irq_handler(int irq, void *data)
{
int i;
unsigned ctlr;
unsigned int cnt = 0;
ctlr = irq2ctlr(irq);
dev_dbg(data, "dma_irq_handler\n");
if ((edma_shadow0_read_array(ctlr, SH_IPR, 0) == 0)
&& (edma_shadow0_read_array(ctlr, SH_IPR, 1) == 0))
return IRQ_NONE;
while (1) {
int j;
if (edma_shadow0_read_array(ctlr, SH_IPR, 0) &
edma_shadow0_read_array(ctlr, SH_IER, 0))
j = 0;
else if (edma_shadow0_read_array(ctlr, SH_IPR, 1) &
edma_shadow0_read_array(ctlr, SH_IER, 1))
j = 1;
else
break;
dev_dbg(data, "IPR%d %08x\n", j,
edma_shadow0_read_array(ctlr, SH_IPR, j));
for (i = 0; i < 32; i++) {
int k = (j << 5) + i;
if ((edma_shadow0_read_array(ctlr, SH_IPR, j) & BIT(i))
&& (edma_shadow0_read_array(ctlr,
SH_IER, j) & BIT(i))) {
/* Clear the corresponding IPR bits */
edma_shadow0_write_array(ctlr, SH_ICR, j,
(1 << i));
if (edma_info[ctlr]->intr_data[k].callback) {
edma_info[ctlr]->intr_data[k].callback(
k, DMA_COMPLETE,
edma_info[ctlr]->intr_data[k].
data);
}
}
}
cnt++;
if (cnt > 10)
break;
}
edma_shadow0_write(ctlr, SH_IEVAL, 1);
return IRQ_HANDLED;
}
/******************************************************************************
*
* DMA error interrupt handler
*
*****************************************************************************/
static irqreturn_t dma_ccerr_handler(int irq, void *data)
{
int i;
unsigned ctlr;
unsigned int cnt = 0;
ctlr = irq2ctlr(irq);
dev_dbg(data, "dma_ccerr_handler\n");
if ((edma_read_array(ctlr, EDMA_EMR, 0) == 0) &&
(edma_read_array(ctlr, EDMA_EMR, 1) == 0) &&
(edma_read(ctlr, EDMA_QEMR) == 0) &&
(edma_read(ctlr, EDMA_CCERR) == 0))
return IRQ_NONE;
while (1) {
int j = -1;
if (edma_read_array(ctlr, EDMA_EMR, 0))
j = 0;
else if (edma_read_array(ctlr, EDMA_EMR, 1))
j = 1;
if (j >= 0) {
// udelay(500); //added by longwei
dev_dbg(data, "EMR%d %08x\n", j,
edma_read_array(ctlr, EDMA_EMR, j)); //in here; control = 0; j = 0
for (i = 0; i < 32; i++) {
int k = (j << 5) + i;
if (edma_read_array(ctlr, EDMA_EMR, j) &
(1 << i)) {
/* Clear the corresponding EMR bits */
edma_write_array(ctlr, EDMA_EMCR, j,
1 << i);
/* Clear any SER */
edma_shadow0_write_array(ctlr, SH_SECR,
j, (1 << i));
if (edma_info[ctlr]->intr_data[k].
callback) {
edma_info[ctlr]->intr_data[k].
callback(k,
DMA_CC_ERROR,
edma_info[ctlr]->intr_data
[k].data);
}
}
}
} else if (edma_read(ctlr, EDMA_QEMR)) {
dev_dbg(data, "QEMR %02x\n",
edma_read(ctlr, EDMA_QEMR));
for (i = 0; i < 8; i++) {
if (edma_read(ctlr, EDMA_QEMR) & (1 << i)) {
/* Clear the corresponding IPR bits */
edma_write(ctlr, EDMA_QEMCR, 1 << i);
edma_shadow0_write(ctlr, SH_QSECR,
(1 << i));
/* NOTE: not reported!! */
}
}
} else if (edma_read(ctlr, EDMA_CCERR)) {
dev_dbg(data, "CCERR %08x\n",
edma_read(ctlr, EDMA_CCERR));
/* FIXME: CCERR.BIT(16) ignored! much better
* to just write CCERRCLR with CCERR value…
*/
for (i = 0; i < 8; i++) {
if (edma_read(ctlr, EDMA_CCERR) & (1 << i)) {
/* Clear the corresponding IPR bits */
edma_write(ctlr, EDMA_CCERRCLR, 1 << i);
/* NOTE: not reported!! */
}
}
}
if ((edma_read_array(ctlr, EDMA_EMR, 0) == 0)
&& (edma_read_array(ctlr, EDMA_EMR, 1) == 0)
&& (edma_read(ctlr, EDMA_QEMR) == 0)
&& (edma_read(ctlr, EDMA_CCERR) == 0)) {
break;
}
cnt++;
if (cnt > 10)
break;
}
edma_write(ctlr, EDMA_EEVAL, 1);
return IRQ_HANDLED;
}
Chris Meng:
你好,
建议你结合一下DM36x EDMA user guide文档,了解中断函数里面的配置含义。