fsldma.h 3.8 KB

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