int cpdma_ctlr_stop(struct cpdma_ctlr *ctlr) { unsigned long flags; int i; spin_lock_irqsave(&ctlr->lock, flags); if (ctlr->state != CPDMA_STATE_ACTIVE) { spin_unlock_irqrestore(&ctlr->lock, flags); return -EINVAL; } ctlr->state = CPDMA_STATE_TEARDOWN; for (i = 0; i < ARRAY_SIZE(ctlr->channels); i++) { if (ctlr->channels[i]) cpdma_chan_stop(ctlr->channels[i]); } dma_reg_write(ctlr, CPDMA_RXINTMASKCLEAR, 0xffffffff); dma_reg_write(ctlr, CPDMA_TXINTMASKCLEAR, 0xffffffff); dma_reg_write(ctlr, CPDMA_TXCONTROL, 0); dma_reg_write(ctlr, CPDMA_RXCONTROL, 0); ctlr->state = CPDMA_STATE_IDLE; spin_unlock_irqrestore(&ctlr->lock, flags); return 0; }
int cpdma_ctlr_stop(struct cpdma_ctlr *ctlr) { rtdm_lockctx_t context; int i; rtdm_lock_get_irqsave(&ctlr->lock, context); if (ctlr->state != CPDMA_STATE_ACTIVE) { rtdm_lock_put_irqrestore(&ctlr->lock, context); return -EINVAL; } ctlr->state = CPDMA_STATE_TEARDOWN; for (i = 0; i < ARRAY_SIZE(ctlr->channels); i++) { if (ctlr->channels[i]) cpdma_chan_stop(ctlr->channels[i]); } dma_reg_write(ctlr, CPDMA_RXINTMASKCLEAR, 0xffffffff); dma_reg_write(ctlr, CPDMA_TXINTMASKCLEAR, 0xffffffff); dma_reg_write(ctlr, CPDMA_TXCONTROL, 0); dma_reg_write(ctlr, CPDMA_RXCONTROL, 0); ctlr->state = CPDMA_STATE_IDLE; rtdm_lock_put_irqrestore(&ctlr->lock, context); return 0; }
static void cpsw_ndo_tx_timeout(struct net_device *ndev) { struct cpsw_priv *priv = netdev_priv(ndev); cpsw_err(priv, tx_err, "transmit timeout, restarting dma\n"); priv->stats.tx_errors++; cpsw_intr_disable(priv); cpdma_ctlr_int_ctrl(priv->dma, false); cpdma_chan_stop(priv->txch); cpdma_chan_start(priv->txch); cpdma_ctlr_int_ctrl(priv->dma, true); cpsw_intr_enable(priv); cpdma_ctlr_eoi(priv->dma); }
int cpdma_chan_destroy(struct cpdma_chan *chan) { struct cpdma_ctlr *ctlr = chan->ctlr; unsigned long flags; if (!chan) return -EINVAL; spin_lock_irqsave(&ctlr->lock, flags); if (chan->state != CPDMA_STATE_IDLE) cpdma_chan_stop(chan); ctlr->channels[chan->chan_num] = NULL; spin_unlock_irqrestore(&ctlr->lock, flags); kfree(chan); return 0; }
int cpdma_chan_destroy(struct cpdma_chan *chan) { struct cpdma_ctlr *ctlr; rtdm_lockctx_t context; if (!chan) return -EINVAL; ctlr = chan->ctlr; rtdm_lock_get_irqsave(&ctlr->lock, context); if (chan->state != CPDMA_STATE_IDLE) cpdma_chan_stop(chan); ctlr->channels[chan->chan_num] = NULL; rtdm_lock_put_irqrestore(&ctlr->lock, context); kfree(chan); return 0; }