Merge branch 'fixes' into next
This commit is contained in:
@@ -134,6 +134,10 @@
|
||||
#define SPRD_DMA_SRC_TRSF_STEP_OFFSET 0
|
||||
#define SPRD_DMA_TRSF_STEP_MASK GENMASK(15, 0)
|
||||
|
||||
/* SPRD DMA_SRC_BLK_STEP register definition */
|
||||
#define SPRD_DMA_LLIST_HIGH_MASK GENMASK(31, 28)
|
||||
#define SPRD_DMA_LLIST_HIGH_SHIFT 28
|
||||
|
||||
/* define DMA channel mode & trigger mode mask */
|
||||
#define SPRD_DMA_CHN_MODE_MASK GENMASK(7, 0)
|
||||
#define SPRD_DMA_TRG_MODE_MASK GENMASK(7, 0)
|
||||
@@ -208,6 +212,7 @@ struct sprd_dma_dev {
|
||||
struct sprd_dma_chn channels[0];
|
||||
};
|
||||
|
||||
static void sprd_dma_free_desc(struct virt_dma_desc *vd);
|
||||
static bool sprd_dma_filter_fn(struct dma_chan *chan, void *param);
|
||||
static struct of_dma_filter_info sprd_dma_info = {
|
||||
.filter_fn = sprd_dma_filter_fn,
|
||||
@@ -609,12 +614,19 @@ static int sprd_dma_alloc_chan_resources(struct dma_chan *chan)
|
||||
static void sprd_dma_free_chan_resources(struct dma_chan *chan)
|
||||
{
|
||||
struct sprd_dma_chn *schan = to_sprd_dma_chan(chan);
|
||||
struct virt_dma_desc *cur_vd = NULL;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&schan->vc.lock, flags);
|
||||
if (schan->cur_desc)
|
||||
cur_vd = &schan->cur_desc->vd;
|
||||
|
||||
sprd_dma_stop(schan);
|
||||
spin_unlock_irqrestore(&schan->vc.lock, flags);
|
||||
|
||||
if (cur_vd)
|
||||
sprd_dma_free_desc(cur_vd);
|
||||
|
||||
vchan_free_chan_resources(&schan->vc);
|
||||
pm_runtime_put(chan->device->dev);
|
||||
}
|
||||
@@ -717,6 +729,7 @@ static int sprd_dma_fill_desc(struct dma_chan *chan,
|
||||
u32 int_mode = flags & SPRD_DMA_INT_MASK;
|
||||
int src_datawidth, dst_datawidth, src_step, dst_step;
|
||||
u32 temp, fix_mode = 0, fix_en = 0;
|
||||
phys_addr_t llist_ptr;
|
||||
|
||||
if (dir == DMA_MEM_TO_DEV) {
|
||||
src_step = sprd_dma_get_step(slave_cfg->src_addr_width);
|
||||
@@ -814,13 +827,16 @@ static int sprd_dma_fill_desc(struct dma_chan *chan,
|
||||
* Set the link-list pointer point to next link-list
|
||||
* configuration's physical address.
|
||||
*/
|
||||
hw->llist_ptr = schan->linklist.phy_addr + temp;
|
||||
llist_ptr = schan->linklist.phy_addr + temp;
|
||||
hw->llist_ptr = lower_32_bits(llist_ptr);
|
||||
hw->src_blk_step = (upper_32_bits(llist_ptr) << SPRD_DMA_LLIST_HIGH_SHIFT) &
|
||||
SPRD_DMA_LLIST_HIGH_MASK;
|
||||
} else {
|
||||
hw->llist_ptr = 0;
|
||||
hw->src_blk_step = 0;
|
||||
}
|
||||
|
||||
hw->frg_step = 0;
|
||||
hw->src_blk_step = 0;
|
||||
hw->des_blk_step = 0;
|
||||
return 0;
|
||||
}
|
||||
@@ -1023,15 +1039,22 @@ static int sprd_dma_resume(struct dma_chan *chan)
|
||||
static int sprd_dma_terminate_all(struct dma_chan *chan)
|
||||
{
|
||||
struct sprd_dma_chn *schan = to_sprd_dma_chan(chan);
|
||||
struct virt_dma_desc *cur_vd = NULL;
|
||||
unsigned long flags;
|
||||
LIST_HEAD(head);
|
||||
|
||||
spin_lock_irqsave(&schan->vc.lock, flags);
|
||||
if (schan->cur_desc)
|
||||
cur_vd = &schan->cur_desc->vd;
|
||||
|
||||
sprd_dma_stop(schan);
|
||||
|
||||
vchan_get_all_descriptors(&schan->vc, &head);
|
||||
spin_unlock_irqrestore(&schan->vc.lock, flags);
|
||||
|
||||
if (cur_vd)
|
||||
sprd_dma_free_desc(cur_vd);
|
||||
|
||||
vchan_dma_desc_free_list(&schan->vc, &head);
|
||||
return 0;
|
||||
}
|
||||
|
Reference in New Issue
Block a user