Commit d89e2378 authored by Robin Murphy's avatar Robin Murphy Committed by Christoph Hellwig

drivers: flag buses which demand DMA configuration

We do not want the common dma_configure() pathway to apply
indiscriminately to all devices, since there are plenty of buses which
do not have DMA capability, and if their child devices were used for
DMA API calls it would only be indicative of a driver bug. However,
there are a number of buses for which DMA is implicitly expected even
when not described by firmware - those we whitelist with an automatic
opt-in to dma_configure(), assuming that the DMA address space and the
physical address space are equivalent if not otherwise specified.

Commit 72328883 ("of: restrict DMA configuration") introduced a
short-term fix by comparing explicit bus types, but this approach is far
from pretty, doesn't scale well, and fails to cope at all with bus
drivers which may be built as modules, like host1x. Let's refine things
by making that opt-in a property of the bus type, which neatly addresses
those problems and lets the decision of whether firmware description of
DMA capability should be optional or mandatory stay internal to the bus
drivers themselves.
Signed-off-by: default avatarRobin Murphy <>
Acked-by: default avatarRob Herring <>
Acked-by: default avatarGreg Kroah-Hartman <>
Acked-by: default avatarThierry Reding <>
Signed-off-by: default avatarChristoph Hellwig <>
parent 33d930e5
......@@ -195,6 +195,7 @@ struct bus_type amba_bustype = {
.match = amba_match,
.uevent = amba_uevent,
.pm = &amba_pm,
.force_dma = true,
static int __init amba_init(void)
......@@ -1143,6 +1143,7 @@ struct bus_type platform_bus_type = {
.match = platform_match,
.uevent = platform_uevent,
.pm = &platform_dev_pm_ops,
.force_dma = true,
......@@ -320,6 +320,7 @@ struct bus_type host1x_bus_type = {
.name = "host1x",
.match = host1x_device_match,
.pm = &host1x_device_pm_ops,
.force_dma = true,
static void __host1x_device_del(struct host1x_device *device)
......@@ -9,9 +9,7 @@
#include <linux/module.h>
#include <linux/mod_devicetable.h>
#include <linux/slab.h>
#include <linux/pci.h>
#include <linux/platform_device.h>
#include <linux/amba/bus.h>
#include <asm/errno.h>
#include "of_private.h"
......@@ -101,11 +99,7 @@ int of_dma_configure(struct device *dev, struct device_node *np)
* DMA configuration regardless of whether "dma-ranges" is
* correctly specified or not.
if (!dev_is_pci(dev) &&
dev->bus != &amba_bustype &&
dev->bus != &platform_bus_type)
if (!dev->bus->force_dma)
return ret == -ENODEV ? 0 : ret;
dma_addr = offset = 0;
......@@ -1466,6 +1466,7 @@ struct bus_type pci_bus_type = {
.drv_groups = pci_drv_groups,
.num_vf = pci_bus_num_vf,
.force_dma = true,
......@@ -97,6 +97,8 @@ extern void bus_remove_file(struct bus_type *, struct bus_attribute *);
* @p: The private data of the driver core, only the driver core can
* touch this.
* @lock_key: Lock class key for use by the lock validator
* @force_dma: Assume devices on this bus should be set up by dma_configure()
* even if DMA capability is not explicitly described by firmware.
* A bus is a channel between the processor and one or more devices. For the
* purposes of the device model, all devices are connected via a bus, even if
......@@ -135,6 +137,8 @@ struct bus_type {
struct subsys_private *p;
struct lock_class_key lock_key;
bool force_dma;
extern int __must_check bus_register(struct bus_type *bus);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment