@@ -1253,6 +1253,17 @@ static bool acpi_fwnode_device_is_available(const struct fwnode_handle *fwnode)
return acpi_device_is_present(to_acpi_device_node(fwnode));
}
+static bool acpi_fwnode_device_dma_supported(const struct fwnode_handle *fwnode)
+{
+ return acpi_dma_supported(to_acpi_device_node(fwnode));
+}
+
+static enum dev_dma_attr
+acpi_fwnode_device_get_dma_attr(const struct fwnode_handle *fwnode)
+{
+ return acpi_get_dma_attr(to_acpi_device_node(fwnode));
+}
+
static bool acpi_fwnode_property_present(const struct fwnode_handle *fwnode,
const char *propname)
{
@@ -1384,6 +1395,9 @@ acpi_fwnode_device_get_match_data(const struct fwnode_handle *fwnode,
const struct fwnode_operations ops = { \
.device_is_available = acpi_fwnode_device_is_available, \
.device_get_match_data = acpi_fwnode_device_get_match_data, \
+ .device_dma_supported = \
+ acpi_fwnode_device_dma_supported, \
+ .device_get_dma_attr = acpi_fwnode_device_get_dma_attr, \
.property_present = acpi_fwnode_property_present, \
.property_read_int_array = \
acpi_fwnode_property_read_int_array, \
@@ -823,33 +823,16 @@ EXPORT_SYMBOL_GPL(device_get_child_node_count);
bool device_dma_supported(struct device *dev)
{
- const struct fwnode_handle *fwnode = dev_fwnode(dev);
-
- /* For DT, this is always supported.
- * For ACPI, this depends on CCA, which
- * is determined by the acpi_dma_supported().
- */
- if (is_of_node(fwnode))
- return true;
-
- return acpi_dma_supported(to_acpi_device_node(fwnode));
+ return fwnode_call_bool_op(dev_fwnode(dev), device_dma_supported);
}
EXPORT_SYMBOL_GPL(device_dma_supported);
enum dev_dma_attr device_get_dma_attr(struct device *dev)
{
- const struct fwnode_handle *fwnode = dev_fwnode(dev);
- enum dev_dma_attr attr = DEV_DMA_NOT_SUPPORTED;
-
- if (is_of_node(fwnode)) {
- if (of_dma_is_coherent(to_of_node(fwnode)))
- attr = DEV_DMA_COHERENT;
- else
- attr = DEV_DMA_NON_COHERENT;
- } else
- attr = acpi_get_dma_attr(to_acpi_device_node(fwnode));
+ if (!fwnode_has_op(dev_fwnode(dev), device_get_dma_attr))
+ return DEV_DMA_NOT_SUPPORTED;
- return attr;
+ return fwnode_call_int_op(dev_fwnode(dev), device_get_dma_attr);
}
EXPORT_SYMBOL_GPL(device_get_dma_attr);
@@ -22,6 +22,7 @@
#define pr_fmt(fmt) "OF: " fmt
#include <linux/of.h>
+#include <linux/of_address.h>
#include <linux/of_device.h>
#include <linux/of_graph.h>
#include <linux/of_irq.h>
@@ -872,6 +873,20 @@ static bool of_fwnode_device_is_available(const struct fwnode_handle *fwnode)
return of_device_is_available(to_of_node(fwnode));
}
+static bool of_fwnode_device_dma_supported(const struct fwnode_handle *fwnode)
+{
+ return true;
+}
+
+static enum dev_dma_attr
+of_fwnode_device_get_dma_attr(const struct fwnode_handle *fwnode)
+{
+ if (of_dma_is_coherent(to_of_node(fwnode)))
+ return DEV_DMA_COHERENT;
+ else
+ return DEV_DMA_NON_COHERENT;
+}
+
static bool of_fwnode_property_present(const struct fwnode_handle *fwnode,
const char *propname)
{
@@ -1472,6 +1487,8 @@ const struct fwnode_operations of_fwnode_ops = {
.put = of_fwnode_put,
.device_is_available = of_fwnode_device_is_available,
.device_get_match_data = of_fwnode_device_get_match_data,
+ .device_dma_supported = of_fwnode_device_dma_supported,
+ .device_get_dma_attr = of_fwnode_device_get_dma_attr,
.property_present = of_fwnode_property_present,
.property_read_int_array = of_fwnode_property_read_int_array,
.property_read_string_array = of_fwnode_property_read_string_array,
@@ -113,6 +113,9 @@ struct fwnode_operations {
bool (*device_is_available)(const struct fwnode_handle *fwnode);
const void *(*device_get_match_data)(const struct fwnode_handle *fwnode,
const struct device *dev);
+ bool (*device_dma_supported)(const struct fwnode_handle *fwnode);
+ enum dev_dma_attr
+ (*device_get_dma_attr)(const struct fwnode_handle *fwnode);
bool (*property_present)(const struct fwnode_handle *fwnode,
const char *propname);
int (*property_read_int_array)(const struct fwnode_handle *fwnode,