Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 #include <linux/acpi.h>
0003 #include <linux/acpi_iort.h>
0004 #include <linux/device.h>
0005 #include <linux/dma-direct.h>
0006 
0007 void acpi_arch_dma_setup(struct device *dev, u64 *dma_addr, u64 *dma_size)
0008 {
0009     int ret;
0010     u64 end, mask;
0011     u64 dmaaddr = 0, size = 0, offset = 0;
0012 
0013     /*
0014      * If @dev is expected to be DMA-capable then the bus code that created
0015      * it should have initialised its dma_mask pointer by this point. For
0016      * now, we'll continue the legacy behaviour of coercing it to the
0017      * coherent mask if not, but we'll no longer do so quietly.
0018      */
0019     if (!dev->dma_mask) {
0020         dev_warn(dev, "DMA mask not set\n");
0021         dev->dma_mask = &dev->coherent_dma_mask;
0022     }
0023 
0024     if (dev->coherent_dma_mask)
0025         size = max(dev->coherent_dma_mask, dev->coherent_dma_mask + 1);
0026     else
0027         size = 1ULL << 32;
0028 
0029     ret = acpi_dma_get_range(dev, &dmaaddr, &offset, &size);
0030     if (ret == -ENODEV)
0031         ret = iort_dma_get_ranges(dev, &size);
0032     if (!ret) {
0033         /*
0034          * Limit coherent and dma mask based on size retrieved from
0035          * firmware.
0036          */
0037         end = dmaaddr + size - 1;
0038         mask = DMA_BIT_MASK(ilog2(end) + 1);
0039         dev->bus_dma_limit = end;
0040         dev->coherent_dma_mask = min(dev->coherent_dma_mask, mask);
0041         *dev->dma_mask = min(*dev->dma_mask, mask);
0042     }
0043 
0044     *dma_addr = dmaaddr;
0045     *dma_size = size;
0046 
0047     ret = dma_direct_set_offset(dev, dmaaddr + offset, dmaaddr, size);
0048 
0049     dev_dbg(dev, "dma_offset(%#08llx)%s\n", offset, ret ? " failed!" : "");
0050 }