fsldma.h 3.8 KB

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