linux/arch/powerpc/include/asm/fsldma.h
<<
>>
Prefs
   1/*
   2 * Freescale MPC83XX / MPC85XX DMA Controller
   3 *
   4 * Copyright (c) 2009 Ira W. Snyder <iws@ovro.caltech.edu>
   5 *
   6 * This file is licensed under the terms of the GNU General Public License
   7 * version 2. This program is licensed "as is" without any warranty of any
   8 * kind, whether express or implied.
   9 */
  10
  11#ifndef __ARCH_POWERPC_ASM_FSLDMA_H__
  12#define __ARCH_POWERPC_ASM_FSLDMA_H__
  13
  14#include <linux/dmaengine.h>
  15
  16/*
  17 * Definitions for the Freescale DMA controller's DMA_SLAVE implemention
  18 *
  19 * The Freescale DMA_SLAVE implementation was designed to handle many-to-many
  20 * transfers. An example usage would be an accelerated copy between two
  21 * scatterlists. Another example use would be an accelerated copy from
  22 * multiple non-contiguous device buffers into a single scatterlist.
  23 *
  24 * A DMA_SLAVE transaction is defined by a struct fsl_dma_slave. This
  25 * structure contains a list of hardware addresses that should be copied
  26 * to/from the scatterlist passed into device_prep_slave_sg(). The structure
  27 * also has some fields to enable hardware-specific features.
  28 */
  29
  30/**
  31 * struct fsl_dma_hw_addr
  32 * @entry: linked list entry
  33 * @address: the hardware address
  34 * @length: length to transfer
  35 *
  36 * Holds a single physical hardware address / length pair for use
  37 * with the DMAEngine DMA_SLAVE API.
  38 */
  39struct fsl_dma_hw_addr {
  40        struct list_head entry;
  41
  42        dma_addr_t address;
  43        size_t length;
  44};
  45
  46/**
  47 * struct fsl_dma_slave
  48 * @addresses: a linked list of struct fsl_dma_hw_addr structures
  49 * @request_count: value for DMA request count
  50 * @src_loop_size: setup and enable constant source-address DMA transfers
  51 * @dst_loop_size: setup and enable constant destination address DMA transfers
  52 * @external_start: enable externally started DMA transfers
  53 * @external_pause: enable externally paused DMA transfers
  54 *
  55 * Holds a list of address / length pairs for use with the DMAEngine
  56 * DMA_SLAVE API implementation for the Freescale DMA controller.
  57 */
  58struct fsl_dma_slave {
  59
  60        /* List of hardware address/length pairs */
  61        struct list_head addresses;
  62
  63        /* Support for extra controller features */
  64        unsigned int request_count;
  65        unsigned int src_loop_size;
  66        unsigned int dst_loop_size;
  67        bool external_start;
  68        bool external_pause;
  69};
  70
  71/**
  72 * fsl_dma_slave_append - add an address/length pair to a struct fsl_dma_slave
  73 * @slave: the &struct fsl_dma_slave to add to
  74 * @address: the hardware address to add
  75 * @length: the length of bytes to transfer from @address
  76 *
  77 * Add a hardware address/length pair to a struct fsl_dma_slave. Returns 0 on
  78 * success, -ERRNO otherwise.
  79 */
  80static inline int fsl_dma_slave_append(struct fsl_dma_slave *slave,
  81                                       dma_addr_t address, size_t length)
  82{
  83        struct fsl_dma_hw_addr *addr;
  84
  85        addr = kzalloc(sizeof(*addr), GFP_ATOMIC);
  86        if (!addr)
  87                return -ENOMEM;
  88
  89        INIT_LIST_HEAD(&addr->entry);
  90        addr->address = address;
  91        addr->length = length;
  92
  93        list_add_tail(&addr->entry, &slave->addresses);
  94        return 0;
  95}
  96
  97/**
  98 * fsl_dma_slave_free - free a struct fsl_dma_slave
  99 * @slave: the struct fsl_dma_slave to free
 100 *
 101 * Free a struct fsl_dma_slave and all associated address/length pairs
 102 */
 103static inline void fsl_dma_slave_free(struct fsl_dma_slave *slave)
 104{
 105        struct fsl_dma_hw_addr *addr, *tmp;
 106
 107        if (slave) {
 108                list_for_each_entry_safe(addr, tmp, &slave->addresses, entry) {
 109                        list_del(&addr->entry);
 110                        kfree(addr);
 111                }
 112
 113                kfree(slave);
 114        }
 115}
 116
 117/**
 118 * fsl_dma_slave_alloc - allocate a struct fsl_dma_slave
 119 * @gfp: the flags to pass to kmalloc when allocating this structure
 120 *
 121 * Allocate a struct fsl_dma_slave for use by the DMA_SLAVE API. Returns a new
 122 * struct fsl_dma_slave on success, or NULL on failure.
 123 */
 124static inline struct fsl_dma_slave *fsl_dma_slave_alloc(gfp_t gfp)
 125{
 126        struct fsl_dma_slave *slave;
 127
 128        slave = kzalloc(sizeof(*slave), gfp);
 129        if (!slave)
 130                return NULL;
 131
 132        INIT_LIST_HEAD(&slave->addresses);
 133        return slave;
 134}
 135
 136#endif /* __ARCH_POWERPC_ASM_FSLDMA_H__ */
 137