123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137 |
- /*
- * Intel MIC Platform Software Stack (MPSS)
- *
- * Copyright(c) 2014 Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License, version 2, as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * Intel SCIF driver.
- *
- */
- #ifndef SCIF_MAP_H
- #define SCIF_MAP_H
- #include "../bus/scif_bus.h"
- static __always_inline void *
- scif_alloc_coherent(dma_addr_t *dma_handle,
- struct scif_dev *scifdev, size_t size,
- gfp_t gfp)
- {
- void *va;
- if (scifdev_self(scifdev)) {
- va = kmalloc(size, gfp);
- if (va)
- *dma_handle = virt_to_phys(va);
- } else {
- va = dma_alloc_coherent(&scifdev->sdev->dev,
- size, dma_handle, gfp);
- if (va && scifdev_is_p2p(scifdev))
- *dma_handle = *dma_handle + scifdev->base_addr;
- }
- return va;
- }
- static __always_inline void
- scif_free_coherent(void *va, dma_addr_t local,
- struct scif_dev *scifdev, size_t size)
- {
- if (scifdev_self(scifdev)) {
- kfree(va);
- } else {
- if (scifdev_is_p2p(scifdev) && local > scifdev->base_addr)
- local = local - scifdev->base_addr;
- dma_free_coherent(&scifdev->sdev->dev,
- size, va, local);
- }
- }
- static __always_inline int
- scif_map_single(dma_addr_t *dma_handle,
- void *local, struct scif_dev *scifdev, size_t size)
- {
- int err = 0;
- if (scifdev_self(scifdev)) {
- *dma_handle = virt_to_phys((local));
- } else {
- *dma_handle = dma_map_single(&scifdev->sdev->dev,
- local, size, DMA_BIDIRECTIONAL);
- if (dma_mapping_error(&scifdev->sdev->dev, *dma_handle))
- err = -ENOMEM;
- else if (scifdev_is_p2p(scifdev))
- *dma_handle = *dma_handle + scifdev->base_addr;
- }
- if (err)
- *dma_handle = 0;
- return err;
- }
- static __always_inline void
- scif_unmap_single(dma_addr_t local, struct scif_dev *scifdev,
- size_t size)
- {
- if (!scifdev_self(scifdev)) {
- if (scifdev_is_p2p(scifdev))
- local = local - scifdev->base_addr;
- dma_unmap_single(&scifdev->sdev->dev, local,
- size, DMA_BIDIRECTIONAL);
- }
- }
- static __always_inline void *
- scif_ioremap(dma_addr_t phys, size_t size, struct scif_dev *scifdev)
- {
- void *out_virt;
- struct scif_hw_dev *sdev = scifdev->sdev;
- if (scifdev_self(scifdev))
- out_virt = phys_to_virt(phys);
- else
- out_virt = (void __force *)
- sdev->hw_ops->ioremap(sdev, phys, size);
- return out_virt;
- }
- static __always_inline void
- scif_iounmap(void *virt, size_t len, struct scif_dev *scifdev)
- {
- if (!scifdev_self(scifdev)) {
- struct scif_hw_dev *sdev = scifdev->sdev;
- sdev->hw_ops->iounmap(sdev, (void __force __iomem *)virt);
- }
- }
- static __always_inline int
- scif_map_page(dma_addr_t *dma_handle, struct page *page,
- struct scif_dev *scifdev)
- {
- int err = 0;
- if (scifdev_self(scifdev)) {
- *dma_handle = page_to_phys(page);
- } else {
- struct scif_hw_dev *sdev = scifdev->sdev;
- *dma_handle = dma_map_page(&sdev->dev,
- page, 0x0, PAGE_SIZE,
- DMA_BIDIRECTIONAL);
- if (dma_mapping_error(&sdev->dev, *dma_handle))
- err = -ENOMEM;
- else if (scifdev_is_p2p(scifdev))
- *dma_handle = *dma_handle + scifdev->base_addr;
- }
- if (err)
- *dma_handle = 0;
- return err;
- }
- #endif /* SCIF_MAP_H */
|