Merge "mhi: core: Add support to create uncached event ring"

This commit is contained in:
qctecmdr 2020-04-19 03:16:33 -07:00 • committed by Gerrit - the friendly Code Review server
commit 8342759058
2 changed files with 59 additions and 3 deletions

View file

@ -223,6 +223,21 @@ static int mhi_alloc_aligned_ring(struct mhi_controller *mhi_cntrl,
return 0;
}
/* MHI protocol require transfer ring to be aligned to ring length */
static int mhi_alloc_aligned_ring_uncached(
struct mhi_controller *mhi_cntrl, struct mhi_ring *ring, u64 len)
{
ring->alloc_size = len + (len - 1);
ring->pre_aligned = mhi_alloc_uncached(mhi_cntrl, ring->alloc_size,
&ring->dma_handle, GFP_KERNEL);
if (!ring->pre_aligned)
return -ENOMEM;
ring->iommu_base = (ring->dma_handle + (len - 1)) & ~(len - 1);
ring->base = ring->pre_aligned + (ring->iommu_base - ring->dma_handle);
return 0;
}
void mhi_deinit_free_irq(struct mhi_controller *mhi_cntrl)
{
int i;
@ -307,7 +322,11 @@ void mhi_deinit_dev_ctxt(struct mhi_controller *mhi_cntrl)
continue;
ring = &mhi_event->ring;
mhi_free_coherent(mhi_cntrl, ring->alloc_size,
if (mhi_event->force_uncached)
mhi_free_uncached(mhi_cntrl, ring->alloc_size,
ring->pre_aligned, ring->dma_handle);
else
mhi_free_coherent(mhi_cntrl, ring->alloc_size,
ring->pre_aligned, ring->dma_handle);
ring->base = NULL;
ring->iommu_base = 0;
@ -463,7 +482,12 @@ int mhi_init_dev_ctxt(struct mhi_controller *mhi_cntrl)
ring->el_size = sizeof(struct mhi_tre);
ring->len = ring->el_size * ring->elements;
ret = mhi_alloc_aligned_ring(mhi_cntrl, ring, ring->len);
if (mhi_event->force_uncached)
ret = mhi_alloc_aligned_ring_uncached(mhi_cntrl, ring,
ring->len);
else
ret = mhi_alloc_aligned_ring(mhi_cntrl, ring,
ring->len);
if (ret)
goto error_alloc_er;
@ -524,7 +548,11 @@ error_alloc_er:
if (mhi_event->offload_ev)
continue;
mhi_free_coherent(mhi_cntrl, ring->alloc_size,
if (mhi_event->force_uncached)
mhi_free_uncached(mhi_cntrl, ring->alloc_size,
ring->pre_aligned, ring->dma_handle);
else
mhi_free_coherent(mhi_cntrl, ring->alloc_size,
ring->pre_aligned, ring->dma_handle);
}
mhi_free_coherent(mhi_cntrl, sizeof(*mhi_ctxt->er_ctxt) *
@ -988,6 +1016,10 @@ static int of_parse_ev_cfg(struct mhi_controller *mhi_cntrl,
continue;
mhi_event->er_index = i++;
mhi_event->force_uncached = of_property_read_bool(child,
"mhi,force-uncached");
ret = of_property_read_u32(child, "mhi,num-elements",
(u32 *)&mhi_event->ring.elements);
if (ret)

View file

@ -658,6 +658,7 @@ struct mhi_event {
struct mhi_controller *mhi_cntrl;
struct mhi_tre last_cached_tre;
u64 last_dev_rp;
bool force_uncached;
};
struct mhi_chan {
@ -860,6 +861,29 @@ static inline void mhi_free_coherent(struct mhi_controller *mhi_cntrl,
dma_free_coherent(mhi_cntrl->dev, size, vaddr, dma_handle);
}
static inline void *mhi_alloc_uncached(struct mhi_controller *mhi_cntrl,
size_t size,
dma_addr_t *dma_handle,
gfp_t gfp)
{
void *buf = dma_alloc_attrs(mhi_cntrl->dev, size, dma_handle, gfp,
DMA_ATTR_FORCE_NON_COHERENT);
if (buf)
atomic_add(size, &mhi_cntrl->alloc_size);
return buf;
}
static inline void mhi_free_uncached(struct mhi_controller *mhi_cntrl,
size_t size,
void *vaddr,
dma_addr_t dma_handle)
{
atomic_sub(size, &mhi_cntrl->alloc_size);
dma_free_attrs(mhi_cntrl->dev, size, vaddr, dma_handle,
DMA_ATTR_FORCE_NON_COHERENT);
}
static inline void *mhi_alloc_contig_coherent(
struct mhi_controller *mhi_cntrl,
size_t size, dma_addr_t *dma_handle,