TI中文支持网
TI专业的中文技术问题搜集分享网站

DM365 EDMA驱动相关问题

各位专家好:

我在使用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文档,了解中断函数里面的配置含义。

赞(0)
未经允许不得转载:TI中文支持网 » DM365 EDMA驱动相关问题
分享到: 更多 (0)