Loading drivers/bus/mhi/core/mhi_init.c +35 −3 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -307,6 +322,10 @@ void mhi_deinit_dev_ctxt(struct mhi_controller *mhi_cntrl) continue; ring = &mhi_event->ring; 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; Loading Loading @@ -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; Loading Loading @@ -524,6 +548,10 @@ int mhi_init_dev_ctxt(struct mhi_controller *mhi_cntrl) if (mhi_event->offload_ev) continue; 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); } Loading Loading @@ -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) Loading drivers/bus/mhi/core/mhi_internal.h +24 −0 Original line number Diff line number Diff line Loading @@ -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 { Loading Loading @@ -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, Loading Loading
drivers/bus/mhi/core/mhi_init.c +35 −3 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -307,6 +322,10 @@ void mhi_deinit_dev_ctxt(struct mhi_controller *mhi_cntrl) continue; ring = &mhi_event->ring; 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; Loading Loading @@ -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; Loading Loading @@ -524,6 +548,10 @@ int mhi_init_dev_ctxt(struct mhi_controller *mhi_cntrl) if (mhi_event->offload_ev) continue; 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); } Loading Loading @@ -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) Loading
drivers/bus/mhi/core/mhi_internal.h +24 −0 Original line number Diff line number Diff line Loading @@ -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 { Loading Loading @@ -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, Loading