tangled
alpha
login
or
join now
tjh.dev
/
kernel
1
fork
atom
Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
1
fork
atom
overview
issues
pulls
pipelines
Merge branch 'topic/xilinx' into for-linus
Vinod Koul
9 years ago
b7b0201a
3378e7a4
+35
-28
1 changed file
expand all
collapse all
unified
split
drivers
dma
xilinx
xilinx_dma.c
+35
-28
drivers/dma/xilinx/xilinx_dma.c
reviewed
···
331
331
* @seg_v: Statically allocated segments base
332
332
* @cyclic_seg_v: Statically allocated segment base for cyclic transfers
333
333
* @start_transfer: Differentiate b/w DMA IP's transfer
334
334
+
* @stop_transfer: Differentiate b/w DMA IP's quiesce
334
335
*/
335
336
struct xilinx_dma_chan {
336
337
struct xilinx_dma_device *xdev;
···
362
361
struct xilinx_axidma_tx_segment *seg_v;
363
362
struct xilinx_axidma_tx_segment *cyclic_seg_v;
364
363
void (*start_transfer)(struct xilinx_dma_chan *chan);
364
364
+
int (*stop_transfer)(struct xilinx_dma_chan *chan);
365
365
u16 tdest;
366
366
};
367
367
···
948
946
}
949
947
950
948
/**
951
951
-
* xilinx_dma_halt - Halt DMA channel
949
949
+
* xilinx_dma_stop_transfer - Halt DMA channel
952
950
* @chan: Driver specific DMA channel
953
951
*/
954
954
-
static void xilinx_dma_halt(struct xilinx_dma_chan *chan)
952
952
+
static int xilinx_dma_stop_transfer(struct xilinx_dma_chan *chan)
955
953
{
956
956
-
int err;
957
954
u32 val;
958
955
959
956
dma_ctrl_clr(chan, XILINX_DMA_REG_DMACR, XILINX_DMA_DMACR_RUNSTOP);
960
957
961
958
/* Wait for the hardware to halt */
962
962
-
err = xilinx_dma_poll_timeout(chan, XILINX_DMA_REG_DMASR, val,
963
963
-
(val & XILINX_DMA_DMASR_HALTED), 0,
964
964
-
XILINX_DMA_LOOP_COUNT);
959
959
+
return xilinx_dma_poll_timeout(chan, XILINX_DMA_REG_DMASR, val,
960
960
+
val & XILINX_DMA_DMASR_HALTED, 0,
961
961
+
XILINX_DMA_LOOP_COUNT);
962
962
+
}
965
963
966
966
-
if (err) {
967
967
-
dev_err(chan->dev, "Cannot stop channel %p: %x\n",
968
968
-
chan, dma_ctrl_read(chan, XILINX_DMA_REG_DMASR));
969
969
-
chan->err = true;
970
970
-
}
964
964
+
/**
965
965
+
* xilinx_cdma_stop_transfer - Wait for the current transfer to complete
966
966
+
* @chan: Driver specific DMA channel
967
967
+
*/
968
968
+
static int xilinx_cdma_stop_transfer(struct xilinx_dma_chan *chan)
969
969
+
{
970
970
+
u32 val;
971
971
+
972
972
+
return xilinx_dma_poll_timeout(chan, XILINX_DMA_REG_DMASR, val,
973
973
+
val & XILINX_DMA_DMASR_IDLE, 0,
974
974
+
XILINX_DMA_LOOP_COUNT);
971
975
}
972
976
973
977
/**
···
1661
1653
{
1662
1654
struct xilinx_dma_chan *chan = to_xilinx_chan(dchan);
1663
1655
struct xilinx_dma_tx_descriptor *desc;
1664
1664
-
struct xilinx_cdma_tx_segment *segment, *prev;
1656
1656
+
struct xilinx_cdma_tx_segment *segment;
1665
1657
struct xilinx_cdma_desc_hw *hw;
1666
1658
1667
1659
if (!len || len > XILINX_DMA_MAX_TRANS_LEN)
···
1688
1680
hw->dest_addr_msb = upper_32_bits(dma_dst);
1689
1681
}
1690
1682
1691
1691
-
/* Fill the previous next descriptor with current */
1692
1692
-
prev = list_last_entry(&desc->segments,
1693
1693
-
struct xilinx_cdma_tx_segment, node);
1694
1694
-
prev->hw.next_desc = segment->phys;
1695
1695
-
1696
1683
/* Insert the segment into the descriptor segments list. */
1697
1684
list_add_tail(&segment->node, &desc->segments);
1698
1685
1699
1699
-
prev = segment;
1700
1700
-
1701
1701
-
/* Link the last hardware descriptor with the first. */
1702
1702
-
segment = list_first_entry(&desc->segments,
1703
1703
-
struct xilinx_cdma_tx_segment, node);
1704
1686
desc->async_tx.phys = segment->phys;
1705
1705
-
prev->hw.next_desc = segment->phys;
1687
1687
+
hw->next_desc = segment->phys;
1706
1688
1707
1689
return &desc->async_tx;
1708
1690
···
2001
2003
{
2002
2004
struct xilinx_dma_chan *chan = to_xilinx_chan(dchan);
2003
2005
u32 reg;
2006
2006
+
int err;
2004
2007
2005
2008
if (chan->cyclic)
2006
2009
xilinx_dma_chan_reset(chan);
2007
2010
2008
2008
-
/* Halt the DMA engine */
2009
2009
-
xilinx_dma_halt(chan);
2011
2011
+
err = chan->stop_transfer(chan);
2012
2012
+
if (err) {
2013
2013
+
dev_err(chan->dev, "Cannot stop channel %p: %x\n",
2014
2014
+
chan, dma_ctrl_read(chan, XILINX_DMA_REG_DMASR));
2015
2015
+
chan->err = true;
2016
2016
+
}
2010
2017
2011
2018
/* Remove and free all of the descriptors in the lists */
2012
2019
xilinx_dma_free_descriptors(chan);
···
2400
2397
return err;
2401
2398
}
2402
2399
2403
2403
-
if (xdev->dma_config->dmatype == XDMA_TYPE_AXIDMA)
2400
2400
+
if (xdev->dma_config->dmatype == XDMA_TYPE_AXIDMA) {
2404
2401
chan->start_transfer = xilinx_dma_start_transfer;
2405
2405
-
else if (xdev->dma_config->dmatype == XDMA_TYPE_CDMA)
2402
2402
+
chan->stop_transfer = xilinx_dma_stop_transfer;
2403
2403
+
} else if (xdev->dma_config->dmatype == XDMA_TYPE_CDMA) {
2406
2404
chan->start_transfer = xilinx_cdma_start_transfer;
2407
2407
-
else
2405
2405
+
chan->stop_transfer = xilinx_cdma_stop_transfer;
2406
2406
+
} else {
2408
2407
chan->start_transfer = xilinx_vdma_start_transfer;
2408
2408
+
chan->stop_transfer = xilinx_dma_stop_transfer;
2409
2409
+
}
2409
2410
2410
2411
/* Initialize the tasklet */
2411
2412
tasklet_init(&chan->tasklet, xilinx_dma_do_tasklet,