linux/drivers/acpi/arm64/dma.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2#include <linux/acpi.h>
   3#include <linux/acpi_iort.h>
   4#include <linux/device.h>
   5#include <linux/dma-direct.h>
   6
   7void acpi_arch_dma_setup(struct device *dev, u64 *dma_addr, u64 *dma_size)
   8{
   9        int ret;
  10        u64 end, mask;
  11        u64 dmaaddr = 0, size = 0, offset = 0;
  12
  13        /*
  14         * If @dev is expected to be DMA-capable then the bus code that created
  15         * it should have initialised its dma_mask pointer by this point. For
  16         * now, we'll continue the legacy behaviour of coercing it to the
  17         * coherent mask if not, but we'll no longer do so quietly.
  18         */
  19        if (!dev->dma_mask) {
  20                dev_warn(dev, "DMA mask not set\n");
  21                dev->dma_mask = &dev->coherent_dma_mask;
  22        }
  23
  24        if (dev->coherent_dma_mask)
  25                size = max(dev->coherent_dma_mask, dev->coherent_dma_mask + 1);
  26        else
  27                size = 1ULL << 32;
  28
  29        ret = acpi_dma_get_range(dev, &dmaaddr, &offset, &size);
  30        if (ret == -ENODEV)
  31                ret = iort_dma_get_ranges(dev, &size);
  32        if (!ret) {
  33                /*
  34                 * Limit coherent and dma mask based on size retrieved from
  35                 * firmware.
  36                 */
  37                end = dmaaddr + size - 1;
  38                mask = DMA_BIT_MASK(ilog2(end) + 1);
  39                dev->bus_dma_limit = end;
  40                dev->coherent_dma_mask = min(dev->coherent_dma_mask, mask);
  41                *dev->dma_mask = min(*dev->dma_mask, mask);
  42        }
  43
  44        *dma_addr = dmaaddr;
  45        *dma_size = size;
  46
  47        ret = dma_direct_set_offset(dev, dmaaddr + offset, dmaaddr, size);
  48
  49        dev_dbg(dev, "dma_offset(%#08llx)%s\n", offset, ret ? " failed!" : "");
  50}
  51