* [PATCH 1/3] dma-mapping: Add devm_ interface for dma_map_single()
@ 2014-05-17 12:22 Eli Billauer
2014-05-17 12:22 ` [PATCH 2/3] dma-mapping: Add devm_ interface for dma_map_single_attrs() Eli Billauer
2014-05-17 12:22 ` [PATCH 3/3] dma-mapping: pci: Add devm_ interface for pci_map_single Eli Billauer
0 siblings, 2 replies; 3+ messages in thread
From: Eli Billauer @ 2014-05-17 12:22 UTC (permalink / raw)
To: tj; +Cc: devel, gregkh, bhelgaas, linux-kernel, linux-pci, Eli Billauer
dmam_map_single() and dmam_unmap_single() are the managed counterparts
for the respective dma_* functions.
Note that dmam_map_single() returns zero on failure, and not a value to
be handled by dma_mapping_error(): The error check is done by
dmam_map_single() to avoid the registration of a mapping that failed.
Signed-off-by: Eli Billauer <eli.billauer@gmail.com>
---
Documentation/driver-model/devres.txt | 2 +
drivers/base/dma-mapping.c | 80 +++++++++++++++++++++++++++++++++
include/linux/dma-mapping.h | 5 ++-
3 files changed, 86 insertions(+), 1 deletions(-)
diff --git a/Documentation/driver-model/devres.txt b/Documentation/driver-model/devres.txt
index e1a2707..13b8be0 100644
--- a/Documentation/driver-model/devres.txt
+++ b/Documentation/driver-model/devres.txt
@@ -266,6 +266,8 @@ DMA
dmam_declare_coherent_memory()
dmam_pool_create()
dmam_pool_destroy()
+ dmam_map_single()
+ dmam_unmap_single()
PCI
pcim_enable_device() : after success, all PCI ops become managed
diff --git a/drivers/base/dma-mapping.c b/drivers/base/dma-mapping.c
index 0ce39a3..db1c496 100644
--- a/drivers/base/dma-mapping.c
+++ b/drivers/base/dma-mapping.c
@@ -19,6 +19,7 @@ struct dma_devres {
size_t size;
void *vaddr;
dma_addr_t dma_handle;
+ enum dma_data_direction direction;
};
static void dmam_coherent_release(struct device *dev, void *res)
@@ -267,3 +268,82 @@ int dma_common_mmap(struct device *dev, struct vm_area_struct *vma,
return ret;
}
EXPORT_SYMBOL(dma_common_mmap);
+
+static int dmam_map_match(struct device *dev, void *res, void *match_data)
+{
+ struct dma_devres *this = res, *match = match_data;
+
+ if (this->dma_handle == match->dma_handle) {
+ WARN_ON(this->size != match->size ||
+ this->direction != match->direction);
+ return 1;
+ }
+ return 0;
+}
+
+static void dmam_map_single_release(struct device *dev, void *res)
+{
+ struct dma_devres *this = res;
+
+ dma_unmap_single(dev, this->dma_handle, this->size, this->direction);
+}
+
+/**
+ * dmam_map_single - Managed dma_map_single()
+ * @dev: Device to map DMA region for
+ * @ptr: Pointer to region
+ * @size: Size to map
+ * @direction: The mapping's direction
+ *
+ * Managed dma_map_single(). The region mapped using this
+ * function will be automatically unmapped on driver detach.
+ *
+ * RETURNS:
+ * The DMA handle of the mapped region upon success, 0 otherwise.
+ */
+dma_addr_t dmam_map_single(struct device *dev, void *ptr, size_t size,
+ enum dma_data_direction direction)
+
+{
+ struct dma_devres *dr;
+ dma_addr_t dma_handle;
+
+ dr = devres_alloc(dmam_map_single_release, sizeof(*dr), GFP_KERNEL);
+ if (!dr)
+ return 0;
+
+ dma_handle = dma_map_single(dev, ptr, size, direction);
+ if (dma_mapping_error(dev, dma_handle)) {
+ devres_free(dr);
+ return 0;
+ }
+
+ dr->vaddr = ptr;
+ dr->dma_handle = dma_handle;
+ dr->size = size;
+ dr->direction = direction;
+
+ devres_add(dev, dr);
+
+ return dma_handle;
+}
+EXPORT_SYMBOL(dmam_map_single);
+
+/**
+ * dmam_unmap_single - Managed dma_unmap_single()
+ * @dev: Device to map DMA region for
+ * @dma_handle: DMA handle of the region to unmap
+ * @size: Size to unmap
+ * @direction: The mapping's direction
+ *
+ * Managed dma_unmap_single().
+ */
+void dmam_unmap_single(struct device *dev, dma_addr_t dma_handle,
+ size_t size, enum dma_data_direction direction)
+{
+ struct dma_devres match_data = { size, NULL, dma_handle, direction };
+
+ WARN_ON(devres_release(dev, dmam_map_single_release, dmam_map_match,
+ &match_data));
+}
+EXPORT_SYMBOL(dmam_unmap_single);
diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h
index fd4aee2..cdb14a8 100644
--- a/include/linux/dma-mapping.h
+++ b/include/linux/dma-mapping.h
@@ -233,7 +233,10 @@ static inline void dmam_release_declared_memory(struct device *dev)
{
}
#endif /* ARCH_HAS_DMA_DECLARE_COHERENT_MEMORY */
-
+dma_addr_t dmam_map_single(struct device *dev, void *ptr, size_t size,
+ enum dma_data_direction direction);
+void dmam_unmap_single(struct device *dev, dma_addr_t dma_handle,
+ size_t size, enum dma_data_direction direction);
#ifndef CONFIG_HAVE_DMA_ATTRS
struct dma_attrs;
--
1.7.2.3
^ permalink raw reply related [flat|nested] 3+ messages in thread
* [PATCH 2/3] dma-mapping: Add devm_ interface for dma_map_single_attrs()
2014-05-17 12:22 [PATCH 1/3] dma-mapping: Add devm_ interface for dma_map_single() Eli Billauer
@ 2014-05-17 12:22 ` Eli Billauer
2014-05-17 12:22 ` [PATCH 3/3] dma-mapping: pci: Add devm_ interface for pci_map_single Eli Billauer
1 sibling, 0 replies; 3+ messages in thread
From: Eli Billauer @ 2014-05-17 12:22 UTC (permalink / raw)
To: tj; +Cc: devel, gregkh, bhelgaas, linux-kernel, linux-pci, Eli Billauer
dmam_map_single_attrs() and dmam_unmap_single_attrs() replace the non-*_attrs
functions, which are implemented as defines instead.
The case of a non-NULL @attrs parameter has not been tested.
Suggested-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Eli Billauer <eli.billauer@gmail.com>
---
Documentation/driver-model/devres.txt | 2 +
drivers/base/dma-mapping.c | 43 +++++++++++++++++++++--------
include/asm-generic/dma-mapping-common.h | 2 +
include/linux/dma-mapping.h | 10 ++++---
4 files changed, 41 insertions(+), 16 deletions(-)
diff --git a/Documentation/driver-model/devres.txt b/Documentation/driver-model/devres.txt
index 13b8be0..2112a00 100644
--- a/Documentation/driver-model/devres.txt
+++ b/Documentation/driver-model/devres.txt
@@ -268,6 +268,8 @@ DMA
dmam_pool_destroy()
dmam_map_single()
dmam_unmap_single()
+ dmam_map_single_attrs()
+ dmam_unmap_single_attrs()
PCI
pcim_enable_device() : after success, all PCI ops become managed
diff --git a/drivers/base/dma-mapping.c b/drivers/base/dma-mapping.c
index db1c496..4e80db1 100644
--- a/drivers/base/dma-mapping.c
+++ b/drivers/base/dma-mapping.c
@@ -11,6 +11,7 @@
#include <linux/export.h>
#include <linux/gfp.h>
#include <asm-generic/dma-coherent.h>
+#include <linux/slab.h>
/*
* Managed DMA API
@@ -20,6 +21,7 @@ struct dma_devres {
void *vaddr;
dma_addr_t dma_handle;
enum dma_data_direction direction;
+ struct dma_attrs *attrs;
};
static void dmam_coherent_release(struct device *dev, void *res)
@@ -285,24 +287,29 @@ static void dmam_map_single_release(struct device *dev, void *res)
{
struct dma_devres *this = res;
- dma_unmap_single(dev, this->dma_handle, this->size, this->direction);
+ dma_unmap_single_attrs(dev, this->dma_handle, this->size,
+ this->direction, this->attrs);
+
+ kfree(this->attrs);
}
/**
- * dmam_map_single - Managed dma_map_single()
+ * dmam_map_single_attrs - Managed dma_map_single_attrs()
* @dev: Device to map DMA region for
* @ptr: Pointer to region
* @size: Size to map
* @direction: The mapping's direction
+ * @attrs: Attributes associated with the DMA mapping
*
- * Managed dma_map_single(). The region mapped using this
+ * Managed dma_map_single_attrs(). The region mapped using this
* function will be automatically unmapped on driver detach.
*
* RETURNS:
* The DMA handle of the mapped region upon success, 0 otherwise.
*/
-dma_addr_t dmam_map_single(struct device *dev, void *ptr, size_t size,
- enum dma_data_direction direction)
+dma_addr_t dmam_map_single_attrs(struct device *dev, void *ptr, size_t size,
+ enum dma_data_direction direction,
+ struct dma_attrs *attrs)
{
struct dma_devres *dr;
@@ -312,8 +319,18 @@ dma_addr_t dmam_map_single(struct device *dev, void *ptr, size_t size,
if (!dr)
return 0;
- dma_handle = dma_map_single(dev, ptr, size, direction);
+ if (attrs) {
+ dr->attrs = kmemdup(attrs, sizeof(*attrs), GFP_KERNEL);
+ if (!dr->attrs) {
+ devres_free(dr);
+ return 0;
+ }
+ } else
+ dr->attrs = NULL;
+
+ dma_handle = dma_map_single_attrs(dev, ptr, size, direction, attrs);
if (dma_mapping_error(dev, dma_handle)) {
+ kfree(dr->attrs);
devres_free(dr);
return 0;
}
@@ -327,23 +344,25 @@ dma_addr_t dmam_map_single(struct device *dev, void *ptr, size_t size,
return dma_handle;
}
-EXPORT_SYMBOL(dmam_map_single);
+EXPORT_SYMBOL(dmam_map_single_attrs);
/**
- * dmam_unmap_single - Managed dma_unmap_single()
+ * dmam_unmap_single_attrs - Managed dma_unmap_single_attrs()
* @dev: Device to map DMA region for
* @dma_handle: DMA handle of the region to unmap
* @size: Size to unmap
* @direction: The mapping's direction
+ * @attrs: Attributes associated with the DMA mapping.
*
- * Managed dma_unmap_single().
+ * Managed dma_unmap_single_attrs().
*/
-void dmam_unmap_single(struct device *dev, dma_addr_t dma_handle,
- size_t size, enum dma_data_direction direction)
+void dmam_unmap_single_attrs(struct device *dev, dma_addr_t dma_handle,
+ size_t size, enum dma_data_direction direction,
+ struct dma_attrs *attrs)
{
struct dma_devres match_data = { size, NULL, dma_handle, direction };
WARN_ON(devres_release(dev, dmam_map_single_release, dmam_map_match,
&match_data));
}
-EXPORT_SYMBOL(dmam_unmap_single);
+EXPORT_SYMBOL(dmam_unmap_single_attrs);
diff --git a/include/asm-generic/dma-mapping-common.h b/include/asm-generic/dma-mapping-common.h
index de8bf89..aaa7c68 100644
--- a/include/asm-generic/dma-mapping-common.h
+++ b/include/asm-generic/dma-mapping-common.h
@@ -175,6 +175,8 @@ dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
#define dma_unmap_single(d, a, s, r) dma_unmap_single_attrs(d, a, s, r, NULL)
#define dma_map_sg(d, s, n, r) dma_map_sg_attrs(d, s, n, r, NULL)
#define dma_unmap_sg(d, s, n, r) dma_unmap_sg_attrs(d, s, n, r, NULL)
+#define dmam_map_single(d, a, s, r) dmam_map_single_attrs(d, a, s, r, NULL)
+#define dmam_unmap_single(d, a, s, r) dmam_unmap_single_attrs(d, a, s, r, NULL)
extern int dma_common_mmap(struct device *dev, struct vm_area_struct *vma,
void *cpu_addr, dma_addr_t dma_addr, size_t size);
diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h
index cdb14a8..ba2a403 100644
--- a/include/linux/dma-mapping.h
+++ b/include/linux/dma-mapping.h
@@ -233,10 +233,12 @@ static inline void dmam_release_declared_memory(struct device *dev)
{
}
#endif /* ARCH_HAS_DMA_DECLARE_COHERENT_MEMORY */
-dma_addr_t dmam_map_single(struct device *dev, void *ptr, size_t size,
- enum dma_data_direction direction);
-void dmam_unmap_single(struct device *dev, dma_addr_t dma_handle,
- size_t size, enum dma_data_direction direction);
+dma_addr_t dmam_map_single_attrs(struct device *dev, void *ptr, size_t size,
+ enum dma_data_direction direction,
+ struct dma_attrs *attrs);
+void dmam_unmap_single_attrs(struct device *dev, dma_addr_t dma_handle,
+ size_t size, enum dma_data_direction direction,
+ struct dma_attrs *attrs);
#ifndef CONFIG_HAVE_DMA_ATTRS
struct dma_attrs;
--
1.7.2.3
^ permalink raw reply related [flat|nested] 3+ messages in thread
* [PATCH 3/3] dma-mapping: pci: Add devm_ interface for pci_map_single
2014-05-17 12:22 [PATCH 1/3] dma-mapping: Add devm_ interface for dma_map_single() Eli Billauer
2014-05-17 12:22 ` [PATCH 2/3] dma-mapping: Add devm_ interface for dma_map_single_attrs() Eli Billauer
@ 2014-05-17 12:22 ` Eli Billauer
1 sibling, 0 replies; 3+ messages in thread
From: Eli Billauer @ 2014-05-17 12:22 UTC (permalink / raw)
To: tj; +Cc: devel, gregkh, bhelgaas, linux-kernel, linux-pci, Eli Billauer
Signed-off-by: Eli Billauer <eli.billauer@gmail.com>
---
Documentation/driver-model/devres.txt | 2 ++
include/asm-generic/pci-dma-compat.h | 17 +++++++++++++++++
2 files changed, 19 insertions(+), 0 deletions(-)
diff --git a/Documentation/driver-model/devres.txt b/Documentation/driver-model/devres.txt
index 2112a00..fea2c69 100644
--- a/Documentation/driver-model/devres.txt
+++ b/Documentation/driver-model/devres.txt
@@ -274,6 +274,8 @@ DMA
PCI
pcim_enable_device() : after success, all PCI ops become managed
pcim_pin_device() : keep PCI device enabled after release
+ pcim_map_single()
+ pcim_unmap_single()
IOMAP
devm_ioport_map()
diff --git a/include/asm-generic/pci-dma-compat.h b/include/asm-generic/pci-dma-compat.h
index 1437b7d..444e598 100644
--- a/include/asm-generic/pci-dma-compat.h
+++ b/include/asm-generic/pci-dma-compat.h
@@ -113,4 +113,21 @@ static inline int pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask)
}
#endif
+/*
+ * Managed DMA API
+ */
+
+static inline dma_addr_t
+pcim_map_single(struct pci_dev *hwdev, void *ptr, size_t size, int direction)
+{
+ return dmam_map_single(hwdev == NULL ? NULL : &hwdev->dev, ptr, size, (enum dma_data_direction)direction);
+}
+
+static inline void
+pcim_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr,
+ size_t size, int direction)
+{
+ dmam_unmap_single(hwdev == NULL ? NULL : &hwdev->dev, dma_addr, size, (enum dma_data_direction)direction);
+}
+
#endif
--
1.7.2.3
^ permalink raw reply related [flat|nested] 3+ messages in thread
end of thread, other threads:[~2014-05-17 12:22 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-05-17 12:22 [PATCH 1/3] dma-mapping: Add devm_ interface for dma_map_single() Eli Billauer
2014-05-17 12:22 ` [PATCH 2/3] dma-mapping: Add devm_ interface for dma_map_single_attrs() Eli Billauer
2014-05-17 12:22 ` [PATCH 3/3] dma-mapping: pci: Add devm_ interface for pci_map_single Eli Billauer
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).