ACPI: Adding DMA Attribute APIs for ACPI Device
authorSuthikulpanit, Suravee <Suravee.Suthikulpanit@amd.com>
Wed, 28 Oct 2015 22:50:48 +0000 (15:50 -0700)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Sat, 7 Nov 2015 00:29:21 +0000 (01:29 +0100)
Adding acpi_get_dma_attr() to query DMA attributes of ACPI devices.
It returns the enum dev_dma_attr, which communicates DMA information
more clearly. This API replaces the acpi_check_dma(), which will be
removed in subsequent patch.

This patch also provides a convenient function, acpi_dma_supported(),
to check DMA support of the specified ACPI device.

Signed-off-by: Suravee Suthikulpanit <Suravee.Suthikulpanit@amd.com>
Acked-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Hanjun Guo <hanjun.guo@linaro.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
drivers/acpi/scan.c
include/acpi/acpi_bus.h
include/linux/acpi.h

index d1ce377db3e94e95d239eb9a2d5e8c4b1230757e..ed3d76fadccf40ff8057ff48c4ee1134b8eed5c9 100644 (file)
@@ -1308,6 +1308,48 @@ void acpi_free_pnp_ids(struct acpi_device_pnp *pnp)
        kfree(pnp->unique_id);
 }
 
+/**
+ * acpi_dma_supported - Check DMA support for the specified device.
+ * @adev: The pointer to acpi device
+ *
+ * Return false if DMA is not supported. Otherwise, return true
+ */
+bool acpi_dma_supported(struct acpi_device *adev)
+{
+       if (!adev)
+               return false;
+
+       if (adev->flags.cca_seen)
+               return true;
+
+       /*
+       * Per ACPI 6.0 sec 6.2.17, assume devices can do cache-coherent
+       * DMA on "Intel platforms".  Presumably that includes all x86 and
+       * ia64, and other arches will set CONFIG_ACPI_CCA_REQUIRED=y.
+       */
+       if (!IS_ENABLED(CONFIG_ACPI_CCA_REQUIRED))
+               return true;
+
+       return false;
+}
+
+/**
+ * acpi_get_dma_attr - Check the supported DMA attr for the specified device.
+ * @adev: The pointer to acpi device
+ *
+ * Return enum dev_dma_attr.
+ */
+enum dev_dma_attr acpi_get_dma_attr(struct acpi_device *adev)
+{
+       if (!acpi_dma_supported(adev))
+               return DEV_DMA_NOT_SUPPORTED;
+
+       if (adev->flags.coherent_dma)
+               return DEV_DMA_COHERENT;
+       else
+               return DEV_DMA_NON_COHERENT;
+}
+
 static void acpi_init_coherency(struct acpi_device *adev)
 {
        unsigned long long cca = 0;
index 8df9905203041e6e7458e3ca7a18de597551bc2b..e56e6520edce4e12025db34411046b2659e11666 100644 (file)
@@ -596,6 +596,9 @@ struct acpi_pci_root {
 
 /* helper */
 
+bool acpi_dma_supported(struct acpi_device *adev);
+enum dev_dma_attr acpi_get_dma_attr(struct acpi_device *adev);
+
 struct acpi_device *acpi_find_child_device(struct acpi_device *parent,
                                           u64 address, bool check_children);
 int acpi_is_root_bridge(acpi_handle);
index 496265b0f52755b0acc6bf2781f2a1961cd0bbb4..292af3b69ede0d77ba213aa1f13a2029f94b63f9 100644 (file)
@@ -579,6 +579,16 @@ static inline bool acpi_check_dma(struct acpi_device *adev, bool *coherent)
        return false;
 }
 
+static inline bool acpi_dma_supported(struct acpi_device *adev)
+{
+       return false;
+}
+
+static inline enum dev_dma_attr acpi_get_dma_attr(struct acpi_device *adev)
+{
+       return DEV_DMA_NOT_SUPPORTED;
+}
+
 #define ACPI_PTR(_ptr) (NULL)
 
 #endif /* !CONFIG_ACPI */