mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-07-01 03:11:59 +00:00
ACPI: arm64: Move DMA setup operations out of IORT
Extract generic DMA setup code out of IORT, so it can be reused by VIOT. Keep it in drivers/acpi/arm64 for now, since it could break x86 platforms that haven't run this code so far, if they have invalid tables. Reviewed-by: Eric Auger <eric.auger@redhat.com> Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org> Reviewed-by: Robin Murphy <robin.murphy@arm.com> Link: https://lore.kernel.org/r/20210618152059.1194210-2-jean-philippe@linaro.org Signed-off-by: Joerg Roedel <jroedel@suse.de>
This commit is contained in:
parent
8124c8a6b3
commit
db59e1b6e4
6 changed files with 66 additions and 50 deletions
|
@ -1,3 +1,4 @@
|
||||||
# SPDX-License-Identifier: GPL-2.0-only
|
# SPDX-License-Identifier: GPL-2.0-only
|
||||||
obj-$(CONFIG_ACPI_IORT) += iort.o
|
obj-$(CONFIG_ACPI_IORT) += iort.o
|
||||||
obj-$(CONFIG_ACPI_GTDT) += gtdt.o
|
obj-$(CONFIG_ACPI_GTDT) += gtdt.o
|
||||||
|
obj-y += dma.o
|
||||||
|
|
50
drivers/acpi/arm64/dma.c
Normal file
50
drivers/acpi/arm64/dma.c
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
|
#include <linux/acpi.h>
|
||||||
|
#include <linux/acpi_iort.h>
|
||||||
|
#include <linux/device.h>
|
||||||
|
#include <linux/dma-direct.h>
|
||||||
|
|
||||||
|
void acpi_arch_dma_setup(struct device *dev, u64 *dma_addr, u64 *dma_size)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
u64 end, mask;
|
||||||
|
u64 dmaaddr = 0, size = 0, offset = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If @dev is expected to be DMA-capable then the bus code that created
|
||||||
|
* it should have initialised its dma_mask pointer by this point. For
|
||||||
|
* now, we'll continue the legacy behaviour of coercing it to the
|
||||||
|
* coherent mask if not, but we'll no longer do so quietly.
|
||||||
|
*/
|
||||||
|
if (!dev->dma_mask) {
|
||||||
|
dev_warn(dev, "DMA mask not set\n");
|
||||||
|
dev->dma_mask = &dev->coherent_dma_mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dev->coherent_dma_mask)
|
||||||
|
size = max(dev->coherent_dma_mask, dev->coherent_dma_mask + 1);
|
||||||
|
else
|
||||||
|
size = 1ULL << 32;
|
||||||
|
|
||||||
|
ret = acpi_dma_get_range(dev, &dmaaddr, &offset, &size);
|
||||||
|
if (ret == -ENODEV)
|
||||||
|
ret = iort_dma_get_ranges(dev, &size);
|
||||||
|
if (!ret) {
|
||||||
|
/*
|
||||||
|
* Limit coherent and dma mask based on size retrieved from
|
||||||
|
* firmware.
|
||||||
|
*/
|
||||||
|
end = dmaaddr + size - 1;
|
||||||
|
mask = DMA_BIT_MASK(ilog2(end) + 1);
|
||||||
|
dev->bus_dma_limit = end;
|
||||||
|
dev->coherent_dma_mask = min(dev->coherent_dma_mask, mask);
|
||||||
|
*dev->dma_mask = min(*dev->dma_mask, mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
*dma_addr = dmaaddr;
|
||||||
|
*dma_size = size;
|
||||||
|
|
||||||
|
ret = dma_direct_set_offset(dev, dmaaddr + offset, dmaaddr, size);
|
||||||
|
|
||||||
|
dev_dbg(dev, "dma_offset(%#08llx)%s\n", offset, ret ? " failed!" : "");
|
||||||
|
}
|
|
@ -1144,56 +1144,18 @@ static int rc_dma_get_range(struct device *dev, u64 *size)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* iort_dma_setup() - Set-up device DMA parameters.
|
* iort_dma_get_ranges() - Look up DMA addressing limit for the device
|
||||||
|
* @dev: device to lookup
|
||||||
|
* @size: DMA range size result pointer
|
||||||
*
|
*
|
||||||
* @dev: device to configure
|
* Return: 0 on success, an error otherwise.
|
||||||
* @dma_addr: device DMA address result pointer
|
|
||||||
* @dma_size: DMA range size result pointer
|
|
||||||
*/
|
*/
|
||||||
void iort_dma_setup(struct device *dev, u64 *dma_addr, u64 *dma_size)
|
int iort_dma_get_ranges(struct device *dev, u64 *size)
|
||||||
{
|
{
|
||||||
u64 end, mask, dmaaddr = 0, size = 0, offset = 0;
|
if (dev_is_pci(dev))
|
||||||
int ret;
|
return rc_dma_get_range(dev, size);
|
||||||
|
|
||||||
/*
|
|
||||||
* If @dev is expected to be DMA-capable then the bus code that created
|
|
||||||
* it should have initialised its dma_mask pointer by this point. For
|
|
||||||
* now, we'll continue the legacy behaviour of coercing it to the
|
|
||||||
* coherent mask if not, but we'll no longer do so quietly.
|
|
||||||
*/
|
|
||||||
if (!dev->dma_mask) {
|
|
||||||
dev_warn(dev, "DMA mask not set\n");
|
|
||||||
dev->dma_mask = &dev->coherent_dma_mask;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dev->coherent_dma_mask)
|
|
||||||
size = max(dev->coherent_dma_mask, dev->coherent_dma_mask + 1);
|
|
||||||
else
|
else
|
||||||
size = 1ULL << 32;
|
return nc_dma_get_range(dev, size);
|
||||||
|
|
||||||
ret = acpi_dma_get_range(dev, &dmaaddr, &offset, &size);
|
|
||||||
if (ret == -ENODEV)
|
|
||||||
ret = dev_is_pci(dev) ? rc_dma_get_range(dev, &size)
|
|
||||||
: nc_dma_get_range(dev, &size);
|
|
||||||
|
|
||||||
if (!ret) {
|
|
||||||
/*
|
|
||||||
* Limit coherent and dma mask based on size retrieved from
|
|
||||||
* firmware.
|
|
||||||
*/
|
|
||||||
end = dmaaddr + size - 1;
|
|
||||||
mask = DMA_BIT_MASK(ilog2(end) + 1);
|
|
||||||
dev->bus_dma_limit = end;
|
|
||||||
dev->coherent_dma_mask = min(dev->coherent_dma_mask, mask);
|
|
||||||
*dev->dma_mask = min(*dev->dma_mask, mask);
|
|
||||||
}
|
|
||||||
|
|
||||||
*dma_addr = dmaaddr;
|
|
||||||
*dma_size = size;
|
|
||||||
|
|
||||||
ret = dma_direct_set_offset(dev, dmaaddr + offset, dmaaddr, size);
|
|
||||||
|
|
||||||
dev_dbg(dev, "dma_offset(%#08llx)%s\n", offset, ret ? " failed!" : "");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __init acpi_iort_register_irq(int hwirq, const char *name,
|
static void __init acpi_iort_register_irq(int hwirq, const char *name,
|
||||||
|
|
|
@ -1537,7 +1537,7 @@ int acpi_dma_configure_id(struct device *dev, enum dev_dma_attr attr,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
iort_dma_setup(dev, &dma_addr, &size);
|
acpi_arch_dma_setup(dev, &dma_addr, &size);
|
||||||
|
|
||||||
iommu = iort_iommu_configure_id(dev, input_id);
|
iommu = iort_iommu_configure_id(dev, input_id);
|
||||||
if (PTR_ERR(iommu) == -EPROBE_DEFER)
|
if (PTR_ERR(iommu) == -EPROBE_DEFER)
|
||||||
|
|
|
@ -259,9 +259,12 @@ void acpi_numa_x2apic_affinity_init(struct acpi_srat_x2apic_cpu_affinity *pa);
|
||||||
|
|
||||||
#ifdef CONFIG_ARM64
|
#ifdef CONFIG_ARM64
|
||||||
void acpi_numa_gicc_affinity_init(struct acpi_srat_gicc_affinity *pa);
|
void acpi_numa_gicc_affinity_init(struct acpi_srat_gicc_affinity *pa);
|
||||||
|
void acpi_arch_dma_setup(struct device *dev, u64 *dma_addr, u64 *dma_size);
|
||||||
#else
|
#else
|
||||||
static inline void
|
static inline void
|
||||||
acpi_numa_gicc_affinity_init(struct acpi_srat_gicc_affinity *pa) { }
|
acpi_numa_gicc_affinity_init(struct acpi_srat_gicc_affinity *pa) { }
|
||||||
|
static inline void
|
||||||
|
acpi_arch_dma_setup(struct device *dev, u64 *dma_addr, u64 *dma_size) { }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int acpi_numa_memory_affinity_init (struct acpi_srat_mem_affinity *ma);
|
int acpi_numa_memory_affinity_init (struct acpi_srat_mem_affinity *ma);
|
||||||
|
|
|
@ -34,7 +34,7 @@ struct irq_domain *iort_get_device_domain(struct device *dev, u32 id,
|
||||||
void acpi_configure_pmsi_domain(struct device *dev);
|
void acpi_configure_pmsi_domain(struct device *dev);
|
||||||
int iort_pmsi_get_dev_id(struct device *dev, u32 *dev_id);
|
int iort_pmsi_get_dev_id(struct device *dev, u32 *dev_id);
|
||||||
/* IOMMU interface */
|
/* IOMMU interface */
|
||||||
void iort_dma_setup(struct device *dev, u64 *dma_addr, u64 *size);
|
int iort_dma_get_ranges(struct device *dev, u64 *size);
|
||||||
const struct iommu_ops *iort_iommu_configure_id(struct device *dev,
|
const struct iommu_ops *iort_iommu_configure_id(struct device *dev,
|
||||||
const u32 *id_in);
|
const u32 *id_in);
|
||||||
int iort_iommu_msi_get_resv_regions(struct device *dev, struct list_head *head);
|
int iort_iommu_msi_get_resv_regions(struct device *dev, struct list_head *head);
|
||||||
|
@ -48,8 +48,8 @@ static inline struct irq_domain *iort_get_device_domain(
|
||||||
{ return NULL; }
|
{ return NULL; }
|
||||||
static inline void acpi_configure_pmsi_domain(struct device *dev) { }
|
static inline void acpi_configure_pmsi_domain(struct device *dev) { }
|
||||||
/* IOMMU interface */
|
/* IOMMU interface */
|
||||||
static inline void iort_dma_setup(struct device *dev, u64 *dma_addr,
|
static inline int iort_dma_get_ranges(struct device *dev, u64 *size)
|
||||||
u64 *size) { }
|
{ return -ENODEV; }
|
||||||
static inline const struct iommu_ops *iort_iommu_configure_id(
|
static inline const struct iommu_ops *iort_iommu_configure_id(
|
||||||
struct device *dev, const u32 *id_in)
|
struct device *dev, const u32 *id_in)
|
||||||
{ return NULL; }
|
{ return NULL; }
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue