lkml.org 
[lkml]   [2014]   [Oct]   [22]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v3 38/59] dmaengine: sa11x0: Split device_control
    Date
    Split the device_control callback of the SA-11x0 DMA driver to make use of the
    newly introduced callbacks, that will eventually be used to retrieve slave
    capabilities.

    Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
    ---
    drivers/dma/sa11x0-dma.c | 158 +++++++++++++++++++++++++----------------------
    1 file changed, 84 insertions(+), 74 deletions(-)

    diff --git a/drivers/dma/sa11x0-dma.c b/drivers/dma/sa11x0-dma.c
    index 4b0ef043729a..432342459ab5 100644
    --- a/drivers/dma/sa11x0-dma.c
    +++ b/drivers/dma/sa11x0-dma.c
    @@ -669,8 +669,10 @@ static struct dma_async_tx_descriptor *sa11x0_dma_prep_dma_cyclic(
    return vchan_tx_prep(&c->vc, &txd->vd, DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
    }

    -static int sa11x0_dma_slave_config(struct sa11x0_dma_chan *c, struct dma_slave_config *cfg)
    +static int sa11x0_dma_slave_config(struct dma_chan *chan,
    + struct dma_slave_config *cfg)
    {
    + struct sa11x0_dma_chan *c = to_sa11x0_dma_chan(chan);
    u32 ddar = c->ddar & ((0xf << 4) | DDAR_RW);
    dma_addr_t addr;
    enum dma_slave_buswidth width;
    @@ -704,8 +706,7 @@ static int sa11x0_dma_slave_config(struct sa11x0_dma_chan *c, struct dma_slave_c
    return 0;
    }

    -static int sa11x0_dma_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
    - unsigned long arg)
    +static int sa11x0_dma_pause(struct dma_chan *chan)
    {
    struct sa11x0_dma_chan *c = to_sa11x0_dma_chan(chan);
    struct sa11x0_dma_dev *d = to_sa11x0_dma(chan->device);
    @@ -714,89 +715,95 @@ static int sa11x0_dma_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
    unsigned long flags;
    int ret;

    - switch (cmd) {
    - case DMA_SLAVE_CONFIG:
    - return sa11x0_dma_slave_config(c, (struct dma_slave_config *)arg);
    -
    - case DMA_TERMINATE_ALL:
    - dev_dbg(d->slave.dev, "vchan %p: terminate all\n", &c->vc);
    - /* Clear the tx descriptor lists */
    - spin_lock_irqsave(&c->vc.lock, flags);
    - vchan_get_all_descriptors(&c->vc, &head);
    + dev_dbg(d->slave.dev, "vchan %p: pause\n", &c->vc);
    + spin_lock_irqsave(&c->vc.lock, flags);
    + if (c->status == DMA_IN_PROGRESS) {
    + c->status = DMA_PAUSED;

    p = c->phy;
    if (p) {
    - dev_dbg(d->slave.dev, "pchan %u: terminating\n", p->num);
    - /* vchan is assigned to a pchan - stop the channel */
    - writel(DCSR_RUN | DCSR_IE |
    - DCSR_STRTA | DCSR_DONEA |
    - DCSR_STRTB | DCSR_DONEB,
    - p->base + DMA_DCSR_C);
    -
    - if (p->txd_load) {
    - if (p->txd_load != p->txd_done)
    - list_add_tail(&p->txd_load->vd.node, &head);
    - p->txd_load = NULL;
    - }
    - if (p->txd_done) {
    - list_add_tail(&p->txd_done->vd.node, &head);
    - p->txd_done = NULL;
    - }
    - c->phy = NULL;
    + writel(DCSR_RUN | DCSR_IE, p->base + DMA_DCSR_C);
    + } else {
    spin_lock(&d->lock);
    - p->vchan = NULL;
    + list_del_init(&c->node);
    spin_unlock(&d->lock);
    - tasklet_schedule(&d->task);
    }
    - spin_unlock_irqrestore(&c->vc.lock, flags);
    - vchan_dma_desc_free_list(&c->vc, &head);
    - ret = 0;
    - break;
    + }
    + spin_unlock_irqrestore(&c->vc.lock, flags);

    - case DMA_PAUSE:
    - dev_dbg(d->slave.dev, "vchan %p: pause\n", &c->vc);
    - spin_lock_irqsave(&c->vc.lock, flags);
    - if (c->status == DMA_IN_PROGRESS) {
    - c->status = DMA_PAUSED;
    + return 0;
    +}

    - p = c->phy;
    - if (p) {
    - writel(DCSR_RUN | DCSR_IE, p->base + DMA_DCSR_C);
    - } else {
    - spin_lock(&d->lock);
    - list_del_init(&c->node);
    - spin_unlock(&d->lock);
    - }
    - }
    - spin_unlock_irqrestore(&c->vc.lock, flags);
    - ret = 0;
    - break;
    +static int sa11x0_dma_resume(struct dma_chan *chan)
    +{
    + struct sa11x0_dma_chan *c = to_sa11x0_dma_chan(chan);
    + struct sa11x0_dma_dev *d = to_sa11x0_dma(chan->device);
    + struct sa11x0_dma_phy *p;
    + LIST_HEAD(head);
    + unsigned long flags;
    + int ret;

    - case DMA_RESUME:
    - dev_dbg(d->slave.dev, "vchan %p: resume\n", &c->vc);
    - spin_lock_irqsave(&c->vc.lock, flags);
    - if (c->status == DMA_PAUSED) {
    - c->status = DMA_IN_PROGRESS;
    -
    - p = c->phy;
    - if (p) {
    - writel(DCSR_RUN | DCSR_IE, p->base + DMA_DCSR_S);
    - } else if (!list_empty(&c->vc.desc_issued)) {
    - spin_lock(&d->lock);
    - list_add_tail(&c->node, &d->chan_pending);
    - spin_unlock(&d->lock);
    - }
    + dev_dbg(d->slave.dev, "vchan %p: resume\n", &c->vc);
    + spin_lock_irqsave(&c->vc.lock, flags);
    + if (c->status == DMA_PAUSED) {
    + c->status = DMA_IN_PROGRESS;
    +
    + p = c->phy;
    + if (p) {
    + writel(DCSR_RUN | DCSR_IE, p->base + DMA_DCSR_S);
    + } else if (!list_empty(&c->vc.desc_issued)) {
    + spin_lock(&d->lock);
    + list_add_tail(&c->node, &d->chan_pending);
    + spin_unlock(&d->lock);
    }
    - spin_unlock_irqrestore(&c->vc.lock, flags);
    - ret = 0;
    - break;
    + }
    + spin_unlock_irqrestore(&c->vc.lock, flags);

    - default:
    - ret = -ENXIO;
    - break;
    + return 0;
    +}
    +
    +static int sa11x0_dma_terminate_all(struct dma_chan *chan)
    +{
    + struct sa11x0_dma_chan *c = to_sa11x0_dma_chan(chan);
    + struct sa11x0_dma_dev *d = to_sa11x0_dma(chan->device);
    + struct sa11x0_dma_phy *p;
    + LIST_HEAD(head);
    + unsigned long flags;
    + int ret;
    +
    + dev_dbg(d->slave.dev, "vchan %p: terminate all\n", &c->vc);
    + /* Clear the tx descriptor lists */
    + spin_lock_irqsave(&c->vc.lock, flags);
    + vchan_get_all_descriptors(&c->vc, &head);
    +
    + p = c->phy;
    + if (p) {
    + dev_dbg(d->slave.dev, "pchan %u: terminating\n", p->num);
    + /* vchan is assigned to a pchan - stop the channel */
    + writel(DCSR_RUN | DCSR_IE |
    + DCSR_STRTA | DCSR_DONEA |
    + DCSR_STRTB | DCSR_DONEB,
    + p->base + DMA_DCSR_C);
    +
    + if (p->txd_load) {
    + if (p->txd_load != p->txd_done)
    + list_add_tail(&p->txd_load->vd.node, &head);
    + p->txd_load = NULL;
    + }
    + if (p->txd_done) {
    + list_add_tail(&p->txd_done->vd.node, &head);
    + p->txd_done = NULL;
    + }
    + c->phy = NULL;
    + spin_lock(&d->lock);
    + p->vchan = NULL;
    + spin_unlock(&d->lock);
    + tasklet_schedule(&d->task);
    }
    + spin_unlock_irqrestore(&c->vc.lock, flags);
    + vchan_dma_desc_free_list(&c->vc, &head);

    - return ret;
    + return 0;
    }

    struct sa11x0_dma_channel_desc {
    @@ -834,7 +841,10 @@ static int sa11x0_dma_init_dmadev(struct dma_device *dmadev,
    dmadev->dev = dev;
    dmadev->device_alloc_chan_resources = sa11x0_dma_alloc_chan_resources;
    dmadev->device_free_chan_resources = sa11x0_dma_free_chan_resources;
    - dmadev->device_control = sa11x0_dma_control;
    + dmadev->device_config = sa11x0_dma_slave_config;
    + dmadev->device_pause = sa11x0_dma_pause;
    + dmadev->device_resume = sa11x0_dma_resume;
    + dmadev->device_terminate_all = sa11x0_dma_terminate_all;
    dmadev->device_tx_status = sa11x0_dma_tx_status;
    dmadev->device_issue_pending = sa11x0_dma_issue_pending;

    --
    2.1.1


    \
     
     \ /
      Last update: 2014-10-22 18:21    [W:4.075 / U:0.216 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site