aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexandre Bounine <alexandre.bounine@idt.com>2012-10-04 20:15:57 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-10-05 14:05:21 -0400
commitda1589f07393e88e917c317ea0c85ea37918a1cf (patch)
tree8ddfa8af4b15b463fb9f7f14f3e49b7f7d62248a
parent18f6287f538858135c2c7ed4f76d4441e28b5714 (diff)
rapidio: add inbound memory mapping interface
Add common inbound memory mapping/unmapping interface. This allows to make local memory space accessible from the RapidIO side using hardware mapping capabilities of RapidIO bridging devices. The new interface is intended to enable data transfers between RapidIO devices in combination with DMA engine support. This patch is based on patch submitted by Li Yang <leoli@freescale.com> (https://lists.ozlabs.org/pipermail/linuxppc-dev/2009-April/071210.html) Signed-off-by: Alexandre Bounine <alexandre.bounine@idt.com> Cc: Matt Porter <mporter@kernel.crashing.org> Cc: Li Yang <leoli@freescale.com> Cc: Kumar Gala <galak@kernel.crashing.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--drivers/rapidio/rio.c44
-rw-r--r--include/linux/rio.h5
-rw-r--r--include/linux/rio_drv.h5
3 files changed, 54 insertions, 0 deletions
diff --git a/drivers/rapidio/rio.c b/drivers/rapidio/rio.c
index c40665a4fa33..d7b68cc2d843 100644
--- a/drivers/rapidio/rio.c
+++ b/drivers/rapidio/rio.c
@@ -33,6 +33,7 @@
33 33
34static LIST_HEAD(rio_mports); 34static LIST_HEAD(rio_mports);
35static unsigned char next_portid; 35static unsigned char next_portid;
36static DEFINE_SPINLOCK(rio_mmap_lock);
36 37
37/** 38/**
38 * rio_local_get_device_id - Get the base/extended device id for a port 39 * rio_local_get_device_id - Get the base/extended device id for a port
@@ -398,6 +399,49 @@ int rio_release_inb_pwrite(struct rio_dev *rdev)
398EXPORT_SYMBOL_GPL(rio_release_inb_pwrite); 399EXPORT_SYMBOL_GPL(rio_release_inb_pwrite);
399 400
400/** 401/**
402 * rio_map_inb_region -- Map inbound memory region.
403 * @mport: Master port.
404 * @lstart: physical address of memory region to be mapped
405 * @rbase: RIO base address assigned to this window
406 * @size: Size of the memory region
407 * @rflags: Flags for mapping.
408 *
409 * Return: 0 -- Success.
410 *
411 * This function will create the mapping from RIO space to local memory.
412 */
413int rio_map_inb_region(struct rio_mport *mport, dma_addr_t local,
414 u64 rbase, u32 size, u32 rflags)
415{
416 int rc = 0;
417 unsigned long flags;
418
419 if (!mport->ops->map_inb)
420 return -1;
421 spin_lock_irqsave(&rio_mmap_lock, flags);
422 rc = mport->ops->map_inb(mport, local, rbase, size, rflags);
423 spin_unlock_irqrestore(&rio_mmap_lock, flags);
424 return rc;
425}
426EXPORT_SYMBOL_GPL(rio_map_inb_region);
427
428/**
429 * rio_unmap_inb_region -- Unmap the inbound memory region
430 * @mport: Master port
431 * @lstart: physical address of memory region to be unmapped
432 */
433void rio_unmap_inb_region(struct rio_mport *mport, dma_addr_t lstart)
434{
435 unsigned long flags;
436 if (!mport->ops->unmap_inb)
437 return;
438 spin_lock_irqsave(&rio_mmap_lock, flags);
439 mport->ops->unmap_inb(mport, lstart);
440 spin_unlock_irqrestore(&rio_mmap_lock, flags);
441}
442EXPORT_SYMBOL_GPL(rio_unmap_inb_region);
443
444/**
401 * rio_mport_get_physefb - Helper function that returns register offset 445 * rio_mport_get_physefb - Helper function that returns register offset
402 * for Physical Layer Extended Features Block. 446 * for Physical Layer Extended Features Block.
403 * @port: Master port to issue transaction 447 * @port: Master port to issue transaction
diff --git a/include/linux/rio.h b/include/linux/rio.h
index ba382f2b57ef..4d1a104cd78d 100644
--- a/include/linux/rio.h
+++ b/include/linux/rio.h
@@ -301,6 +301,8 @@ struct rio_net {
301 * @add_outb_message: Callback to add a message to an outbound mailbox queue. 301 * @add_outb_message: Callback to add a message to an outbound mailbox queue.
302 * @add_inb_buffer: Callback to add a buffer to an inbound mailbox queue. 302 * @add_inb_buffer: Callback to add a buffer to an inbound mailbox queue.
303 * @get_inb_message: Callback to get a message from an inbound mailbox queue. 303 * @get_inb_message: Callback to get a message from an inbound mailbox queue.
304 * @map_inb: Callback to map RapidIO address region into local memory space.
305 * @unmap_inb: Callback to unmap RapidIO address region mapped with map_inb().
304 */ 306 */
305struct rio_ops { 307struct rio_ops {
306 int (*lcread) (struct rio_mport *mport, int index, u32 offset, int len, 308 int (*lcread) (struct rio_mport *mport, int index, u32 offset, int len,
@@ -323,6 +325,9 @@ struct rio_ops {
323 int mbox, void *buffer, size_t len); 325 int mbox, void *buffer, size_t len);
324 int (*add_inb_buffer)(struct rio_mport *mport, int mbox, void *buf); 326 int (*add_inb_buffer)(struct rio_mport *mport, int mbox, void *buf);
325 void *(*get_inb_message)(struct rio_mport *mport, int mbox); 327 void *(*get_inb_message)(struct rio_mport *mport, int mbox);
328 int (*map_inb)(struct rio_mport *mport, dma_addr_t lstart,
329 u64 rstart, u32 size, u32 flags);
330 void (*unmap_inb)(struct rio_mport *mport, dma_addr_t lstart);
326}; 331};
327 332
328#define RIO_RESOURCE_MEM 0x00000100 333#define RIO_RESOURCE_MEM 0x00000100
diff --git a/include/linux/rio_drv.h b/include/linux/rio_drv.h
index 31ad146be316..b75c05920ab5 100644
--- a/include/linux/rio_drv.h
+++ b/include/linux/rio_drv.h
@@ -365,6 +365,11 @@ void rio_release_regions(struct rio_dev *);
365int rio_request_region(struct rio_dev *, int, char *); 365int rio_request_region(struct rio_dev *, int, char *);
366void rio_release_region(struct rio_dev *, int); 366void rio_release_region(struct rio_dev *, int);
367 367
368/* Memory mapping functions */
369extern int rio_map_inb_region(struct rio_mport *mport, dma_addr_t local,
370 u64 rbase, u32 size, u32 rflags);
371extern void rio_unmap_inb_region(struct rio_mport *mport, dma_addr_t lstart);
372
368/* Port-Write management */ 373/* Port-Write management */
369extern int rio_request_inb_pwrite(struct rio_dev *, 374extern int rio_request_inb_pwrite(struct rio_dev *,
370 int (*)(struct rio_dev *, union rio_pw_msg*, int)); 375 int (*)(struct rio_dev *, union rio_pw_msg*, int));