mirror of
https://github.com/torvalds/linux.git
synced 2024-12-23 19:31:53 +00:00
a93a121a96
arch_setup_dma_ops() is used in device probe code paths to create an
IOMMU mapping and attach it to the device. The function assumes that the
device is attached to a device-specific IOMMU instance (or at least a
device-specific TLB in a shared IOMMU instance) and thus creates a
separate mapping for every device.
On several systems (Renesas R-Car Gen2 being one of them), that
assumption is not true, and IOMMU mappings must be shared between
multiple devices. In those cases the IOMMU driver knows better than the
generic ARM dma-mapping layer and attaches mapping to devices manually
with arm_iommu_attach_device(), which sets the DMA ops for the device.
The arch_setup_dma_ops() function takes this into account and bails out
immediately if the device already has DMA ops assigned. However, the
corresponding arch_teardown_dma_ops() function, called from driver
unbind code paths (including probe deferral), will tear the mapping down
regardless of who created it. When the device is reprobed
arch_setup_dma_ops() will be called again but won't perform any
operation as the DMA ops will still be set.
We need to reset the DMA ops in arch_teardown_dma_ops() to fix this.
However, we can't do so unconditionally, as then a new mapping would be
created by arch_setup_dma_ops() when the device is reprobed, regardless
of whether the device needs to share a mapping or not. We must thus keep
track of whether arch_setup_dma_ops() created the mapping, and only in
that case tear it down in arch_teardown_dma_ops().
Keep track of that information in the dev_archdata structure. As the
structure is embedded in all instances of struct device let's not grow
it, but turn the existing dma_coherent bool field into a bitfield that
can be used for other purposes.
Fixes: 09515ef5dd
("of/acpi: Configure dma operations at probe time for platform/amba/pci bus devices")
Reviewed-by: Robin Murphy <robin.murphy@arm.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Signed-off-by: Joerg Roedel <jroedel@suse.de>
41 lines
771 B
C
41 lines
771 B
C
/*
|
|
* Arch specific extensions to struct device
|
|
*
|
|
* This file is released under the GPLv2
|
|
*/
|
|
#ifndef ASMARM_DEVICE_H
|
|
#define ASMARM_DEVICE_H
|
|
|
|
struct dev_archdata {
|
|
#ifdef CONFIG_DMABOUNCE
|
|
struct dmabounce_device_info *dmabounce;
|
|
#endif
|
|
#ifdef CONFIG_IOMMU_API
|
|
void *iommu; /* private IOMMU data */
|
|
#endif
|
|
#ifdef CONFIG_ARM_DMA_USE_IOMMU
|
|
struct dma_iommu_mapping *mapping;
|
|
#endif
|
|
#ifdef CONFIG_XEN
|
|
const struct dma_map_ops *dev_dma_ops;
|
|
#endif
|
|
unsigned int dma_coherent:1;
|
|
unsigned int dma_ops_setup:1;
|
|
};
|
|
|
|
struct omap_device;
|
|
|
|
struct pdev_archdata {
|
|
#ifdef CONFIG_ARCH_OMAP
|
|
struct omap_device *od;
|
|
#endif
|
|
};
|
|
|
|
#ifdef CONFIG_ARM_DMA_USE_IOMMU
|
|
#define to_dma_iommu_mapping(dev) ((dev)->archdata.mapping)
|
|
#else
|
|
#define to_dma_iommu_mapping(dev) NULL
|
|
#endif
|
|
|
|
#endif
|