* [PATCH 2/5] dma-mapping: Add devm_ interface for dma_map_single()
2014-05-16 8:26 [PATCH 0/5] devres: Add functions + migrate Xillybus driver Eli Billauer
2014-05-16 8:26 ` [PATCH 1/5] devres: Add devm_get_free_pages API Eli Billauer
@ 2014-05-16 8:26 ` Eli Billauer
2014-05-16 21:08 ` Tejun Heo
2014-05-16 8:26 ` [PATCH 3/5] dma-mapping: pci: Add devm_ interface for pci_map_single Eli Billauer
` (2 subsequent siblings)
4 siblings, 1 reply; 13+ messages in thread
From: Eli Billauer @ 2014-05-16 8:26 UTC (permalink / raw)
To: gregkh; +Cc: devel, tj, linux-kernel, 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] 13+ messages in thread* [PATCH 4/5] staging: xillybus: Use devm_ API on probe and remove
2014-05-16 8:26 [PATCH 0/5] devres: Add functions + migrate Xillybus driver Eli Billauer
` (2 preceding siblings ...)
2014-05-16 8:26 ` [PATCH 3/5] dma-mapping: pci: Add devm_ interface for pci_map_single Eli Billauer
@ 2014-05-16 8:26 ` Eli Billauer
2014-05-16 8:26 ` [PATCH 5/5] staging: xillybus: Use devm_ API for memory allocation and DMA mapping Eli Billauer
4 siblings, 0 replies; 13+ messages in thread
From: Eli Billauer @ 2014-05-16 8:26 UTC (permalink / raw)
To: gregkh; +Cc: devel, tj, linux-kernel, Eli Billauer
Suggested-by: Baruch Siach <baruch@tkos.co.il>
Signed-off-by: Eli Billauer <eli.billauer@gmail.com>
---
drivers/staging/xillybus/xillybus.h | 1 -
drivers/staging/xillybus/xillybus_core.c | 2 +-
drivers/staging/xillybus/xillybus_of.c | 47 ++++-----------------
drivers/staging/xillybus/xillybus_pcie.c | 65 ++++++++----------------------
4 files changed, 27 insertions(+), 88 deletions(-)
diff --git a/drivers/staging/xillybus/xillybus.h b/drivers/staging/xillybus/xillybus.h
index e5e91d6..78a749a 100644
--- a/drivers/staging/xillybus/xillybus.h
+++ b/drivers/staging/xillybus/xillybus.h
@@ -116,7 +116,6 @@ struct xilly_endpoint {
*/
struct pci_dev *pdev;
struct device *dev;
- struct resource res; /* OF devices only */
struct xilly_endpoint_hardware *ephw;
struct list_head ep_list;
diff --git a/drivers/staging/xillybus/xillybus_core.c b/drivers/staging/xillybus/xillybus_core.c
index b0a6696..fe8f9d2 100644
--- a/drivers/staging/xillybus/xillybus_core.c
+++ b/drivers/staging/xillybus/xillybus_core.c
@@ -2094,7 +2094,7 @@ struct xilly_endpoint *xillybus_init_endpoint(struct pci_dev *pdev,
{
struct xilly_endpoint *endpoint;
- endpoint = kzalloc(sizeof(*endpoint), GFP_KERNEL);
+ endpoint = devm_kzalloc(dev, sizeof(*endpoint), GFP_KERNEL);
if (!endpoint) {
dev_err(dev, "Failed to allocate memory. Aborting.\n");
return NULL;
diff --git a/drivers/staging/xillybus/xillybus_of.c b/drivers/staging/xillybus/xillybus_of.c
index 23a609b..46ea010 100644
--- a/drivers/staging/xillybus/xillybus_of.c
+++ b/drivers/staging/xillybus/xillybus_of.c
@@ -19,6 +19,7 @@
#include <linux/of_address.h>
#include <linux/of_device.h>
#include <linux/of_platform.h>
+#include <linux/err.h>
#include "xillybus.h"
MODULE_DESCRIPTION("Xillybus driver for Open Firmware");
@@ -123,6 +124,7 @@ static int xilly_drv_probe(struct platform_device *op)
struct xilly_endpoint *endpoint;
int rc = 0;
int irq;
+ struct resource res;
struct xilly_endpoint_hardware *ephw = &of_hw;
if (of_property_read_bool(dev->of_node, "dma-coherent"))
@@ -135,38 +137,26 @@ static int xilly_drv_probe(struct platform_device *op)
dev_set_drvdata(dev, endpoint);
- rc = of_address_to_resource(dev->of_node, 0, &endpoint->res);
+ rc = of_address_to_resource(dev->of_node, 0, &res);
if (rc) {
dev_warn(endpoint->dev,
"Failed to obtain device tree resource\n");
- goto failed_request_regions;
+ return rc;
}
- if (!request_mem_region(endpoint->res.start,
- resource_size(&endpoint->res), xillyname)) {
- dev_err(endpoint->dev,
- "request_mem_region failed. Aborting.\n");
- rc = -EBUSY;
- goto failed_request_regions;
- }
+ endpoint->registers = devm_ioremap_resource(dev, &res);
- endpoint->registers = of_iomap(dev->of_node, 0);
- if (!endpoint->registers) {
- dev_err(endpoint->dev,
- "Failed to map I/O memory. Aborting.\n");
- rc = -EIO;
- goto failed_iomap0;
- }
+ if (IS_ERR(endpoint->registers))
+ return PTR_ERR(endpoint->registers);
irq = irq_of_parse_and_map(dev->of_node, 0);
- rc = request_irq(irq, xillybus_isr, 0, xillyname, endpoint);
+ rc = devm_request_irq(dev, irq, xillybus_isr, 0, xillyname, endpoint);
if (rc) {
dev_err(endpoint->dev,
"Failed to register IRQ handler. Aborting.\n");
- rc = -ENODEV;
- goto failed_register_irq;
+ return -ENODEV;
}
rc = xillybus_endpoint_discovery(endpoint);
@@ -174,18 +164,8 @@ static int xilly_drv_probe(struct platform_device *op)
if (!rc)
return 0;
- free_irq(irq, endpoint);
-
-failed_register_irq:
- iounmap(endpoint->registers);
-failed_iomap0:
- release_mem_region(endpoint->res.start,
- resource_size(&endpoint->res));
-
-failed_request_regions:
xillybus_do_cleanup(&endpoint->cleanup, endpoint);
- kfree(endpoint);
return rc;
}
@@ -193,20 +173,11 @@ static int xilly_drv_remove(struct platform_device *op)
{
struct device *dev = &op->dev;
struct xilly_endpoint *endpoint = dev_get_drvdata(dev);
- int irq = irq_of_parse_and_map(dev->of_node, 0);
xillybus_endpoint_remove(endpoint);
- free_irq(irq, endpoint);
-
- iounmap(endpoint->registers);
- release_mem_region(endpoint->res.start,
- resource_size(&endpoint->res));
-
xillybus_do_cleanup(&endpoint->cleanup, endpoint);
- kfree(endpoint);
-
return 0;
}
diff --git a/drivers/staging/xillybus/xillybus_pcie.c b/drivers/staging/xillybus/xillybus_pcie.c
index 51426d8..a4fe51c 100644
--- a/drivers/staging/xillybus/xillybus_pcie.c
+++ b/drivers/staging/xillybus/xillybus_pcie.c
@@ -141,38 +141,32 @@ static int xilly_probe(struct pci_dev *pdev,
pci_set_drvdata(pdev, endpoint);
- rc = pci_enable_device(pdev);
-
- /* L0s has caused packet drops. No power saving, thank you. */
-
- pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S);
+ rc = pcim_enable_device(pdev);
if (rc) {
dev_err(endpoint->dev,
- "pci_enable_device() failed. Aborting.\n");
- goto no_enable;
+ "pcim_enable_device() failed. Aborting.\n");
+ return rc;
}
+ /* L0s has caused packet drops. No power saving, thank you. */
+
+ pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S);
+
if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) {
dev_err(endpoint->dev,
"Incorrect BAR configuration. Aborting.\n");
- rc = -ENODEV;
- goto bad_bar;
+ return -ENODEV;
}
- rc = pci_request_regions(pdev, xillyname);
+ rc = pcim_iomap_regions(pdev, 0x01, xillyname);
if (rc) {
dev_err(endpoint->dev,
- "pci_request_regions() failed. Aborting.\n");
- goto failed_request_regions;
+ "pcim_iomap_regions() failed. Aborting.\n");
+ return rc;
}
- endpoint->registers = pci_iomap(pdev, 0, 128);
- if (!endpoint->registers) {
- dev_err(endpoint->dev, "Failed to map BAR 0. Aborting.\n");
- rc = -EIO;
- goto failed_iomap0;
- }
+ endpoint->registers = pcim_iomap_table(pdev)[0];
pci_set_master(pdev);
@@ -180,16 +174,15 @@ static int xilly_probe(struct pci_dev *pdev,
if (pci_enable_msi(pdev)) {
dev_err(endpoint->dev,
"Failed to enable MSI interrupts. Aborting.\n");
- rc = -ENODEV;
- goto failed_enable_msi;
+ return -ENODEV;
}
- rc = request_irq(pdev->irq, xillybus_isr, 0, xillyname, endpoint);
+ rc = devm_request_irq(&pdev->dev, pdev->irq, xillybus_isr, 0,
+ xillyname, endpoint);
if (rc) {
dev_err(endpoint->dev,
"Failed to register MSI handler. Aborting.\n");
- rc = -ENODEV;
- goto failed_register_msi;
+ return -ENODEV;
}
/*
@@ -203,8 +196,7 @@ static int xilly_probe(struct pci_dev *pdev,
endpoint->dma_using_dac = 0;
else {
dev_err(endpoint->dev, "Failed to set DMA mask. Aborting.\n");
- rc = -ENODEV;
- goto failed_dmamask;
+ return -ENODEV;
}
rc = xillybus_endpoint_discovery(endpoint);
@@ -212,22 +204,8 @@ static int xilly_probe(struct pci_dev *pdev,
if (!rc)
return 0;
-failed_dmamask:
- free_irq(pdev->irq, endpoint);
-failed_register_msi:
- pci_disable_msi(pdev);
-failed_enable_msi:
- /* pci_clear_master(pdev); Nobody else seems to do this */
- pci_iounmap(pdev, endpoint->registers);
-failed_iomap0:
- pci_release_regions(pdev);
-failed_request_regions:
-bad_bar:
- pci_disable_device(pdev);
-no_enable:
xillybus_do_cleanup(&endpoint->cleanup, endpoint);
- kfree(endpoint);
return rc;
}
@@ -237,16 +215,7 @@ static void xilly_remove(struct pci_dev *pdev)
xillybus_endpoint_remove(endpoint);
- free_irq(pdev->irq, endpoint);
-
- pci_disable_msi(pdev);
- pci_iounmap(pdev, endpoint->registers);
- pci_release_regions(pdev);
- pci_disable_device(pdev);
-
xillybus_do_cleanup(&endpoint->cleanup, endpoint);
-
- kfree(endpoint);
}
MODULE_DEVICE_TABLE(pci, xillyids);
--
1.7.2.3
^ permalink raw reply related [flat|nested] 13+ messages in thread* [PATCH 5/5] staging: xillybus: Use devm_ API for memory allocation and DMA mapping
2014-05-16 8:26 [PATCH 0/5] devres: Add functions + migrate Xillybus driver Eli Billauer
` (3 preceding siblings ...)
2014-05-16 8:26 ` [PATCH 4/5] staging: xillybus: Use devm_ API on probe and remove Eli Billauer
@ 2014-05-16 8:26 ` Eli Billauer
4 siblings, 0 replies; 13+ messages in thread
From: Eli Billauer @ 2014-05-16 8:26 UTC (permalink / raw)
To: gregkh; +Cc: devel, tj, linux-kernel, Eli Billauer
Managed device resource API replaces code that reinvents it for memory
allocation, page allocation and DMA mapping.
Suggested-by: Baruch Siach <baruch@tkos.co.il>
Signed-off-by: Eli Billauer <eli.billauer@gmail.com>
---
drivers/staging/xillybus/xillybus.h | 31 +------
drivers/staging/xillybus/xillybus_core.c | 160 ++++++++----------------------
drivers/staging/xillybus/xillybus_of.c | 54 +----------
drivers/staging/xillybus/xillybus_pcie.c | 46 +--------
4 files changed, 48 insertions(+), 243 deletions(-)
diff --git a/drivers/staging/xillybus/xillybus.h b/drivers/staging/xillybus/xillybus.h
index 78a749a..88bb6e5 100644
--- a/drivers/staging/xillybus/xillybus.h
+++ b/drivers/staging/xillybus/xillybus.h
@@ -25,33 +25,12 @@
struct xilly_endpoint_hardware;
-struct xilly_page {
- struct list_head node;
- unsigned long addr;
- unsigned int order;
-};
-
-struct xilly_dma {
- struct list_head node;
- struct pci_dev *pdev;
- struct device *dev;
- dma_addr_t dma_addr;
- size_t size;
- int direction;
-};
-
struct xilly_buffer {
void *addr;
dma_addr_t dma_addr;
int end_offset; /* Counting elements, not bytes */
};
-struct xilly_cleanup {
- struct list_head to_kfree;
- struct list_head to_pagefree;
- struct list_head to_unmap;
-};
-
struct xilly_idt_handle {
unsigned char *chandesc;
unsigned char *idt;
@@ -126,9 +105,6 @@ struct xilly_endpoint {
struct mutex register_mutex;
wait_queue_head_t ep_wait;
- /* List of memory allocations, to make release easy */
- struct xilly_cleanup cleanup;
-
/* Channels and message handling */
struct cdev cdev;
@@ -156,19 +132,14 @@ struct xilly_endpoint_hardware {
dma_addr_t,
size_t,
int);
- dma_addr_t (*map_single)(struct xilly_cleanup *,
- struct xilly_endpoint *,
+ dma_addr_t (*map_single)(struct xilly_endpoint *,
void *,
size_t,
int);
- void (*unmap_single)(struct xilly_dma *entry);
};
irqreturn_t xillybus_isr(int irq, void *data);
-void xillybus_do_cleanup(struct xilly_cleanup *mem,
- struct xilly_endpoint *endpoint);
-
struct xilly_endpoint *xillybus_init_endpoint(struct pci_dev *pdev,
struct device *dev,
struct xilly_endpoint_hardware
diff --git a/drivers/staging/xillybus/xillybus_core.c b/drivers/staging/xillybus/xillybus_core.c
index fe8f9d2..ff78937 100644
--- a/drivers/staging/xillybus/xillybus_core.c
+++ b/drivers/staging/xillybus/xillybus_core.c
@@ -311,85 +311,14 @@ EXPORT_SYMBOL(xillybus_isr);
* no locks are applied!
*/
-void xillybus_do_cleanup(struct xilly_cleanup *mem,
- struct xilly_endpoint *endpoint)
-{
- struct list_head *this, *next;
-
- list_for_each_safe(this, next, &mem->to_unmap) {
- struct xilly_dma *entry =
- list_entry(this, struct xilly_dma, node);
-
- endpoint->ephw->unmap_single(entry);
- kfree(entry);
- }
-
- INIT_LIST_HEAD(&mem->to_unmap);
-
- list_for_each_safe(this, next, &mem->to_kfree)
- kfree(this);
-
- INIT_LIST_HEAD(&mem->to_kfree);
-
- list_for_each_safe(this, next, &mem->to_pagefree) {
- struct xilly_page *entry =
- list_entry(this, struct xilly_page, node);
-
- free_pages(entry->addr, entry->order);
- kfree(entry);
- }
- INIT_LIST_HEAD(&mem->to_pagefree);
-}
-EXPORT_SYMBOL(xillybus_do_cleanup);
-
-static void *xilly_malloc(struct xilly_cleanup *mem, size_t size)
-{
- void *ptr;
-
- ptr = kzalloc(sizeof(struct list_head) + size, GFP_KERNEL);
-
- if (!ptr)
- return ptr;
-
- list_add_tail((struct list_head *) ptr, &mem->to_kfree);
-
- return ptr + sizeof(struct list_head);
-}
-
-static unsigned long xilly_pagealloc(struct xilly_cleanup *mem,
- unsigned long order)
-{
- unsigned long addr;
- struct xilly_page *this;
-
- this = kmalloc(sizeof(struct xilly_page), GFP_KERNEL);
- if (!this)
- return 0;
-
- addr = __get_free_pages(GFP_KERNEL | __GFP_DMA32 | __GFP_ZERO, order);
-
- if (!addr) {
- kfree(this);
- return 0;
- }
-
- this->addr = addr;
- this->order = order;
-
- list_add_tail(&this->node, &mem->to_pagefree);
-
- return addr;
-}
-
-
static void xillybus_autoflush(struct work_struct *work);
static int xilly_setupchannels(struct xilly_endpoint *ep,
- struct xilly_cleanup *mem,
unsigned char *chandesc,
int entries
)
{
+ struct device *dev = ep->dev;
int i, entry, wr_nbuffer, rd_nbuffer;
struct xilly_channel *channel;
int channelnum, bufnum, bufsize, format, is_writebuf;
@@ -402,17 +331,19 @@ static int xilly_setupchannels(struct xilly_endpoint *ep,
int left_of_rd_salami = 0;
dma_addr_t dma_addr;
int msg_buf_done = 0;
+ const gfp_t gfp_mask = GFP_KERNEL | __GFP_DMA32 | __GFP_ZERO;
struct xilly_buffer *this_buffer = NULL; /* Init to silence warning */
- channel = xilly_malloc(mem, ep->num_channels *
- sizeof(struct xilly_channel));
+ channel = devm_kzalloc(dev, ep->num_channels *
+ sizeof(struct xilly_channel), GFP_KERNEL);
if (!channel)
goto memfail;
- ep->channels = xilly_malloc(mem, (ep->num_channels + 1) *
- sizeof(struct xilly_channel *));
+ ep->channels = devm_kzalloc(dev, (ep->num_channels + 1) *
+ sizeof(struct xilly_channel *),
+ GFP_KERNEL);
if (!ep->channels)
goto memfail;
@@ -501,16 +432,16 @@ static int xilly_setupchannels(struct xilly_endpoint *ep,
channel->rd_exclusive_open = exclusive_open;
channel->seekable = seekable;
- channel->rd_buffers = xilly_malloc(
- mem,
- bufnum * sizeof(struct xilly_buffer *));
+ channel->rd_buffers = devm_kzalloc(dev,
+ bufnum * sizeof(struct xilly_buffer *),
+ GFP_KERNEL);
if (!channel->rd_buffers)
goto memfail;
- this_buffer = xilly_malloc(
- mem,
- bufnum * sizeof(struct xilly_buffer));
+ this_buffer = devm_kzalloc(dev,
+ bufnum * sizeof(struct xilly_buffer),
+ GFP_KERNEL);
if (!this_buffer)
goto memfail;
@@ -530,16 +461,16 @@ static int xilly_setupchannels(struct xilly_endpoint *ep,
channel->wr_synchronous = synchronous;
channel->wr_exclusive_open = exclusive_open;
- channel->wr_buffers = xilly_malloc(
- mem,
- bufnum * sizeof(struct xilly_buffer *));
+ channel->wr_buffers = devm_kzalloc(dev,
+ bufnum * sizeof(struct xilly_buffer *),
+ GFP_KERNEL);
if (!channel->wr_buffers)
goto memfail;
- this_buffer = xilly_malloc(
- mem,
- bufnum * sizeof(struct xilly_buffer));
+ this_buffer = devm_kzalloc(dev,
+ bufnum * sizeof(struct xilly_buffer),
+ GFP_KERNEL);
if (!this_buffer)
goto memfail;
@@ -576,15 +507,16 @@ static int xilly_setupchannels(struct xilly_endpoint *ep,
}
wr_salami = (void *)
- xilly_pagealloc(mem,
- allocorder);
+ devm_get_free_pages(
+ dev, gfp_mask,
+ allocorder);
+
if (!wr_salami)
goto memfail;
left_of_wr_salami = allocsize;
}
dma_addr = ep->ephw->map_single(
- mem,
ep,
wr_salami,
bytebufsize,
@@ -654,8 +586,8 @@ static int xilly_setupchannels(struct xilly_endpoint *ep,
}
rd_salami = (void *)
- xilly_pagealloc(
- mem,
+ devm_get_free_pages(
+ dev, gfp_mask,
allocorder);
if (!rd_salami)
@@ -664,7 +596,6 @@ static int xilly_setupchannels(struct xilly_endpoint *ep,
}
dma_addr = ep->ephw->map_single(
- mem,
ep,
rd_salami,
bytebufsize,
@@ -2103,9 +2034,6 @@ struct xilly_endpoint *xillybus_init_endpoint(struct pci_dev *pdev,
endpoint->pdev = pdev;
endpoint->dev = dev;
endpoint->ephw = ephw;
- INIT_LIST_HEAD(&endpoint->cleanup.to_kfree);
- INIT_LIST_HEAD(&endpoint->cleanup.to_pagefree);
- INIT_LIST_HEAD(&endpoint->cleanup.to_unmap);
endpoint->msg_counter = 0x0b;
endpoint->failed_messages = 0;
endpoint->fatal_error = 0;
@@ -2131,7 +2059,7 @@ static int xilly_quiesce(struct xilly_endpoint *endpoint)
if (endpoint->idtlen < 0) {
dev_err(endpoint->dev,
- "Failed to quiesce the device on exit. Quitting while leaving a mess.\n");
+ "Failed to quiesce the device on exit.\n");
return -ENODEV;
}
return 0; /* Success */
@@ -2141,8 +2069,9 @@ int xillybus_endpoint_discovery(struct xilly_endpoint *endpoint)
{
int rc = 0;
- struct xilly_cleanup tmpmem;
+ void *bootstrap_resources;
int idtbuffersize = (1 << PAGE_SHIFT);
+ struct device *dev = endpoint->dev;
/*
* The bogus IDT is used during bootstrap for allocating the initial
@@ -2155,10 +2084,6 @@ int xillybus_endpoint_discovery(struct xilly_endpoint *endpoint)
3, 192, PAGE_SHIFT, 0 };
struct xilly_idt_handle idt_handle;
- INIT_LIST_HEAD(&tmpmem.to_kfree);
- INIT_LIST_HEAD(&tmpmem.to_pagefree);
- INIT_LIST_HEAD(&tmpmem.to_unmap);
-
/*
* Writing the value 0x00000001 to Endianness register signals which
* endianness this processor is using, so the FPGA can swap words as
@@ -2170,12 +2095,16 @@ int xillybus_endpoint_discovery(struct xilly_endpoint *endpoint)
/* Bootstrap phase I: Allocate temporary message buffer */
+ bootstrap_resources = devres_open_group(dev, NULL, GFP_KERNEL);
+ if (!bootstrap_resources)
+ return -ENOMEM;
+
endpoint->num_channels = 0;
- rc = xilly_setupchannels(endpoint, &tmpmem, bogus_idt, 1);
+ rc = xilly_setupchannels(endpoint, bogus_idt, 1);
if (rc)
- goto failed_buffers;
+ return rc;
/* Clear the message subsystem (and counter in particular) */
iowrite32(0x04, &endpoint->registers[fpga_msg_ctrl_reg]);
@@ -2199,8 +2128,7 @@ int xillybus_endpoint_discovery(struct xilly_endpoint *endpoint)
if (endpoint->idtlen < 0) {
dev_err(endpoint->dev, "No response from FPGA. Aborting.\n");
- rc = -ENODEV;
- goto failed_quiesce;
+ return -ENODEV;
}
/* Enable DMA */
@@ -2216,7 +2144,7 @@ int xillybus_endpoint_discovery(struct xilly_endpoint *endpoint)
endpoint->num_channels = 1;
- rc = xilly_setupchannels(endpoint, &tmpmem, bogus_idt, 2);
+ rc = xilly_setupchannels(endpoint, bogus_idt, 2);
if (rc)
goto failed_idt;
@@ -2234,10 +2162,12 @@ int xillybus_endpoint_discovery(struct xilly_endpoint *endpoint)
rc = -ENODEV;
goto failed_idt;
}
+
+ devres_close_group(dev, bootstrap_resources);
+
/* Bootstrap phase III: Allocate buffers according to IDT */
rc = xilly_setupchannels(endpoint,
- &endpoint->cleanup,
idt_handle.chandesc,
idt_handle.entries);
@@ -2260,7 +2190,7 @@ int xillybus_endpoint_discovery(struct xilly_endpoint *endpoint)
if (rc)
goto failed_chrdevs;
- xillybus_do_cleanup(&tmpmem, endpoint);
+ devres_release_group(dev, bootstrap_resources);
return 0;
@@ -2270,16 +2200,8 @@ failed_chrdevs:
mutex_unlock(&ep_list_lock);
failed_idt:
- /* Quiesce the device. Now it's serious to do it */
- rc = xilly_quiesce(endpoint);
-
- if (rc)
- return rc; /* FPGA may still DMA, so no release */
-
+ xilly_quiesce(endpoint);
flush_workqueue(xillybus_wq);
-failed_quiesce:
-failed_buffers:
- xillybus_do_cleanup(&tmpmem, endpoint);
return rc;
}
diff --git a/drivers/staging/xillybus/xillybus_of.c b/drivers/staging/xillybus/xillybus_of.c
index 46ea010..0e4a67c 100644
--- a/drivers/staging/xillybus/xillybus_of.c
+++ b/drivers/staging/xillybus/xillybus_of.c
@@ -62,44 +62,13 @@ static void xilly_dma_sync_single_nop(struct xilly_endpoint *ep,
{
}
-static dma_addr_t xilly_map_single_of(struct xilly_cleanup *mem,
- struct xilly_endpoint *ep,
+static dma_addr_t xilly_map_single_of(struct xilly_endpoint *ep,
void *ptr,
size_t size,
int direction
)
{
-
- dma_addr_t addr = 0;
- struct xilly_dma *this;
-
- this = kmalloc(sizeof(struct xilly_dma), GFP_KERNEL);
- if (!this)
- return 0;
-
- addr = dma_map_single(ep->dev, ptr, size, direction);
- this->direction = direction;
-
- if (dma_mapping_error(ep->dev, addr)) {
- kfree(this);
- return 0;
- }
-
- this->dma_addr = addr;
- this->dev = ep->dev;
- this->size = size;
-
- list_add_tail(&this->node, &mem->to_unmap);
-
- return addr;
-}
-
-static void xilly_unmap_single_of(struct xilly_dma *entry)
-{
- dma_unmap_single(entry->dev,
- entry->dma_addr,
- entry->size,
- entry->direction);
+ return dmam_map_single(ep->dev, ptr, size, direction);
}
static struct xilly_endpoint_hardware of_hw = {
@@ -107,7 +76,6 @@ static struct xilly_endpoint_hardware of_hw = {
.hw_sync_sgl_for_cpu = xilly_dma_sync_single_for_cpu_of,
.hw_sync_sgl_for_device = xilly_dma_sync_single_for_device_of,
.map_single = xilly_map_single_of,
- .unmap_single = xilly_unmap_single_of
};
static struct xilly_endpoint_hardware of_hw_coherent = {
@@ -115,7 +83,6 @@ static struct xilly_endpoint_hardware of_hw_coherent = {
.hw_sync_sgl_for_cpu = xilly_dma_sync_single_nop,
.hw_sync_sgl_for_device = xilly_dma_sync_single_nop,
.map_single = xilly_map_single_of,
- .unmap_single = xilly_unmap_single_of
};
static int xilly_drv_probe(struct platform_device *op)
@@ -138,12 +105,6 @@ static int xilly_drv_probe(struct platform_device *op)
dev_set_drvdata(dev, endpoint);
rc = of_address_to_resource(dev->of_node, 0, &res);
- if (rc) {
- dev_warn(endpoint->dev,
- "Failed to obtain device tree resource\n");
- return rc;
- }
-
endpoint->registers = devm_ioremap_resource(dev, &res);
if (IS_ERR(endpoint->registers))
@@ -159,14 +120,7 @@ static int xilly_drv_probe(struct platform_device *op)
return -ENODEV;
}
- rc = xillybus_endpoint_discovery(endpoint);
-
- if (!rc)
- return 0;
-
- xillybus_do_cleanup(&endpoint->cleanup, endpoint);
-
- return rc;
+ return xillybus_endpoint_discovery(endpoint);
}
static int xilly_drv_remove(struct platform_device *op)
@@ -176,8 +130,6 @@ static int xilly_drv_remove(struct platform_device *op)
xillybus_endpoint_remove(endpoint);
- xillybus_do_cleanup(&endpoint->cleanup, endpoint);
-
return 0;
}
diff --git a/drivers/staging/xillybus/xillybus_pcie.c b/drivers/staging/xillybus/xillybus_pcie.c
index a4fe51c..a7d60c7 100644
--- a/drivers/staging/xillybus/xillybus_pcie.c
+++ b/drivers/staging/xillybus/xillybus_pcie.c
@@ -78,46 +78,16 @@ static void xilly_dma_sync_single_for_device_pci(struct xilly_endpoint *ep,
* but that can change.
*/
-static dma_addr_t xilly_map_single_pci(struct xilly_cleanup *mem,
- struct xilly_endpoint *ep,
+static dma_addr_t xilly_map_single_pci(struct xilly_endpoint *ep,
void *ptr,
size_t size,
int direction
)
{
-
- dma_addr_t addr = 0;
- struct xilly_dma *this;
int pci_direction;
- this = kmalloc(sizeof(struct xilly_dma), GFP_KERNEL);
- if (!this)
- return 0;
-
pci_direction = xilly_pci_direction(direction);
- addr = pci_map_single(ep->pdev, ptr, size, pci_direction);
- this->direction = pci_direction;
-
- if (pci_dma_mapping_error(ep->pdev, addr)) {
- kfree(this);
- return 0;
- }
-
- this->dma_addr = addr;
- this->pdev = ep->pdev;
- this->size = size;
-
- list_add_tail(&this->node, &mem->to_unmap);
-
- return addr;
-}
-
-static void xilly_unmap_single_pci(struct xilly_dma *entry)
-{
- pci_unmap_single(entry->pdev,
- entry->dma_addr,
- entry->size,
- entry->direction);
+ return pcim_map_single(ep->pdev, ptr, size, pci_direction);
}
static struct xilly_endpoint_hardware pci_hw = {
@@ -125,7 +95,6 @@ static struct xilly_endpoint_hardware pci_hw = {
.hw_sync_sgl_for_cpu = xilly_dma_sync_single_for_cpu_pci,
.hw_sync_sgl_for_device = xilly_dma_sync_single_for_device_pci,
.map_single = xilly_map_single_pci,
- .unmap_single = xilly_unmap_single_pci
};
static int xilly_probe(struct pci_dev *pdev,
@@ -199,14 +168,7 @@ static int xilly_probe(struct pci_dev *pdev,
return -ENODEV;
}
- rc = xillybus_endpoint_discovery(endpoint);
-
- if (!rc)
- return 0;
-
- xillybus_do_cleanup(&endpoint->cleanup, endpoint);
-
- return rc;
+ return xillybus_endpoint_discovery(endpoint);
}
static void xilly_remove(struct pci_dev *pdev)
@@ -214,8 +176,6 @@ static void xilly_remove(struct pci_dev *pdev)
struct xilly_endpoint *endpoint = pci_get_drvdata(pdev);
xillybus_endpoint_remove(endpoint);
-
- xillybus_do_cleanup(&endpoint->cleanup, endpoint);
}
MODULE_DEVICE_TABLE(pci, xillyids);
--
1.7.2.3
^ permalink raw reply related [flat|nested] 13+ messages in thread