linux/drivers/misc/mic/scif/scif_map.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0-only */
   2/*
   3 * Intel MIC Platform Software Stack (MPSS)
   4 *
   5 * Copyright(c) 2014 Intel Corporation.
   6 *
   7 * Intel SCIF driver.
   8 */
   9#ifndef SCIF_MAP_H
  10#define SCIF_MAP_H
  11
  12#include "../bus/scif_bus.h"
  13
  14static __always_inline void *
  15scif_alloc_coherent(dma_addr_t *dma_handle,
  16                    struct scif_dev *scifdev, size_t size,
  17                    gfp_t gfp)
  18{
  19        void *va;
  20
  21        if (scifdev_self(scifdev)) {
  22                va = kmalloc(size, gfp);
  23                if (va)
  24                        *dma_handle = virt_to_phys(va);
  25        } else {
  26                va = dma_alloc_coherent(&scifdev->sdev->dev,
  27                                        size, dma_handle, gfp);
  28                if (va && scifdev_is_p2p(scifdev))
  29                        *dma_handle = *dma_handle + scifdev->base_addr;
  30        }
  31        return va;
  32}
  33
  34static __always_inline void
  35scif_free_coherent(void *va, dma_addr_t local,
  36                   struct scif_dev *scifdev, size_t size)
  37{
  38        if (scifdev_self(scifdev)) {
  39                kfree(va);
  40        } else {
  41                if (scifdev_is_p2p(scifdev) && local > scifdev->base_addr)
  42                        local = local - scifdev->base_addr;
  43                dma_free_coherent(&scifdev->sdev->dev,
  44                                  size, va, local);
  45        }
  46}
  47
  48static __always_inline int
  49scif_map_single(dma_addr_t *dma_handle,
  50                void *local, struct scif_dev *scifdev, size_t size)
  51{
  52        int err = 0;
  53
  54        if (scifdev_self(scifdev)) {
  55                *dma_handle = virt_to_phys((local));
  56        } else {
  57                *dma_handle = dma_map_single(&scifdev->sdev->dev,
  58                                             local, size, DMA_BIDIRECTIONAL);
  59                if (dma_mapping_error(&scifdev->sdev->dev, *dma_handle))
  60                        err = -ENOMEM;
  61                else if (scifdev_is_p2p(scifdev))
  62                        *dma_handle = *dma_handle + scifdev->base_addr;
  63        }
  64        if (err)
  65                *dma_handle = 0;
  66        return err;
  67}
  68
  69static __always_inline void
  70scif_unmap_single(dma_addr_t local, struct scif_dev *scifdev,
  71                  size_t size)
  72{
  73        if (!scifdev_self(scifdev)) {
  74                if (scifdev_is_p2p(scifdev))
  75                        local = local - scifdev->base_addr;
  76                dma_unmap_single(&scifdev->sdev->dev, local,
  77                                 size, DMA_BIDIRECTIONAL);
  78        }
  79}
  80
  81static __always_inline void *
  82scif_ioremap(dma_addr_t phys, size_t size, struct scif_dev *scifdev)
  83{
  84        void *out_virt;
  85        struct scif_hw_dev *sdev = scifdev->sdev;
  86
  87        if (scifdev_self(scifdev))
  88                out_virt = phys_to_virt(phys);
  89        else
  90                out_virt = (void __force *)
  91                           sdev->hw_ops->remap(sdev, phys, size);
  92        return out_virt;
  93}
  94
  95static __always_inline void
  96scif_iounmap(void *virt, size_t len, struct scif_dev *scifdev)
  97{
  98        if (!scifdev_self(scifdev)) {
  99                struct scif_hw_dev *sdev = scifdev->sdev;
 100
 101                sdev->hw_ops->unmap(sdev, (void __force __iomem *)virt);
 102        }
 103}
 104
 105static __always_inline int
 106scif_map_page(dma_addr_t *dma_handle, struct page *page,
 107              struct scif_dev *scifdev)
 108{
 109        int err = 0;
 110
 111        if (scifdev_self(scifdev)) {
 112                *dma_handle = page_to_phys(page);
 113        } else {
 114                struct scif_hw_dev *sdev = scifdev->sdev;
 115                *dma_handle = dma_map_page(&sdev->dev,
 116                                           page, 0x0, PAGE_SIZE,
 117                                           DMA_BIDIRECTIONAL);
 118                if (dma_mapping_error(&sdev->dev, *dma_handle))
 119                        err = -ENOMEM;
 120                else if (scifdev_is_p2p(scifdev))
 121                        *dma_handle = *dma_handle + scifdev->base_addr;
 122        }
 123        if (err)
 124                *dma_handle = 0;
 125        return err;
 126}
 127#endif  /* SCIF_MAP_H */
 128