mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 01:32:21 +02:00
driver core: Replace dev->dma_coherent with dev_dma_coherent()
In C, bitfields are not necessarily safe to modify from multiple threads without locking. Switch "dma_coherent" over to the "flags" field so modifications are safe. Cc: Christoph Hellwig <hch@lst.de> Reviewed-by: Rafael J. Wysocki (Intel) <rafael@kernel.org> Reviewed-by: Danilo Krummrich <dakr@kernel.org> Acked-by: Vinod Koul <vkoul@kernel.org> Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Acked-by: Marek Szyprowski <m.szyprowski@samsung.com> Signed-off-by: Douglas Anderson <dianders@chromium.org> Link: https://patch.msgid.link/20260406162231.v5.7.If839f6dde98979fce177f70c6c74689a1904ee76@changeid [ Since all DEV_FLAG_DMA_COHERENT accessors are exposed unconditionally, also drop the CONFIG guards around dev_assign_dma_coherent() in device_initialize() to ensure a correct default value. - Danilo ] Signed-off-by: Danilo Krummrich <dakr@kernel.org>
This commit is contained in:
parent
7befbf1281
commit
3e2c1e213a
|
|
@ -98,8 +98,8 @@ void arch_setup_dma_ops(struct device *dev, bool coherent)
|
|||
* DMA buffers.
|
||||
*/
|
||||
if (is_isa_arcv2() && ioc_enable && coherent)
|
||||
dev->dma_coherent = true;
|
||||
dev_set_dma_coherent(dev);
|
||||
|
||||
dev_info(dev, "use %scoherent DMA ops\n",
|
||||
dev->dma_coherent ? "" : "non");
|
||||
dev_dma_coherent(dev) ? "" : "non");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ static int highbank_platform_notifier(struct notifier_block *nb,
|
|||
if (of_property_read_bool(dev->of_node, "dma-coherent")) {
|
||||
val = readl(sregs_base + reg);
|
||||
writel(val | 0xff01, sregs_base + reg);
|
||||
dev->dma_coherent = true;
|
||||
dev_set_dma_coherent(dev);
|
||||
}
|
||||
|
||||
return NOTIFY_OK;
|
||||
|
|
|
|||
|
|
@ -95,7 +95,7 @@ static int mvebu_hwcc_notifier(struct notifier_block *nb,
|
|||
|
||||
if (event != BUS_NOTIFY_ADD_DEVICE)
|
||||
return NOTIFY_DONE;
|
||||
dev->dma_coherent = true;
|
||||
dev_set_dma_coherent(dev);
|
||||
|
||||
return NOTIFY_OK;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,11 +42,11 @@ void arch_setup_dma_ops(struct device *dev, bool coherent)
|
|||
* enough to check if MPU is in use or not since in absence of
|
||||
* MPU system memory map is used.
|
||||
*/
|
||||
dev->dma_coherent = cacheid ? coherent : true;
|
||||
dev_assign_dma_coherent(dev, cacheid ? coherent : true);
|
||||
} else {
|
||||
/*
|
||||
* Assume coherent DMA in case MMU/MPU has not been set up.
|
||||
*/
|
||||
dev->dma_coherent = (get_cr() & CR_M) ? coherent : true;
|
||||
dev_assign_dma_coherent(dev, (get_cr() & CR_M) ? coherent : true);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1076,7 +1076,7 @@ static void *arm_iommu_alloc_attrs(struct device *dev, size_t size,
|
|||
pgprot_t prot = __get_dma_pgprot(attrs, PAGE_KERNEL);
|
||||
struct page **pages;
|
||||
void *addr = NULL;
|
||||
int coherent_flag = dev->dma_coherent ? COHERENT : NORMAL;
|
||||
int coherent_flag = dev_dma_coherent(dev) ? COHERENT : NORMAL;
|
||||
|
||||
*handle = DMA_MAPPING_ERROR;
|
||||
size = PAGE_ALIGN(size);
|
||||
|
|
@ -1124,7 +1124,7 @@ static int arm_iommu_mmap_attrs(struct device *dev, struct vm_area_struct *vma,
|
|||
if (vma->vm_pgoff >= nr_pages)
|
||||
return -ENXIO;
|
||||
|
||||
if (!dev->dma_coherent)
|
||||
if (!dev_dma_coherent(dev))
|
||||
vma->vm_page_prot = __get_dma_pgprot(attrs, vma->vm_page_prot);
|
||||
|
||||
err = vm_map_pages(vma, pages, nr_pages);
|
||||
|
|
@ -1141,7 +1141,7 @@ static int arm_iommu_mmap_attrs(struct device *dev, struct vm_area_struct *vma,
|
|||
static void arm_iommu_free_attrs(struct device *dev, size_t size, void *cpu_addr,
|
||||
dma_addr_t handle, unsigned long attrs)
|
||||
{
|
||||
int coherent_flag = dev->dma_coherent ? COHERENT : NORMAL;
|
||||
int coherent_flag = dev_dma_coherent(dev) ? COHERENT : NORMAL;
|
||||
struct page **pages;
|
||||
size = PAGE_ALIGN(size);
|
||||
|
||||
|
|
@ -1202,7 +1202,7 @@ static int __map_sg_chunk(struct device *dev, struct scatterlist *sg,
|
|||
phys_addr_t phys = page_to_phys(sg_page(s));
|
||||
unsigned int len = PAGE_ALIGN(s->offset + s->length);
|
||||
|
||||
if (!dev->dma_coherent && !(attrs & DMA_ATTR_SKIP_CPU_SYNC))
|
||||
if (!dev_dma_coherent(dev) && !(attrs & DMA_ATTR_SKIP_CPU_SYNC))
|
||||
arch_sync_dma_for_device(sg_phys(s), s->length, dir);
|
||||
|
||||
prot = __dma_info_to_prot(dir, attrs);
|
||||
|
|
@ -1304,7 +1304,7 @@ static void arm_iommu_unmap_sg(struct device *dev,
|
|||
if (sg_dma_len(s))
|
||||
__iommu_remove_mapping(dev, sg_dma_address(s),
|
||||
sg_dma_len(s));
|
||||
if (!dev->dma_coherent && !(attrs & DMA_ATTR_SKIP_CPU_SYNC))
|
||||
if (!dev_dma_coherent(dev) && !(attrs & DMA_ATTR_SKIP_CPU_SYNC))
|
||||
arch_sync_dma_for_cpu(sg_phys(s), s->length, dir);
|
||||
}
|
||||
}
|
||||
|
|
@ -1323,7 +1323,7 @@ static void arm_iommu_sync_sg_for_cpu(struct device *dev,
|
|||
struct scatterlist *s;
|
||||
int i;
|
||||
|
||||
if (dev->dma_coherent)
|
||||
if (dev_dma_coherent(dev))
|
||||
return;
|
||||
|
||||
for_each_sg(sg, s, nents, i)
|
||||
|
|
@ -1345,7 +1345,7 @@ static void arm_iommu_sync_sg_for_device(struct device *dev,
|
|||
struct scatterlist *s;
|
||||
int i;
|
||||
|
||||
if (dev->dma_coherent)
|
||||
if (dev_dma_coherent(dev))
|
||||
return;
|
||||
|
||||
for_each_sg(sg, s, nents, i)
|
||||
|
|
@ -1371,7 +1371,7 @@ static dma_addr_t arm_iommu_map_phys(struct device *dev, phys_addr_t phys,
|
|||
dma_addr_t dma_addr;
|
||||
int ret, prot;
|
||||
|
||||
if (!dev->dma_coherent &&
|
||||
if (!dev_dma_coherent(dev) &&
|
||||
!(attrs & (DMA_ATTR_SKIP_CPU_SYNC | DMA_ATTR_MMIO)))
|
||||
arch_sync_dma_for_device(phys, size, dir);
|
||||
|
||||
|
|
@ -1412,7 +1412,7 @@ static void arm_iommu_unmap_phys(struct device *dev, dma_addr_t handle,
|
|||
if (!iova)
|
||||
return;
|
||||
|
||||
if (!dev->dma_coherent &&
|
||||
if (!dev_dma_coherent(dev) &&
|
||||
!(attrs & (DMA_ATTR_SKIP_CPU_SYNC | DMA_ATTR_MMIO))) {
|
||||
phys_addr_t phys = iommu_iova_to_phys(mapping->domain, iova);
|
||||
|
||||
|
|
@ -1431,7 +1431,7 @@ static void arm_iommu_sync_single_for_cpu(struct device *dev,
|
|||
unsigned int offset = handle & ~PAGE_MASK;
|
||||
phys_addr_t phys;
|
||||
|
||||
if (dev->dma_coherent || !iova)
|
||||
if (dev_dma_coherent(dev) || !iova)
|
||||
return;
|
||||
|
||||
phys = iommu_iova_to_phys(mapping->domain, iova);
|
||||
|
|
@ -1446,7 +1446,7 @@ static void arm_iommu_sync_single_for_device(struct device *dev,
|
|||
unsigned int offset = handle & ~PAGE_MASK;
|
||||
phys_addr_t phys;
|
||||
|
||||
if (dev->dma_coherent || !iova)
|
||||
if (dev_dma_coherent(dev) || !iova)
|
||||
return;
|
||||
|
||||
phys = iommu_iova_to_phys(mapping->domain, iova);
|
||||
|
|
@ -1701,13 +1701,13 @@ static void arm_teardown_iommu_dma_ops(struct device *dev) { }
|
|||
void arch_setup_dma_ops(struct device *dev, bool coherent)
|
||||
{
|
||||
/*
|
||||
* Due to legacy code that sets the ->dma_coherent flag from a bus
|
||||
* notifier we can't just assign coherent to the ->dma_coherent flag
|
||||
* Due to legacy code that sets the dma_coherent flag from a bus
|
||||
* notifier we can't just assign coherent to the dma_coherent flag
|
||||
* here, but instead have to make sure we only set but never clear it
|
||||
* for now.
|
||||
*/
|
||||
if (coherent)
|
||||
dev->dma_coherent = true;
|
||||
dev_set_dma_coherent(dev);
|
||||
|
||||
/*
|
||||
* Don't override the dma_ops if they have already been set. Ideally
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ void arch_setup_dma_ops(struct device *dev, bool coherent)
|
|||
dev_driver_string(dev), dev_name(dev),
|
||||
ARCH_DMA_MINALIGN, cls);
|
||||
|
||||
dev->dma_coherent = coherent;
|
||||
dev_assign_dma_coherent(dev, coherent);
|
||||
|
||||
xen_setup_dma_ops(dev);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -139,6 +139,6 @@ void arch_sync_dma_for_cpu(phys_addr_t paddr, size_t size,
|
|||
#ifdef CONFIG_ARCH_HAS_SETUP_DMA_OPS
|
||||
void arch_setup_dma_ops(struct device *dev, bool coherent)
|
||||
{
|
||||
dev->dma_coherent = coherent;
|
||||
dev_assign_dma_coherent(dev, coherent);
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -140,7 +140,7 @@ void arch_setup_dma_ops(struct device *dev, bool coherent)
|
|||
"%s %s: device non-coherent but no non-coherent operations supported",
|
||||
dev_driver_string(dev), dev_name(dev));
|
||||
|
||||
dev->dma_coherent = coherent;
|
||||
dev_assign_dma_coherent(dev, coherent);
|
||||
}
|
||||
|
||||
void riscv_noncoherent_supported(void)
|
||||
|
|
|
|||
|
|
@ -3170,11 +3170,7 @@ void device_initialize(struct device *dev)
|
|||
INIT_LIST_HEAD(&dev->links.suppliers);
|
||||
INIT_LIST_HEAD(&dev->links.defer_sync);
|
||||
dev->links.status = DL_DEV_NO_DRIVER;
|
||||
#if defined(CONFIG_ARCH_HAS_SYNC_DMA_FOR_DEVICE) || \
|
||||
defined(CONFIG_ARCH_HAS_SYNC_DMA_FOR_CPU) || \
|
||||
defined(CONFIG_ARCH_HAS_SYNC_DMA_FOR_CPU_ALL)
|
||||
dev->dma_coherent = dma_default_coherent;
|
||||
#endif
|
||||
dev_assign_dma_coherent(dev, dma_default_coherent);
|
||||
swiotlb_dev_init(dev);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(device_initialize);
|
||||
|
|
|
|||
|
|
@ -312,7 +312,7 @@ k3_udma_glue_request_tx_chn_common(struct device *dev,
|
|||
|
||||
if (xudma_is_pktdma(tx_chn->common.udmax)) {
|
||||
/* prepare the channel device as coherent */
|
||||
tx_chn->common.chan_dev.dma_coherent = true;
|
||||
dev_set_dma_coherent(&tx_chn->common.chan_dev);
|
||||
dma_coerce_mask_and_coherent(&tx_chn->common.chan_dev,
|
||||
DMA_BIT_MASK(48));
|
||||
}
|
||||
|
|
@ -1003,7 +1003,7 @@ k3_udma_glue_request_rx_chn_priv(struct device *dev, const char *name,
|
|||
|
||||
if (xudma_is_pktdma(rx_chn->common.udmax)) {
|
||||
/* prepare the channel device as coherent */
|
||||
rx_chn->common.chan_dev.dma_coherent = true;
|
||||
dev_set_dma_coherent(&rx_chn->common.chan_dev);
|
||||
dma_coerce_mask_and_coherent(&rx_chn->common.chan_dev,
|
||||
DMA_BIT_MASK(48));
|
||||
}
|
||||
|
|
@ -1104,7 +1104,7 @@ k3_udma_glue_request_remote_rx_chn_common(struct k3_udma_glue_rx_channel *rx_chn
|
|||
|
||||
if (xudma_is_pktdma(rx_chn->common.udmax)) {
|
||||
/* prepare the channel device as coherent */
|
||||
rx_chn->common.chan_dev.dma_coherent = true;
|
||||
dev_set_dma_coherent(&rx_chn->common.chan_dev);
|
||||
dma_coerce_mask_and_coherent(&rx_chn->common.chan_dev,
|
||||
DMA_BIT_MASK(48));
|
||||
rx_chn->single_fdq = false;
|
||||
|
|
|
|||
|
|
@ -428,18 +428,18 @@ static void k3_configure_chan_coherency(struct dma_chan *chan, u32 asel)
|
|||
/* No special handling for the channel */
|
||||
chan->dev->chan_dma_dev = false;
|
||||
|
||||
chan_dev->dma_coherent = false;
|
||||
dev_clear_dma_coherent(chan_dev);
|
||||
chan_dev->dma_parms = NULL;
|
||||
} else if (asel == 14 || asel == 15) {
|
||||
chan->dev->chan_dma_dev = true;
|
||||
|
||||
chan_dev->dma_coherent = true;
|
||||
dev_set_dma_coherent(chan_dev);
|
||||
dma_coerce_mask_and_coherent(chan_dev, DMA_BIT_MASK(48));
|
||||
chan_dev->dma_parms = chan_dev->parent->dma_parms;
|
||||
} else {
|
||||
dev_warn(chan->device->dev, "Invalid ASEL value: %u\n", asel);
|
||||
|
||||
chan_dev->dma_coherent = false;
|
||||
dev_clear_dma_coherent(chan_dev);
|
||||
chan_dev->dma_parms = NULL;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -527,6 +527,8 @@ struct device_physical_location {
|
|||
* @DEV_FLAG_STATE_SYNCED: The hardware state of this device has been synced to
|
||||
* match the software state of this device by calling the
|
||||
* driver/bus sync_state() callback.
|
||||
* @DEV_FLAG_DMA_COHERENT: This particular device is dma coherent, even if the
|
||||
* architecture supports non-coherent devices.
|
||||
* @DEV_FLAG_COUNT: Number of defined struct_device_flags.
|
||||
*/
|
||||
enum struct_device_flags {
|
||||
|
|
@ -536,6 +538,7 @@ enum struct_device_flags {
|
|||
DEV_FLAG_DMA_SKIP_SYNC = 3,
|
||||
DEV_FLAG_DMA_OPS_BYPASS = 4,
|
||||
DEV_FLAG_STATE_SYNCED = 5,
|
||||
DEV_FLAG_DMA_COHERENT = 6,
|
||||
|
||||
DEV_FLAG_COUNT
|
||||
};
|
||||
|
|
@ -619,8 +622,6 @@ enum struct_device_flags {
|
|||
* @offline: Set after successful invocation of bus type's .offline().
|
||||
* @of_node_reused: Set if the device-tree node is shared with an ancestor
|
||||
* device.
|
||||
* @dma_coherent: this particular device is dma coherent, even if the
|
||||
* architecture supports non-coherent devices.
|
||||
* @flags: DEV_FLAG_XXX flags. Use atomic bitfield operations to modify.
|
||||
*
|
||||
* At the lowest level, every device in a Linux system is represented by an
|
||||
|
|
@ -728,11 +729,6 @@ struct device {
|
|||
bool offline_disabled:1;
|
||||
bool offline:1;
|
||||
bool of_node_reused:1;
|
||||
#if defined(CONFIG_ARCH_HAS_SYNC_DMA_FOR_DEVICE) || \
|
||||
defined(CONFIG_ARCH_HAS_SYNC_DMA_FOR_CPU) || \
|
||||
defined(CONFIG_ARCH_HAS_SYNC_DMA_FOR_CPU_ALL)
|
||||
bool dma_coherent:1;
|
||||
#endif
|
||||
|
||||
DECLARE_BITMAP(flags, DEV_FLAG_COUNT);
|
||||
};
|
||||
|
|
@ -765,6 +761,7 @@ __create_dev_flag_accessors(dma_iommu, DEV_FLAG_DMA_IOMMU);
|
|||
__create_dev_flag_accessors(dma_skip_sync, DEV_FLAG_DMA_SKIP_SYNC);
|
||||
__create_dev_flag_accessors(dma_ops_bypass, DEV_FLAG_DMA_OPS_BYPASS);
|
||||
__create_dev_flag_accessors(state_synced, DEV_FLAG_STATE_SYNCED);
|
||||
__create_dev_flag_accessors(dma_coherent, DEV_FLAG_DMA_COHERENT);
|
||||
|
||||
#undef __create_dev_flag_accessors
|
||||
|
||||
|
|
|
|||
|
|
@ -225,7 +225,7 @@ int dma_direct_set_offset(struct device *dev, phys_addr_t cpu_start,
|
|||
extern bool dma_default_coherent;
|
||||
static inline bool dev_is_dma_coherent(struct device *dev)
|
||||
{
|
||||
return dev->dma_coherent;
|
||||
return dev_dma_coherent(dev);
|
||||
}
|
||||
#else
|
||||
#define dma_default_coherent true
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user