gpu: host1x: Call of_dma_configure after setting bus
Subsystems (7)
Mikko Perttunen
maintainerPATCH 1/2 gpu: host1x: Call of_dma_configure after setting bus
of_dma_configure now checks the device's bus before configuring it, so we need to set the device's bus before calling.
--- drivers/gpu/host1x/bus.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/gpu/host1x/bus.c +2 -1
@@ -403,12 +403,13 @@ static int host1x_device_add(struct host1x *host1x, device->dev.coherent_dma_mask = host1x->dev->coherent_dma_mask; device->dev.dma_mask = &device->dev.coherent_dma_mask;dev_set_name (&device->dev,"%s" , driver->driver.name); -of_dma_configure (&device->dev, host1x->dev->of_node); device->dev.release = host1x_device_release; device->dev.of_node = host1x->dev->of_node; device->dev.bus = &host1x_bus_type; device->dev.parent = host1x->dev; +of_dma_configure (&device->dev, host1x->dev->of_node); + err =host1x_device_parse_dt (device, driver);if (err <0 ) {kfree (device);
Signature · 1 line
2.14.1
Mikko Perttunen
maintainerPATCH 2/2 of: configure DMA for host1x devices
Devices in the host1x bus rely on the old behavior of of_dma_configure to set up DMA ops. Add a check for them into of_dma_configure.
We must do the check using a string comparison instead of using pointers since the host1x bus can be compiled into a module.
--- drivers/of/device.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/of/device.c +3 -0
@@ -104,6 +104,9 @@ int of_dma_configure(struct device *dev, struct device_node *np) if (!dev_is_pci(dev) &&#ifdef CONFIG_ARM_AMBA dev->bus != &amba_bustype && +#endif +#if IS_ENABLED (CONFIG_TEGRA_HOST1X ) + !(dev->bus && !strcmp ("host1x" , dev->bus->name)) && #endif dev->bus != &platform_bus_type) return ret == -ENODEV ? 0 : ret;
Signature · 1 line
2.14.1
PATCH 2/2 of: configure DMA for host1x devices
Quoted 17 lines · Mikko Perttunen
Devices in the host1x bus rely on the old behavior of
of_dma_configureto set up DMA ops. Add a check for them intoof_dma_configure.We must do the check using a string comparison instead of using pointers since the host1x bus can be compiled into a module.
Fixes 723288836628 ("of: restrict DMA configuration")Signed-off-by Mikko Perttunen <[email protected]>--- drivers/of/device.c | 3 +++ 1 file changed, 3 insertions(+)drivers/of/device.c +0
-0
drivers/of/device.c int of_dma_configure(struct device *dev, struct device_node *np) · line 112
Quoted 9 lines
drivers/of/device.c +3
-0@@ -104,6 +104,9 @@ int of_dma_configure(struct device *dev, struct device_node *np) if (!dev_is_pci(dev) &&#ifdef CONFIG_ARM_AMBA dev->bus != &amba_bustype && +#endif +#if IS_ENABLED (CONFIG_TEGRA_HOST1X ) + !(dev->bus && !strcmp ("host1x" , dev->bus->name)) && #endif dev->bus != &platform_bus_type) return ret == -ENODEV ? 0 : ret;
Maybe a slightly better solution would be to add a dev_is_host1x() function that returns dev->bus == &host1x_bus_type if TEGRA_HOST1X is enabled and returns false otherwise. That way we can have a "proper" check for the bus type and avoid the #if in this file.
It's slightly more complicated because of the dependencies between the DT and Tegra DRM trees, but I'm sure we can get Rob to either give his Acked-by on the drivers/of/device.c change or carry the Tegra DRM patch in the DT tree.
Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20170925/9c58ca02/attachment.sig>
PATCH 2/2 of: configure DMA for host1x devices
Quoted 33 lines · Thierry Reding
Quoted 17 lines · Mikko Perttunen
Devices in the host1x bus rely on the old behavior of
of_dma_configureto set up DMA ops. Add a check for them intoof_dma_configure.We must do the check using a string comparison instead of using pointers since the host1x bus can be compiled into a module.
Fixes 723288836628 ("of: restrict DMA configuration")Signed-off-by Mikko Perttunen <[email protected]>--- drivers/of/device.c | 3 +++ 1 file changed, 3 insertions(+)drivers/of/device.c +0
-0drivers/of/device.c int of_dma_configure(struct device *dev, struct device_node *np) · line 112
Quoted 9 lines
drivers/of/device.c +3
-0@@ -104,6 +104,9 @@ int of_dma_configure(struct device *dev, struct device_node *np) if (!dev_is_pci(dev) &&#ifdef CONFIG_ARM_AMBA dev->bus != &amba_bustype && +#endif +#if IS_ENABLED (CONFIG_TEGRA_HOST1X ) + !(dev->bus && !strcmp ("host1x" , dev->bus->name)) && #endif dev->bus != &platform_bus_type) return ret == -ENODEV ? 0 : ret;Maybe a slightly better solution would be to add a
dev_is_host1x()function that returnsdev->bus==&host1x_bus_typeifTEGRA_HOST1Xis enabled and returns false otherwise. That way we can have a "proper" check for the bus type and avoid the #if in this file.
Quoted 4 lines
It's slightly more complicated because of the dependencies between the DT and Tegra DRM trees, but I'm sure we can get Rob to either give his Acked-by on the
drivers/of/device.cchange or carry the Tegra DRM patch in the DT tree.
Alternatively (and modulo Greg's opinion, obviously) it would arguably be neatest to handle this at a slightly lower level as below - I only really considered this idea after writing the existing fix, but now that I have actually written it up I do rather like it.
Robin.
----->8-----
From: Robin Murphy <[email protected]>
Date: Mon, 25 Sep 2017 12:45:58 +0100
Subject: [PATCH] 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, so we currently whitelist those to automatically opt in to dma_configure(), assuming a 1:1 mapping between the DMA address space and the physical address space.
Commit 723288836628 ("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. 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.
--- drivers/amba/bus.c | 1 + drivers/base/platform.c | 1 + drivers/gpu/host1x/bus.c | 1 + drivers/of/device.c | 8 +------- drivers/pci/pci-driver.c | 1 + include/linux/device.h | 4 ++++ 6 files changed, 9 insertions(+), 7 deletions(-)
drivers/amba/bus.c +1 -0
@@ -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 )
drivers/base/platform.c +1 -0
@@ -1142,6 +1142,7 @@ struct bus_type platform_bus_type = { .match = platform_match, .uevent = platform_uevent, .pm = &platform_dev_pm_ops, + .force_dma = true, };EXPORT_SYMBOL_GPL (platform_bus_type);
drivers/gpu/host1x/bus.c +1 -0
@@ -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)
drivers/of/device.c +1 -7
@@ -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) && -#ifdef CONFIG_ARM_AMBA - dev->bus != &amba_bustype && -#endif - dev->bus != &platform_bus_type) +if (!dev->bus->force_dma)return ret == -ENODEV ?0 : ret; dma_addr = offset =0 ;
drivers/pci/pci-driver.c +1 -0
@@ -1466,6 +1466,7 @@ struct bus_type pci_bus_type = { .drv_groups = pci_drv_groups, .pm = PCI_PM_OPS_PTR, .num_vf = pci_bus_num_vf, + .force_dma = true, };EXPORT_SYMBOL (pci_bus_type);
include/linux/device.h +4 -0
@@ -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);
Signature · 1 line
2.13.4.dirty
PATCH 2/2 of: configure DMA for host1x devices
Quoted 4 lines · Robin Murphy
Alternatively (and modulo Greg's opinion, obviously) it would arguably be neatest to handle this at a slightly lower level as below - I only really considered this idea after writing the existing fix, but now that I have actually written it up I do rather like it.
I also like this much better than hardcoding specific busses. The only real downside is that it makes it too easy to add exceptions :)
PATCH 2/2 of: configure DMA for host1x devices
In reply to Robin MurphyQuoted 39 lines · Robin Murphy
Quoted 33 lines · Thierry Reding
Quoted 17 lines · Mikko Perttunen
Devices in the host1x bus rely on the old behavior of
of_dma_configureto set up DMA ops. Add a check for them intoof_dma_configure.We must do the check using a string comparison instead of using pointers since the host1x bus can be compiled into a module.
Fixes 723288836628 ("of: restrict DMA configuration")Signed-off-by Mikko Perttunen <[email protected]>--- drivers/of/device.c | 3 +++ 1 file changed, 3 insertions(+)drivers/of/device.c +0
-0drivers/of/device.c int of_dma_configure(struct device *dev, struct device_node *np) · line 112
Quoted 9 lines
drivers/of/device.c +3
-0@@ -104,6 +104,9 @@ int of_dma_configure(struct device *dev, struct device_node *np) if (!dev_is_pci(dev) &&#ifdef CONFIG_ARM_AMBA dev->bus != &amba_bustype && +#endif +#if IS_ENABLED (CONFIG_TEGRA_HOST1X ) + !(dev->bus && !strcmp ("host1x" , dev->bus->name)) && #endif dev->bus != &platform_bus_type) return ret == -ENODEV ? 0 : ret;Maybe a slightly better solution would be to add a
dev_is_host1x()function that returnsdev->bus==&host1x_bus_typeifTEGRA_HOST1Xis enabled and returns false otherwise. That way we can have a "proper" check for the bus type and avoid the #if in this file.Quoted 4 lines
It's slightly more complicated because of the dependencies between the DT and Tegra DRM trees, but I'm sure we can get Rob to either give his Acked-by on the
drivers/of/device.cchange or carry the Tegra DRM patch in the DT tree.
Quoted 6 lines
Alternatively (and modulo Greg's opinion, obviously) it would arguably be neatest to handle this at a slightly lower level as below - I only really considered this idea after writing the existing fix, but now that I have actually written it up I do rather like it.
Robin.
Yep, this solution seems the cleanest to me as well.
Mikko
Quoted 132 lines
----->8-----
From: Robin Murphy <[email protected]>
Date: Mon, 25 Sep 2017 12:45:58 +0100
Subject: [PATCH] drivers: Flag buses which demand DMA configurationWe 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, so we currently whitelist those to automatically opt in todma_configure(), assuming a 1:1 mapping between the DMA address space and the physical address space.Commit 723288836628 ("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. 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 Robin Murphy <[email protected]>--- drivers/amba/bus.c | 1 + drivers/base/platform.c | 1 + drivers/gpu/host1x/bus.c | 1 + drivers/of/device.c | 8 +------- drivers/pci/pci-driver.c | 1 + include/linux/device.h | 4 ++++ 6 files changed, 9 insertions(+), 7 deletions(-)drivers/amba/bus.c +1
-0@@ -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 )drivers/base/platform.c +1
-0@@ -1142,6 +1142,7 @@ struct bus_type platform_bus_type = { .match = platform_match, .uevent = platform_uevent, .pm = &platform_dev_pm_ops, + .force_dma = true, };EXPORT_SYMBOL_GPL (platform_bus_type);drivers/gpu/host1x/bus.c +1
-0@@ -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)drivers/of/device.c +1
-7@@ -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) && -#ifdef CONFIG_ARM_AMBA - dev->bus != &amba_bustype && -#endif - dev->bus != &platform_bus_type) +if (!dev->bus->force_dma)return ret == -ENODEV ?0 : ret; dma_addr = offset =0 ;drivers/pci/pci-driver.c +1
-0@@ -1466,6 +1466,7 @@ struct bus_type pci_bus_type = { .drv_groups = pci_drv_groups, .pm = PCI_PM_OPS_PTR, .num_vf = pci_bus_num_vf, + .force_dma = true, };EXPORT_SYMBOL (pci_bus_type);include/linux/device.h +4
-0@@ -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);
PATCH 2/2 of: configure DMA for host1x devices
In reply to Robin MurphyQuoted 168 lines · Robin Murphy
Quoted 33 lines · Thierry Reding
Quoted 17 lines · Mikko Perttunen
Devices in the host1x bus rely on the old behavior of
of_dma_configureto set up DMA ops. Add a check for them intoof_dma_configure.We must do the check using a string comparison instead of using pointers since the host1x bus can be compiled into a module.
Fixes 723288836628 ("of: restrict DMA configuration")Signed-off-by Mikko Perttunen <[email protected]>--- drivers/of/device.c | 3 +++ 1 file changed, 3 insertions(+)drivers/of/device.c +0
-0drivers/of/device.c int of_dma_configure(struct device *dev, struct device_node *np) · line 112
Quoted 9 lines
drivers/of/device.c +3
-0@@ -104,6 +104,9 @@ int of_dma_configure(struct device *dev, struct device_node *np) if (!dev_is_pci(dev) &&#ifdef CONFIG_ARM_AMBA dev->bus != &amba_bustype && +#endif +#if IS_ENABLED (CONFIG_TEGRA_HOST1X ) + !(dev->bus && !strcmp ("host1x" , dev->bus->name)) && #endif dev->bus != &platform_bus_type) return ret == -ENODEV ? 0 : ret;Maybe a slightly better solution would be to add a
dev_is_host1x()function that returnsdev->bus==&host1x_bus_typeifTEGRA_HOST1Xis enabled and returns false otherwise. That way we can have a "proper" check for the bus type and avoid the #if in this file.Quoted 4 lines
It's slightly more complicated because of the dependencies between the DT and Tegra DRM trees, but I'm sure we can get Rob to either give his Acked-by on the
drivers/of/device.cchange or carry the Tegra DRM patch in the DT tree.Alternatively (and modulo Greg's opinion, obviously) it would arguably be neatest to handle this at a slightly lower level as below - I only really considered this idea after writing the existing fix, but now that I have actually written it up I do rather like it.
Robin.
----->8-----
From: Robin Murphy <[email protected]>
Date: Mon, 25 Sep 2017 12:45:58 +0100
Subject: [PATCH] drivers: Flag buses which demand DMA configurationWe 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, so we currently whitelist those to automatically opt in todma_configure(), assuming a 1:1 mapping between the DMA address space and the physical address space.Commit 723288836628 ("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. 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 Robin Murphy <[email protected]>--- drivers/amba/bus.c | 1 + drivers/base/platform.c | 1 + drivers/gpu/host1x/bus.c | 1 + drivers/of/device.c | 8 +------- drivers/pci/pci-driver.c | 1 + include/linux/device.h | 4 ++++ 6 files changed, 9 insertions(+), 7 deletions(-)drivers/amba/bus.c +1
-0@@ -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 )drivers/base/platform.c +1
-0@@ -1142,6 +1142,7 @@ struct bus_type platform_bus_type = { .match = platform_match, .uevent = platform_uevent, .pm = &platform_dev_pm_ops, + .force_dma = true, };EXPORT_SYMBOL_GPL (platform_bus_type);drivers/gpu/host1x/bus.c +1
-0@@ -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)drivers/of/device.c +1
-7@@ -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) && -#ifdef CONFIG_ARM_AMBA - dev->bus != &amba_bustype && -#endif - dev->bus != &platform_bus_type) +if (!dev->bus->force_dma)return ret == -ENODEV ?0 : ret; dma_addr = offset =0 ;drivers/pci/pci-driver.c +1
-0@@ -1466,6 +1466,7 @@ struct bus_type pci_bus_type = { .drv_groups = pci_drv_groups, .pm = PCI_PM_OPS_PTR, .num_vf = pci_bus_num_vf, + .force_dma = true, };EXPORT_SYMBOL (pci_bus_type);include/linux/device.h +2
-0@@ -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
include/linux/device.h struct bus_type { · line 141
Quoted 5 lines
include/linux/device.h +2
-0@@ -135,6 +137,8 @@ struct bus_type {struct subsys_private *p;struct lock_class_key lock_key; + +bool force_dma;
Maybe force_dma_setup to clarify that we're not trying to force DMA usage, but rather setup of DMA properties.
Either way:
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20170926/ac787ff8/attachment.sig>
Rob Herring
maintainerPATCH 2/2 of: configure DMA for host1x devices
In reply to Robin MurphyQuoted 69 lines · Robin Murphy
Quoted 33 lines · Thierry Reding
Quoted 17 lines · Mikko Perttunen
Devices in the host1x bus rely on the old behavior of
of_dma_configureto set up DMA ops. Add a check for them intoof_dma_configure.We must do the check using a string comparison instead of using pointers since the host1x bus can be compiled into a module.
Fixes 723288836628 ("of: restrict DMA configuration")Signed-off-by Mikko Perttunen <[email protected]>--- drivers/of/device.c | 3 +++ 1 file changed, 3 insertions(+)drivers/of/device.c +0
-0drivers/of/device.c int of_dma_configure(struct device *dev, struct device_node *np) · line 112
Quoted 9 lines
drivers/of/device.c +3
-0@@ -104,6 +104,9 @@ int of_dma_configure(struct device *dev, struct device_node *np) if (!dev_is_pci(dev) &&#ifdef CONFIG_ARM_AMBA dev->bus != &amba_bustype && +#endif +#if IS_ENABLED (CONFIG_TEGRA_HOST1X ) + !(dev->bus && !strcmp ("host1x" , dev->bus->name)) && #endif dev->bus != &platform_bus_type) return ret == -ENODEV ? 0 : ret;Maybe a slightly better solution would be to add a
dev_is_host1x()function that returnsdev->bus==&host1x_bus_typeifTEGRA_HOST1Xis enabled and returns false otherwise. That way we can have a "proper" check for the bus type and avoid the #if in this file.Quoted 4 lines
It's slightly more complicated because of the dependencies between the DT and Tegra DRM trees, but I'm sure we can get Rob to either give his Acked-by on the
drivers/of/device.cchange or carry the Tegra DRM patch in the DT tree.Alternatively (and modulo Greg's opinion, obviously) it would arguably be neatest to handle this at a slightly lower level as below - I only really considered this idea after writing the existing fix, but now that I have actually written it up I do rather like it.
Robin.
----->8-----
From: Robin Murphy <[email protected]>
Date: Mon, 25 Sep 2017 12:45:58 +0100
Subject: [PATCH] drivers: Flag buses which demand DMA configurationWe 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, so we currently whitelist those to automatically opt in todma_configure(), assuming a 1:1 mapping between the DMA address space and the physical address space.Commit 723288836628 ("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. 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.
Quoted 1 line
Signed-off-by Robin Murphy <[email protected]>
Are you going to send out as a proper patch? We've now got another case with pci_epf_bus_type...
Rob
Quoted 108 lines
--- drivers/amba/bus.c | 1 + drivers/base/platform.c | 1 + drivers/gpu/host1x/bus.c | 1 + drivers/of/device.c | 8 +------- drivers/pci/pci-driver.c | 1 + include/linux/device.h | 4 ++++ 6 files changed, 9 insertions(+), 7 deletions(-)drivers/amba/bus.c +1
-0@@ -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 )drivers/base/platform.c +1
-0@@ -1142,6 +1142,7 @@ struct bus_type platform_bus_type = { .match = platform_match, .uevent = platform_uevent, .pm = &platform_dev_pm_ops, + .force_dma = true, };EXPORT_SYMBOL_GPL (platform_bus_type);drivers/gpu/host1x/bus.c +1
-0@@ -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)drivers/of/device.c +1
-7@@ -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) && -#ifdef CONFIG_ARM_AMBA - dev->bus != &amba_bustype && -#endif - dev->bus != &platform_bus_type) +if (!dev->bus->force_dma)return ret == -ENODEV ?0 : ret; dma_addr = offset =0 ;drivers/pci/pci-driver.c +1
-0@@ -1466,6 +1466,7 @@ struct bus_type pci_bus_type = { .drv_groups = pci_drv_groups, .pm = PCI_PM_OPS_PTR, .num_vf = pci_bus_num_vf, + .force_dma = true, };EXPORT_SYMBOL (pci_bus_type);include/linux/device.h +4
-1@@ -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); --2.13.4.dirty