diff options
-rw-r--r-- | drivers/dma/ipu/ipu_idmac.c | 65 |
1 files changed, 56 insertions, 9 deletions
diff --git a/drivers/dma/ipu/ipu_idmac.c b/drivers/dma/ipu/ipu_idmac.c index 7ce0e25266dc..90773844cc89 100644 --- a/drivers/dma/ipu/ipu_idmac.c +++ b/drivers/dma/ipu/ipu_idmac.c | |||
@@ -1442,8 +1442,8 @@ static struct dma_async_tx_descriptor *idmac_prep_slave_sg(struct dma_chan *chan | |||
1442 | unsigned long flags; | 1442 | unsigned long flags; |
1443 | 1443 | ||
1444 | /* We only can handle these three channels so far */ | 1444 | /* We only can handle these three channels so far */ |
1445 | if (ichan->dma_chan.chan_id != IDMAC_SDC_0 && ichan->dma_chan.chan_id != IDMAC_SDC_1 && | 1445 | if (chan->chan_id != IDMAC_SDC_0 && chan->chan_id != IDMAC_SDC_1 && |
1446 | ichan->dma_chan.chan_id != IDMAC_IC_7) | 1446 | chan->chan_id != IDMAC_IC_7) |
1447 | return NULL; | 1447 | return NULL; |
1448 | 1448 | ||
1449 | if (direction != DMA_FROM_DEVICE && direction != DMA_TO_DEVICE) { | 1449 | if (direction != DMA_FROM_DEVICE && direction != DMA_TO_DEVICE) { |
@@ -1484,7 +1484,7 @@ static void idmac_issue_pending(struct dma_chan *chan) | |||
1484 | 1484 | ||
1485 | /* This is not always needed, but doesn't hurt either */ | 1485 | /* This is not always needed, but doesn't hurt either */ |
1486 | spin_lock_irqsave(&ipu->lock, flags); | 1486 | spin_lock_irqsave(&ipu->lock, flags); |
1487 | ipu_select_buffer(ichan->dma_chan.chan_id, ichan->active_buffer); | 1487 | ipu_select_buffer(chan->chan_id, ichan->active_buffer); |
1488 | spin_unlock_irqrestore(&ipu->lock, flags); | 1488 | spin_unlock_irqrestore(&ipu->lock, flags); |
1489 | 1489 | ||
1490 | /* | 1490 | /* |
@@ -1541,6 +1541,28 @@ static void idmac_terminate_all(struct dma_chan *chan) | |||
1541 | mutex_unlock(&ichan->chan_mutex); | 1541 | mutex_unlock(&ichan->chan_mutex); |
1542 | } | 1542 | } |
1543 | 1543 | ||
1544 | #ifdef DEBUG | ||
1545 | static irqreturn_t ic_sof_irq(int irq, void *dev_id) | ||
1546 | { | ||
1547 | struct idmac_channel *ichan = dev_id; | ||
1548 | printk(KERN_DEBUG "Got SOF IRQ %d on Channel %d\n", | ||
1549 | irq, ichan->dma_chan.chan_id); | ||
1550 | disable_irq(irq); | ||
1551 | return IRQ_HANDLED; | ||
1552 | } | ||
1553 | |||
1554 | static irqreturn_t ic_eof_irq(int irq, void *dev_id) | ||
1555 | { | ||
1556 | struct idmac_channel *ichan = dev_id; | ||
1557 | printk(KERN_DEBUG "Got EOF IRQ %d on Channel %d\n", | ||
1558 | irq, ichan->dma_chan.chan_id); | ||
1559 | disable_irq(irq); | ||
1560 | return IRQ_HANDLED; | ||
1561 | } | ||
1562 | |||
1563 | static int ic_sof = -EINVAL, ic_eof = -EINVAL; | ||
1564 | #endif | ||
1565 | |||
1544 | static int idmac_alloc_chan_resources(struct dma_chan *chan) | 1566 | static int idmac_alloc_chan_resources(struct dma_chan *chan) |
1545 | { | 1567 | { |
1546 | struct idmac_channel *ichan = to_idmac_chan(chan); | 1568 | struct idmac_channel *ichan = to_idmac_chan(chan); |
@@ -1554,7 +1576,7 @@ static int idmac_alloc_chan_resources(struct dma_chan *chan) | |||
1554 | chan->cookie = 1; | 1576 | chan->cookie = 1; |
1555 | ichan->completed = -ENXIO; | 1577 | ichan->completed = -ENXIO; |
1556 | 1578 | ||
1557 | ret = ipu_irq_map(ichan->dma_chan.chan_id); | 1579 | ret = ipu_irq_map(chan->chan_id); |
1558 | if (ret < 0) | 1580 | if (ret < 0) |
1559 | goto eimap; | 1581 | goto eimap; |
1560 | 1582 | ||
@@ -1575,17 +1597,28 @@ static int idmac_alloc_chan_resources(struct dma_chan *chan) | |||
1575 | if (ret < 0) | 1597 | if (ret < 0) |
1576 | goto erirq; | 1598 | goto erirq; |
1577 | 1599 | ||
1600 | #ifdef DEBUG | ||
1601 | if (chan->chan_id == IDMAC_IC_7) { | ||
1602 | ic_sof = ipu_irq_map(69); | ||
1603 | if (ic_sof > 0) | ||
1604 | request_irq(ic_sof, ic_sof_irq, 0, "IC SOF", ichan); | ||
1605 | ic_eof = ipu_irq_map(70); | ||
1606 | if (ic_eof > 0) | ||
1607 | request_irq(ic_eof, ic_eof_irq, 0, "IC EOF", ichan); | ||
1608 | } | ||
1609 | #endif | ||
1610 | |||
1578 | ichan->status = IPU_CHANNEL_INITIALIZED; | 1611 | ichan->status = IPU_CHANNEL_INITIALIZED; |
1579 | 1612 | ||
1580 | dev_dbg(&ichan->dma_chan.dev->device, "Found channel 0x%x, irq %d\n", | 1613 | dev_dbg(&chan->dev->device, "Found channel 0x%x, irq %d\n", |
1581 | ichan->dma_chan.chan_id, ichan->eof_irq); | 1614 | chan->chan_id, ichan->eof_irq); |
1582 | 1615 | ||
1583 | return ret; | 1616 | return ret; |
1584 | 1617 | ||
1585 | erirq: | 1618 | erirq: |
1586 | ipu_uninit_channel(idmac, ichan); | 1619 | ipu_uninit_channel(idmac, ichan); |
1587 | eichan: | 1620 | eichan: |
1588 | ipu_irq_unmap(ichan->dma_chan.chan_id); | 1621 | ipu_irq_unmap(chan->chan_id); |
1589 | eimap: | 1622 | eimap: |
1590 | return ret; | 1623 | return ret; |
1591 | } | 1624 | } |
@@ -1600,8 +1633,22 @@ static void idmac_free_chan_resources(struct dma_chan *chan) | |||
1600 | __idmac_terminate_all(chan); | 1633 | __idmac_terminate_all(chan); |
1601 | 1634 | ||
1602 | if (ichan->status > IPU_CHANNEL_FREE) { | 1635 | if (ichan->status > IPU_CHANNEL_FREE) { |
1636 | #ifdef DEBUG | ||
1637 | if (chan->chan_id == IDMAC_IC_7) { | ||
1638 | if (ic_sof > 0) { | ||
1639 | free_irq(ic_sof, ichan); | ||
1640 | ipu_irq_unmap(69); | ||
1641 | ic_sof = -EINVAL; | ||
1642 | } | ||
1643 | if (ic_eof > 0) { | ||
1644 | free_irq(ic_eof, ichan); | ||
1645 | ipu_irq_unmap(70); | ||
1646 | ic_eof = -EINVAL; | ||
1647 | } | ||
1648 | } | ||
1649 | #endif | ||
1603 | free_irq(ichan->eof_irq, ichan); | 1650 | free_irq(ichan->eof_irq, ichan); |
1604 | ipu_irq_unmap(ichan->dma_chan.chan_id); | 1651 | ipu_irq_unmap(chan->chan_id); |
1605 | } | 1652 | } |
1606 | 1653 | ||
1607 | ichan->status = IPU_CHANNEL_FREE; | 1654 | ichan->status = IPU_CHANNEL_FREE; |
@@ -1663,7 +1710,7 @@ static int __init ipu_idmac_init(struct ipu *ipu) | |||
1663 | dma_chan->device = &idmac->dma; | 1710 | dma_chan->device = &idmac->dma; |
1664 | dma_chan->cookie = 1; | 1711 | dma_chan->cookie = 1; |
1665 | dma_chan->chan_id = i; | 1712 | dma_chan->chan_id = i; |
1666 | list_add_tail(&ichan->dma_chan.device_node, &dma->channels); | 1713 | list_add_tail(&dma_chan->device_node, &dma->channels); |
1667 | } | 1714 | } |
1668 | 1715 | ||
1669 | idmac_write_icreg(ipu, 0x00000070, IDMAC_CONF); | 1716 | idmac_write_icreg(ipu, 0x00000070, IDMAC_CONF); |