Skip to content

Xilinx dma.c

Function dma_read(struct xilinx_dma_chan *chan, u32 reg)

dma_read: The function of dma_read is to read a 32-bit value from a specified register of a Xilinx DMA channel.

parameters: The parameters of this Function. · parameter1: chan - A pointer to a struct xilinx_dma_chan, which represents the DMA channel from which the register will be read. · parameter2: reg - A 32-bit unsigned integer that specifies the offset of the register to be read from the DMA channel's device registers.

Code Description: The dma_read function is defined as a static inline function, which means it is intended to be used only within the file it is defined in and may be optimized by the compiler for performance. The function takes two parameters: a pointer to a xilinx_dma_chan structure and a register offset. It calculates the address of the register by adding the provided offset (reg) to the base address of the device's registers (chan->xdev->regs). The function then calls ioread32, which is a standard function used in Linux kernel programming to read a 32-bit value from a specific memory-mapped I/O address. The result of this read operation is returned as a 32-bit unsigned integer.

Note: It is important to ensure that the provided register offset is valid and that the DMA channel is properly initialized before calling this function to avoid undefined behavior or access violations.

Output Example: If the register at the specified offset contains the value 0x000000FF, the function will return 255 as a 32-bit unsigned integer.

graph TD
    A[Start dma_read function] --> B[Receive channel and register parameters]
    B --> C[Calculate address by adding register offset to device's register base]
    C --> D[Read value from calculated address using ioread32]
    D --> E[Return read value]
    E --> F[End dma_read function]

Function dma_write(struct xilinx_dma_chan *chan, u32 reg, u32 value)

dma_write: The function of dma_write is to write a specified value to a specific register of a DMA channel.

parameters: The parameters of this Function. · parameter1: struct xilinx_dma_chan *chan - A pointer to the DMA channel structure that contains the device context and register information. · parameter2: u32 reg - The offset of the register within the device's register space where the value will be written. · parameter3: u32 value - The value to be written to the specified register.

Code Description: The dma_write function is defined as a static inline function, which means it is intended for use only within the file it is defined in and may be optimized by the compiler for performance. The function takes three parameters: a pointer to a xilinx_dma_chan structure, a register offset, and a value to write.

Within the function, the iowrite32 function is called, which is responsible for writing a 32-bit value to a specific memory-mapped I/O address. The address is calculated by adding the register offset (reg) to the base address of the device's registers (chan->xdev->regs). This operation effectively writes the specified value to the desired register of the DMA channel, allowing for configuration or control of the DMA operation.

The use of iowrite32 indicates that this function is intended for environments where direct memory access to hardware registers is required, typical in low-level device driver development.

Note: It is important to ensure that the DMA channel is properly initialized before calling this function, as writing to uninitialized or incorrect registers may lead to undefined behavior or hardware malfunctions. Additionally, the function should be used in a context where the memory-mapped I/O is accessible and the system is in a suitable state for such operations.

graph TD
    A[Start dma_write function] --> B[Receive parameters: chan, reg, value]
    B --> C[Calculate address: chan->xdev->regs + reg]
    C --> D[Write value to calculated address using iowrite32]
    D --> E[End dma_write function]

Function vdma_desc_write(struct xilinx_dma_chan *chan, u32 reg,

               u32 value)

vdma_desc_write: The function of vdma_desc_write is to write a value to a specific register offset in the DMA channel descriptor.

parameters: The parameters of this Function. · parameter1: struct xilinx_dma_chan *chan - A pointer to the DMA channel structure that contains the descriptor offset and other channel-specific information.
· parameter2: u32 reg - The register offset from the descriptor base address where the value will be written.
· parameter3: u32 value - The value to be written to the specified register.

Code Description: The vdma_desc_write function is defined as a static inline function, which means it is intended for use only within the file it is defined in and may be optimized by the compiler for performance. The function takes three parameters: a pointer to a xilinx_dma_chan structure, a register offset, and a value to write.

Inside the function, the dma_write function is called, which is responsible for performing the actual write operation to the hardware register. The address to which the value is written is calculated by adding the descriptor offset (chan->desc_offset) to the provided register offset (reg). This allows the function to target specific registers within the DMA channel's descriptor space, facilitating configuration or control of the DMA operation.

The use of the inline keyword suggests that this function is small and frequently called, allowing the compiler to insert the function's code directly at the call site, potentially improving performance by reducing function call overhead.

Note: When using this function, ensure that the chan pointer is valid and points to a properly initialized xilinx_dma_chan structure. Additionally, the reg parameter should correspond to a valid register offset within the descriptor space to avoid unintended behavior.

graph TD
    A[Start] --> B[Receive channel object]
    B --> C[Receive register offset]
    C --> D[Receive value to write]
    D --> E[Calculate address using channel descriptor offset]
    E --> F[Write value to calculated address]
    F --> G[End]

Function dma_ctrl_read(struct xilinx_dma_chan *chan, u32 reg)

dma_ctrl_read: The function of dma_ctrl_read is to read a value from a specific control register of a Xilinx DMA channel.

parameters: The parameters of this Function. · parameter1: struct xilinx_dma_chan *chan - A pointer to the DMA channel structure that contains information about the channel, including its control register offset. · parameter2: u32 reg - The specific register offset to read from, relative to the control register base address.

Code Description: The dma_ctrl_read function is defined as a static inline function, which means it is intended to be used only within the file it is defined in and can be optimized by the compiler for performance. The function takes two parameters: a pointer to a xilinx_dma_chan structure and a register offset. It computes the absolute address of the control register by adding the control offset (chan->ctrl_offset) to the provided register offset (reg). The function then calls another function, dma_read, passing it the channel pointer and the computed address. The dma_read function is responsible for performing the actual read operation from the specified address and returning the value read from the control register.

This function is crucial for interacting with the hardware registers of the Xilinx DMA controller, allowing the software to retrieve the current state or configuration of the DMA channel.

Note: When using this function, ensure that the channel pointer is valid and properly initialized. Accessing an invalid memory address may lead to undefined behavior or system crashes.

Output Example: If the control register at the computed address contains the value 0x00000001, the function will return this value as a 32-bit unsigned integer (u32).

graph TD
    A[Start dma_ctrl_read function] --> B[Receive channel and register parameters]
    B --> C[Calculate control register address]
    C --> D[Call dma_read function with calculated address]
    D --> E[Return result from dma_read]
    E --> F[End dma_ctrl_read function]

Function dma_ctrl_write(struct xilinx_dma_chan *chan, u32 reg,

               u32 value)

dma_ctrl_write: The function of dma_ctrl_write is to write a value to a specified control register of a DMA channel.

parameters: The parameters of this Function. · chan: A pointer to a struct xilinx_dma_chan that represents the DMA channel to which the control register belongs.
· reg: An unsigned 32-bit integer that specifies the offset of the control register within the channel's control space.
· value: An unsigned 32-bit integer that represents the value to be written to the specified control register.

Code Description: The dma_ctrl_write function is defined as a static inline function, which means it is intended for use only within the file it is defined in and may be optimized by the compiler for performance. The function takes three parameters: a pointer to a xilinx_dma_chan structure, an offset register value, and the value to be written.

Inside the function, the dma_write function is called, which performs the actual write operation. The address to which the value is written is calculated by adding the control offset (chan->ctrl_offset) to the provided register offset (reg). This allows the function to target specific control registers dynamically based on the channel and the register offset provided. The value is then written to this calculated address, effectively updating the control register of the DMA channel with the new value.

Note: It is important to ensure that the chan parameter is valid and properly initialized before calling this function. Additionally, the reg parameter should correspond to a valid control register offset for the specific DMA channel to avoid unintended behavior.

graph TD
    A[Start dma_ctrl_write function] --> B[Receive parameters: chan, reg, value]
    B --> C[Calculate address using chan->ctrl_offset + reg]
    C --> D[Call dma_write function with parameters: chan, calculated address, value]
    D --> E[End dma_ctrl_write function]

Function dma_ctrl_clr(struct xilinx_dma_chan *chan, u32 reg,

             u32 clr)

dma_ctrl_clr: The function of dma_ctrl_clr is to clear specific bits in a DMA control register for a given DMA channel.

parameters: The parameters of this Function. · parameter1: struct xilinx_dma_chan *chan - A pointer to the DMA channel structure that contains the channel-specific information. · parameter2: u32 reg - The register address that is to be modified. · parameter3: u32 clr - A bitmask indicating which bits in the register should be cleared.

Code Description: The dma_ctrl_clr function is defined as a static inline function, which means it is intended for use only within the file it is defined in and may be optimized by the compiler for performance. The function takes three parameters: a pointer to a xilinx_dma_chan structure, a register address, and a bitmask.

The function first reads the current value of the specified register by calling dma_ctrl_read with the channel pointer and the register address. It then applies a bitwise AND operation with the negation of the clr parameter. This operation effectively clears the bits specified by the clr mask in the register value. The result is then written back to the register using the dma_ctrl_write function.

This operation is crucial for managing the state of the DMA controller, allowing specific control bits to be reset without affecting the other bits in the register.

Note: It is important to ensure that the clr parameter accurately represents the bits intended to be cleared, as incorrect usage may lead to unintended behavior of the DMA controller. Additionally, this function should be used in contexts where the DMA channel is properly initialized and configured to avoid accessing invalid memory or registers.

graph TD
    A[Start] --> B[Receive channel object]
    B --> C[Receive register address]
    C --> D[Receive clear mask]
    D --> E[Read current value from register]
    E --> F[Apply clear mask to current value]
    F --> G[Write updated value back to register]
    G --> H[End]

Function dma_ctrl_set(struct xilinx_dma_chan *chan, u32 reg,

             u32 set)

dma_ctrl_set: The function of dma_ctrl_set is to set specific bits in a DMA control register for a given DMA channel.

parameters: The parameters of this Function. · parameter1: struct xilinx_dma_chan *chan - A pointer to the DMA channel structure that specifies which DMA channel's control register is being modified. · parameter2: u32 reg - The specific control register address that needs to be accessed. · parameter3: u32 set - The bitmask representing the bits to be set in the control register.

Code Description: The dma_ctrl_set function is defined as a static inline function, which means it is intended for use only within the file it is defined in and may be optimized by the compiler for performance. The function takes three parameters: a pointer to a xilinx_dma_chan structure, a register address, and a bitmask.

The function first reads the current value of the specified control register using the dma_ctrl_read function. It then applies a bitwise OR operation between the current value and the provided bitmask (set). This operation effectively sets the bits specified in the bitmask while leaving the other bits unchanged. Finally, the modified value is written back to the control register using the dma_ctrl_write function.

This approach allows for selective modification of the control register without affecting other bits, which is crucial for maintaining the proper operation of the DMA channel.

Note: It is important to ensure that the provided register address and bitmask are valid for the specific DMA channel being modified. Incorrect usage may lead to unintended behavior or hardware malfunctions. Additionally, this function should be used in contexts where concurrent access to the DMA control registers is properly managed to avoid race conditions.

graph TD
    A[Start] --> B[Receive channel object]
    B --> C[Receive register value]
    C --> D[Receive set value]
    D --> E[Read current value from register]
    E --> F[Perform bitwise OR with set value]
    F --> G[Write updated value back to register]
    G --> H[End]

Function vdma_desc_write_64(struct xilinx_dma_chan *chan, u32 reg,

                  u32 value_lsb,  u32 value_msb)

vdma_desc_write_64: The function of vdma_desc_write_64 is to write a 64-bit value to a specified register of a Xilinx DMA channel.

parameters: The parameters of this Function. · parameter1: struct xilinx_dma_chan *chan - A pointer to the DMA channel structure that contains the device context and register offsets. · parameter2: u32 reg - The register offset within the DMA channel to which the value will be written. · parameter3: u32 value_lsb - The least significant 32 bits of the 64-bit value to be written. · parameter4: u32 value_msb - The most significant 32 bits of the 64-bit value to be written.

Code Description: The vdma_desc_write_64 function is designed to facilitate the writing of a 64-bit value to a specific register of a Xilinx DMA channel. It takes four parameters: a pointer to the DMA channel structure, the register offset, and the least and most significant parts of the 64-bit value to be written.

The function operates as follows: 1. It first writes the least significant 32 bits (value_lsb) to the specified register by calculating the address using the base address of the device's registers (chan->xdev->regs), the channel's descriptor offset (chan->desc_offset), and the provided register offset (reg). The writel function is used for this operation, which is typically a macro or function that performs a write operation to a memory-mapped register.

  1. Next, it writes the most significant 32 bits (value_msb) to the same register, but at an offset of 4 bytes from the initial register address. This is done to ensure that the 64-bit value is correctly written across two 32-bit registers, as many hardware architectures require separate writes for higher and lower parts of a 64-bit value.

This function is marked as static inline, indicating that it is intended for use only within the file it is defined in and that the compiler may choose to inline the function to optimize performance.

Note: When using this function, it is essential to ensure that the DMA channel is properly initialized and that the register offsets are correctly defined. Additionally, care should be taken to ensure that the values being written do not exceed the expected range for the specific hardware implementation.

graph TD
    A[Start vdma_desc_write_64 function] --> B[Write lsb 32 bits]
    B --> C[Calculate address for lsb]
    C --> D[Call writel function with lsb value]
    D --> E[Write msb 32 bits]
    E --> F[Calculate address for msb]
    F --> G[Call writel function with msb value]
    G --> H[End vdma_desc_write_64 function]

Function dma_writeq(struct xilinx_dma_chan *chan, u32 reg, u64 value)

dma_writeq: The function of dma_writeq is to write a 64-bit value to a specified register of a Xilinx DMA channel.

parameters: The parameters of this Function. · parameter1: struct xilinx_dma_chan *chan - A pointer to the DMA channel structure that contains channel-specific information and device context. · parameter2: u32 reg - The offset of the register within the DMA channel's control space where the value will be written. · parameter3: u64 value - The 64-bit value that will be written to the specified register.

Code Description: The dma_writeq function is defined as a static inline function, which means it is intended to be used only within the file it is defined in and can be optimized by the compiler for performance. The function takes three parameters: a pointer to a xilinx_dma_chan structure, a register offset, and a 64-bit value.

Inside the function, the lo_hi_writeq function is called, which is responsible for writing the 64-bit value to the appropriate register. The address of the register is calculated by adding the base address of the DMA device's registers (chan->xdev->regs) to the control offset of the channel (chan->ctrl_offset) and the specified register offset (reg). This calculation ensures that the correct memory-mapped I/O address is targeted for the write operation.

The use of lo_hi_writeq indicates that the function is likely designed to handle writing 64-bit values in a way that respects the architecture's requirements for accessing high and low parts of the data, ensuring that the operation is performed correctly on hardware that may have specific requirements for 64-bit writes.

Note: It is important to ensure that the DMA channel is properly initialized and that the register offsets are valid before calling this function. Incorrect usage may lead to undefined behavior or hardware malfunctions. Additionally, this function should be used in contexts where atomicity of the write operation is guaranteed, as concurrent access to the same register may lead to race conditions.

graph TD
    A[Start dma_writeq function] --> B[Receive parameters: chan, reg, value]
    B --> C[Calculate address using chan->xdev->regs, chan->ctrl_offset, and reg]
    C --> D[Call lo_hi_writeq with value and calculated address]
    D --> E[End dma_writeq function]

Function xilinx_write(struct xilinx_dma_chan *chan, u32 reg,

            dma_addr_t addr)

xilinx_write: The function of xilinx_write is to write data to a specified register of a Xilinx DMA channel.

parameters: The parameters of this Function. · chan: A pointer to a struct xilinx_dma_chan that represents the DMA channel to which the write operation is directed.
· reg: An unsigned 32-bit integer that specifies the register address to which the data will be written.
· addr: A dma_addr_t type variable that holds the address of the data to be written to the specified register.

Code Description: The xilinx_write function is defined as a static inline function, which means it is intended to be used only within the file it is defined in and can be optimized by the compiler for performance. The function takes three parameters: a pointer to a xilinx_dma_chan structure, a register address, and a data address.

The function first checks the ext_addr field of the provided channel structure (chan). If ext_addr is true (non-zero), it indicates that the DMA channel is configured to use an external address for the write operation. In this case, the function calls dma_writeq, passing the channel, the register, and the address as arguments. The dma_writeq function is responsible for writing a 64-bit value to the specified register at the external address.

If ext_addr is false (zero), the function instead calls dma_ctrl_write, which writes to the register using the internal control mechanism of the DMA channel. This allows for flexibility in handling different configurations of the DMA channel, depending on whether it is using an external address or not.

Note: It is important to ensure that the channel structure is properly initialized before calling this function. Additionally, the correct register and address values should be provided to avoid unintended behavior during the write operation. The use of this function should be aligned with the overall DMA configuration and operation to ensure data integrity and proper functionality.

graph TD
    A[Start xilinx_write function] --> B[Check if chan->ext_addr is true]
    B -->|Yes| C[Call dma_writeq with chan, reg, addr]
    B -->|No| D[Call dma_ctrl_write with chan, reg, addr]
    C --> E[End xilinx_write function]
    D --> E

Function xilinx_axidma_buf(struct xilinx_dma_chan *chan,

                 struct xilinx_axidma_desc_hw *hw, 
                 dma_addr_t buf_addr,  size_t sg_used, 
                 size_t period_len)

xilinx_axidma_buf: The function of xilinx_axidma_buf is to set the buffer address in the hardware descriptor based on the DMA channel configuration and the provided buffer address.

parameters: The parameters of this Function. · chan: A pointer to the xilinx_dma_chan structure representing the DMA channel being used. · hw: A pointer to the xilinx_axidma_desc_hw structure where the buffer address will be stored. · buf_addr: The base address of the buffer in memory. · sg_used: The size of the scatter-gather list that has been used. · period_len: The length of the current period being processed.

Code Description: The xilinx_axidma_buf function is defined as a static inline function, which means it is intended to be used only within the file it is defined in and can be optimized by the compiler for performance. The function takes in a DMA channel structure, a hardware descriptor structure, a buffer address, the size of the scatter-gather list used, and the length of the current processing period.

The function first checks if the DMA channel has an external address (chan->ext_addr). If this condition is true, it calculates the lower and upper 32 bits of the buffer address by adding the sg_used and period_len to the buf_addr. This is done using the helper functions lower_32_bits and upper_32_bits, which extract the respective parts of the address. The calculated values are then assigned to hw->buf_addr and hw->buf_addr_msb.

If the DMA channel does not have an external address, the function simply assigns the sum of buf_addr, sg_used, and period_len directly to hw->buf_addr. This approach ensures that the buffer address is correctly set in the hardware descriptor based on the configuration of the DMA channel.

Note: It is important to ensure that the chan and hw pointers are valid before calling this function to avoid dereferencing null or invalid pointers. Additionally, the function assumes that the buffer address calculations do not exceed the addressable memory range.

graph TD
    A[Start] --> B[Check if channel has external address]
    B -->|Yes| C[Calculate lower 32 bits of buffer address]
    C --> D[Store lower 32 bits in hw->buf_addr]
    D --> E[Calculate upper 32 bits of buffer address]
    E --> F[Store upper 32 bits in hw->buf_addr_msb]
    B -->|No| G[Calculate buffer address]
    G --> H[Store buffer address in hw->buf_addr]
    F --> I[End]
    H --> I

Function xilinx_dma_clean_hw_desc(struct xilinx_axidma_desc_hw *hw)

xilinx_dma_clean_hw_desc: The function of xilinx_dma_clean_hw_desc is to reset the hardware descriptor structure while preserving specific fields.

parameters: The parameters of this Function. · hw: A pointer to a struct xilinx_axidma_desc_hw that represents the hardware descriptor to be cleaned.

Code Description: The xilinx_dma_clean_hw_desc function is designed to reset the contents of a hardware descriptor structure of type xilinx_axidma_desc_hw. The function begins by storing the values of the next_desc and next_desc_msb fields from the hw structure into local variables. This is done to ensure that these specific fields are preserved during the cleaning process.

Next, the function utilizes the memset function to set all bytes of the hw structure to zero. This effectively clears all fields within the structure, preparing it for a fresh state. After the memset operation, the function restores the original values of next_desc and next_desc_msb back into the hw structure. This ensures that while the rest of the fields are reset, the next descriptor pointers remain intact, which is crucial for maintaining the integrity of the descriptor chain in DMA operations.

Note: It is important to ensure that the hw parameter passed to this function is a valid pointer to a properly allocated xilinx_axidma_desc_hw structure. Additionally, this function should be used with caution in contexts where the next_desc and next_desc_msb fields are critical for ongoing DMA operations, as improper usage may lead to inconsistencies in the descriptor chain.

graph TD
    A[Start] --> B[Retrieve next_desc from hw]
    B --> C[Retrieve next_desc_msb from hw]
    C --> D[Clear hw structure using memset]
    D --> E[Set hw.next_desc to next_desc]
    E --> F[Set hw.next_desc_msb to next_desc_msb]
    F --> G[End]

Function xilinx_dma_free_tx_segment(struct xilinx_dma_chan *chan,

            struct xilinx_axidma_tx_segment *segment)

xilinx_dma_free_tx_segment: The function of xilinx_dma_free_tx_segment is to free a transmission segment and add it back to the channel's free segment list.

parameters: The parameters of this Function. · chan: A pointer to the xilinx_dma_chan structure representing the DMA channel from which the transmission segment is being freed. · segment: A pointer to the xilinx_axidma_tx_segment structure that represents the transmission segment to be freed.

Code Description: The xilinx_dma_free_tx_segment function is designed to handle the deallocation of a transmission segment within a Xilinx DMA channel. It first calls the function xilinx_dma_clean_hw_desc, passing the hardware descriptor associated with the segment. This step is crucial as it ensures that any resources or states associated with the hardware descriptor are properly cleaned up before the segment is returned to the free list.

After cleaning up the hardware descriptor, the function utilizes the list_add_tail function to append the segment's node to the channel's free segment list. This operation effectively marks the segment as available for future use, allowing the DMA channel to reuse it for subsequent transmission tasks. The use of list_add_tail ensures that the segment is added at the end of the list, maintaining the order of free segments.

Note: It is important to ensure that the segment being freed is valid and has been properly initialized before calling this function. Additionally, care should be taken to avoid accessing the segment after it has been freed, as this could lead to undefined behavior.

graph TD
    A[Start xilinx_dma_free_tx_segment] --> B[Receive channel and segment parameters]
    B --> C[Clean hardware descriptor of segment]
    C --> D[Add segment to free segment list of channel]
    D --> E[End xilinx_dma_free_tx_segment]

Function xilinx_cdma_free_tx_segment(struct xilinx_dma_chan *chan,

            struct xilinx_cdma_tx_segment *segment)

xilinx_cdma_free_tx_segment: The function of xilinx_cdma_free_tx_segment is to free a transmission segment associated with a given DMA channel.

parameters: The parameters of this Function. · parameter1: struct xilinx_dma_chan chan - A pointer to the DMA channel structure that contains the descriptor pool from which the segment was allocated. · parameter2: struct xilinx_cdma_tx_segment segment - A pointer to the transmission segment that is to be freed.

Code Description: The xilinx_cdma_free_tx_segment function is designed to release a previously allocated transmission segment back to the DMA channel's descriptor pool. It takes two parameters: a pointer to the DMA channel structure (chan) and a pointer to the transmission segment (segment). The function utilizes the dma_pool_free function to perform the deallocation. The dma_pool_free function is called with three arguments: the descriptor pool associated with the DMA channel (chan->desc_pool), the segment to be freed (segment), and the physical address of the segment (segment->phys). By doing this, the function ensures that the resources allocated for the transmission segment are properly released, preventing memory leaks and ensuring efficient memory management within the DMA subsystem.

Note: It is important to ensure that the segment being freed was previously allocated from the same descriptor pool to avoid undefined behavior. Additionally, this function should only be called after the transmission segment is no longer in use to prevent access violations.

graph TD
    A[Start] --> B[Receive channel and segment]
    B --> C[Free DMA memory]
    C --> D[Return to caller]
    D --> E[End]

Function xilinx_vdma_free_tx_segment(struct xilinx_dma_chan *chan,

                struct xilinx_vdma_tx_segment *segment)

xilinx_vdma_free_tx_segment: The function of xilinx_vdma_free_tx_segment is to free a transmission segment from the DMA descriptor pool.

parameters: The parameters of this Function. · parameter1: struct xilinx_dma_chan chan - A pointer to the DMA channel structure that contains information about the DMA channel, including the descriptor pool from which the segment was allocated. · parameter2: struct xilinx_vdma_tx_segment segment - A pointer to the transmission segment that needs to be freed, which includes the physical address used for freeing the memory.

Code Description: The xilinx_vdma_free_tx_segment function is a static function designed to release a previously allocated transmission segment back to the DMA descriptor pool. It takes two parameters: a pointer to the DMA channel structure (chan) and a pointer to the transmission segment (segment) that is to be freed.

Within the function, the dma_pool_free function is called, which is responsible for deallocating the memory associated with the transmission segment. The first argument to dma_pool_free is the descriptor pool associated with the DMA channel (chan->desc_pool), which indicates where the memory should be returned. The second argument is the segment pointer, which points to the memory that is to be freed. The third argument is segment->phys, which provides the physical address of the segment that was allocated earlier. This ensures that the correct memory is released back to the pool.

This function is essential for managing memory efficiently in a DMA context, as it helps prevent memory leaks by ensuring that allocated segments are returned to the pool when they are no longer needed.

Note: It is important to ensure that the segment being freed was previously allocated from the same descriptor pool to avoid undefined behavior. Additionally, this function should only be called when the segment is no longer in use to prevent access violations or data corruption.

graph TD
    A[Start] --> B[Receive channel and segment]
    B --> C[Free DMA memory]
    C --> D[Call dma_pool_free function]
    D --> E[Pass channel descriptor pool]
    D --> F[Pass segment pointer]
    D --> G[Pass segment physical address]
    E --> H[Memory freed]
    F --> H
    G --> H
    H --> I[End]

Function xilinx_dma_free_tx_descriptor(struct xilinx_dma_chan *chan,

               struct xilinx_dma_tx_descriptor *desc)

xilinx_dma_free_tx_descriptor: The function of xilinx_dma_free_tx_descriptor is to free the transmission descriptors associated with a given DMA channel.

parameters: The parameters of this Function. · parameter1: struct xilinx_dma_chan chan - A pointer to the DMA channel structure that contains the configuration and state of the DMA channel. · parameter2: struct xilinx_dma_tx_descriptor desc - A pointer to the transmission descriptor that needs to be freed.

Code Description: The xilinx_dma_free_tx_descriptor function is responsible for releasing the resources associated with a transmission descriptor in a DMA channel. It first checks if the provided descriptor pointer desc is valid (not NULL). If it is NULL, the function returns immediately without performing any operations.

The function then determines the type of DMA configuration associated with the channel by accessing chan->xdev->dma_config->dmatype. Based on the DMA type, it processes the segments linked to the descriptor:

  1. If the DMA type is XDMA_TYPE_VDMA, the function iterates through the list of segments in the descriptor using list_for_each_entry_safe. For each segment, it removes the segment from the list using list_del and calls xilinx_vdma_free_tx_segment to free the resources allocated for that segment.

  2. If the DMA type is XDMA_TYPE_CDMA, a similar process is followed where it iterates through the segments and calls xilinx_cdma_free_tx_segment for each segment.

  3. For any other DMA type (assumed to be XDMA_TYPE_AXIDMA), the function iterates through the segments and calls xilinx_dma_free_tx_segment for each segment.

After all segments have been processed and freed, the function finally releases the memory allocated for the descriptor itself by calling kfree(desc).

Note: It is important to ensure that the descriptor passed to this function is valid and that it has been properly initialized before calling this function. Failure to do so may lead to undefined behavior or memory leaks.

Output Example: The function does not return a value; it performs memory deallocation and thus does not produce a return output. However, upon successful execution, the memory associated with the descriptor and its segments will be freed, and any subsequent access to the freed descriptor or segments should be avoided.

graph TD
    A[Start] --> B[Check if descriptor is null]
    B -->|Yes| C[Return]
    B -->|No| D[Check DMA type]
    D -->|VDMA| E[Iterate through VDMA segments]
    D -->|CDMA| G[Iterate through CDMA segments]
    D -->|AXIDMA| I[Iterate through AXIDMA segments]

    E --> F[Delete segment node]
    F --> H[Free VDMA segment]
    H --> E

    G --> J[Delete CDMA segment node]
    J --> L[Free CDMA segment]
    L --> G

    I --> M[Delete AXIDMA segment node]
    M --> O[Free AXIDMA segment]
    O --> I

    E --> P[Check if more segments]
    G --> P
    I --> P
    P -->|Yes| E
    P -->|No| Q[Free descriptor]
    Q --> R[End]

Function xilinx_dma_free_desc_list(struct xilinx_dma_chan *chan,

                struct list_head *list)

xilinx_dma_free_desc_list: The function of xilinx_dma_free_desc_list is to free a list of DMA transaction descriptors associated with a given DMA channel.

parameters: The parameters of this Function. · parameter1: struct xilinx_dma_chan chan - A pointer to the DMA channel structure that owns the descriptors to be freed. · parameter2: struct list_head list - A pointer to the head of the list containing the transaction descriptors to be freed.

Code Description: The xilinx_dma_free_desc_list function iterates through a linked list of transaction descriptors, safely removing each descriptor from the list and freeing its associated resources. The function uses the list_for_each_entry_safe macro to traverse the list, which allows for safe deletion of the current entry while still being able to access the next entry. For each descriptor in the list, the function performs the following actions: 1. It retrieves the current descriptor (desc) and the next descriptor (next) in the list. 2. It removes the current descriptor from the list using the list_del function, which updates the linked list pointers to exclude the current descriptor. 3. It calls the xilinx_dma_free_tx_descriptor function, passing the DMA channel and the current descriptor as arguments, to release any resources allocated for that descriptor.

This ensures that all descriptors in the list are properly freed, preventing memory leaks and ensuring that the DMA channel can operate without stale or dangling references to previously allocated descriptors.

Note: It is important to ensure that the list passed to this function is not empty and that the descriptors have been properly initialized before calling this function. Additionally, this function should be called when the descriptors are no longer needed, typically during cleanup or deallocation processes.

graph TD
    A[Start] --> B[Receive channel and list]
    B --> C[Initialize descriptor and next pointers]
    C --> D[Iterate through list with safe entry]
    D --> E[Delete current descriptor from list]
    E --> F[Free current transaction descriptor]
    F --> D
    D --> G[End of list reached]
    G --> H[Finish processing]
    H --> I[Return to caller]

Function xilinx_dma_free_descriptors(struct xilinx_dma_chan *chan)

xilinx_dma_free_descriptors: The function of xilinx_dma_free_descriptors is to free the DMA descriptors associated with a given DMA channel.

parameters: The parameters of this Function. · chan: A pointer to a struct xilinx_dma_chan that represents the DMA channel whose descriptors are to be freed.

Code Description: The xilinx_dma_free_descriptors function is designed to manage the cleanup of DMA descriptors for a specified DMA channel. It begins by declaring a variable flags to hold the state of interrupt flags. The function then acquires a spinlock using spin_lock_irqsave, which locks the channel's lock and saves the current state of interrupts in flags. This is crucial for ensuring thread safety and preventing race conditions while the descriptors are being freed.

Once the lock is acquired, the function calls xilinx_dma_free_desc_list three times, passing the channel pointer and three different lists of descriptors: pending_list, done_list, and active_list. Each of these lists represents a different state of DMA transactions, and the function is responsible for releasing the memory associated with each of these lists to avoid memory leaks.

After the descriptor lists have been freed, the function releases the spinlock using spin_unlock_irqrestore, which restores the previous state of interrupts stored in flags. This ensures that the system's interrupt handling is returned to its prior state, maintaining the integrity of the system.

Note: It is important to ensure that this function is called in a context where the DMA channel is no longer in use, as freeing descriptors while they are still active could lead to undefined behavior or system instability. Proper synchronization mechanisms should be in place to guarantee that no other operations are accessing the descriptor lists during the cleanup process.

graph TD
    A[Start xilinx_dma_free_descriptors] --> B[Save current interrupt flags]
    B --> C[Acquire lock on channel]
    C --> D[Free pending descriptors]
    D --> E[Free done descriptors]
    E --> F[Free active descriptors]
    F --> G[Release lock on channel]
    G --> H[End xilinx_dma_free_descriptors]

Function xilinx_dma_free_chan_resources(struct dma_chan *dchan)

xilinx_dma_free_chan_resources: The function of xilinx_dma_free_chan_resources is to release all resources associated with a specified DMA channel.

parameters: The parameters of this Function. · dchan: A pointer to the dma_chan structure representing the DMA channel whose resources are to be freed.

Code Description: The xilinx_dma_free_chan_resources function is designed to clean up and free all resources allocated for a specific DMA channel. It begins by converting the generic dma_chan pointer to a xilinx_dma_chan pointer, which provides access to the specific channel's properties and resources.

The function first logs a debug message indicating that it is freeing all channel resources. It then calls xilinx_dma_free_descriptors to free any descriptors associated with the channel.

Next, the function checks the type of DMA configuration associated with the channel. If the DMA type is XDMA_TYPE_AXIDMA, it proceeds to lock the channel's spinlock to ensure thread safety while manipulating the free segment list. It initializes the free segment list to an empty state and then unlocks the spinlock.

Following this, the function frees memory allocated for the buffer descriptors (BD) using dma_free_coherent, which releases the coherent memory allocated for the channel's segment vector and its physical address. It also frees memory allocated for cyclic DMA mode, ensuring that all resources are properly released.

If the DMA type is not XDMA_TYPE_AXIDMA, the function destroys the descriptor pool associated with the channel using dma_pool_destroy, and sets the descriptor pool pointer to NULL to avoid dangling references.

Note: It is important to ensure that this function is called when a DMA channel is no longer needed to prevent memory leaks. Additionally, the function assumes that the caller has already ensured that no operations are pending on the channel before freeing its resources.

graph TD
    A[Start xilinx_dma_free_chan_resources] --> B[Get xilinx_dma_chan from dma_chan]
    B --> C[Log message Free all channel resources]
    C --> D[Call xilinx_dma_free_descriptors]
    D --> E{Check dmatype}
    E -->|AXIDMA| F[Acquire lock with spin_lock_irqsave]
    F --> G[Initialize free_seg_list]
    G --> H[Release lock with spin_unlock_irqrestore]
    H --> I[Free memory for BD using dma_free_coherent]
    I --> J[Free memory for cyclic DMA Mode using dma_free_coherent]
    E -->|Not AXIDMA| K[Destroy desc_pool using dma_pool_destroy]
    K --> L[Set desc_pool to NULL]
    J --> M[End xilinx_dma_free_chan_resources]
    L --> M

Function xilinx_dma_chan_handle_cyclic(struct xilinx_dma_chan *chan,

                  struct xilinx_dma_tx_descriptor *desc, 
                  unsigned long *flags)

xilinx_dma_chan_handle_cyclic: The function of xilinx_dma_chan_handle_cyclic is to handle the callback for a cyclic DMA transfer on a specified DMA channel.

parameters: The parameters of this Function. · chan: A pointer to the xilinx_dma_chan structure representing the DMA channel that is being handled.
· desc: A pointer to the xilinx_dma_tx_descriptor structure that contains the details of the DMA transaction, including the callback function.
· flags: A pointer to an unsigned long variable that holds the interrupt flags for the spinlock, ensuring thread safety during the callback execution.

Code Description: The xilinx_dma_chan_handle_cyclic function is designed to manage the callback mechanism associated with cyclic DMA transfers. It first retrieves the callback function and its associated parameter from the provided transaction descriptor (desc). If a callback function is defined (i.e., not NULL), the function proceeds to release the spinlock associated with the DMA channel (chan) using the flags provided. This is crucial as it allows other processes or interrupts to access the DMA channel while the callback is being executed. After invoking the callback with the specified parameter, the function re-acquires the spinlock to maintain synchronization and protect the DMA channel from concurrent access. This ensures that the critical section of code is executed safely, preventing race conditions or data corruption.

Note: It is important to ensure that the callback function is properly defined before invoking this function to avoid dereferencing a NULL pointer. Additionally, the flags must be correctly set prior to calling this function to maintain the integrity of the spinlock mechanism.

graph TD
    A[Start xilinx_dma_chan_handle_cyclic] --> B[Retrieve callback from descriptor]
    B --> C[Retrieve callback parameter from descriptor]
    C --> D{Is callback defined?}
    D -- Yes --> E[Unlock channel lock with flags]
    E --> F[Execute callback with callback parameter]
    F --> G[Lock channel lock with flags]
    D -- No --> G
    G --> H[End xilinx_dma_chan_handle_cyclic]

Function xilinx_dma_chan_desc_cleanup(struct xilinx_dma_chan *chan)

xilinx_dma_chan_desc_cleanup: The function of xilinx_dma_chan_desc_cleanup is to clean up and free DMA transaction descriptors associated with a given DMA channel.

parameters: The parameters of this Function. · chan: A pointer to the xilinx_dma_chan structure representing the DMA channel whose descriptors are to be cleaned up.

Code Description: The xilinx_dma_chan_desc_cleanup function is responsible for managing the cleanup process of DMA transaction descriptors that have been completed or are no longer needed for a specific DMA channel. The function begins by acquiring a spin lock to ensure thread safety while accessing shared resources. This is crucial in a concurrent environment where multiple threads may attempt to modify the same data structures.

The function then iterates over the list of completed descriptors (done_list) using the list_for_each_entry_safe macro, which allows safe removal of elements from the list during iteration. For each descriptor, the function checks if it is cyclic. If it is, the function calls xilinx_dma_chan_handle_cyclic to handle the cyclic descriptor appropriately and breaks out of the loop to prevent further processing of this descriptor.

If the descriptor is not cyclic, it is removed from the done_list using list_del. The function then retrieves the callback associated with the descriptor using dmaengine_desc_get_callback. If the callback is valid, the spin lock is released, and the callback is invoked. After invoking the callback, the spin lock is reacquired to maintain consistency in the shared data structures.

Following the callback invocation, any dependencies associated with the descriptor are run using dma_run_dependencies, ensuring that all related operations are completed. Finally, the descriptor is freed using xilinx_dma_free_tx_descriptor, which releases the resources allocated for the descriptor.

The function concludes by releasing the spin lock, ensuring that other threads can access the DMA channel's resources.

Note: It is important to ensure that this function is called in a context where it is safe to manipulate the DMA channel's descriptors. Proper locking mechanisms must be in place to prevent race conditions and ensure data integrity during the cleanup process.

graph TD
    A[Start xilinx_dma_chan_desc_cleanup] --> B[Acquire lock on channel]
    B --> C[Iterate through done_list with safe iteration]
    C --> D{Is descriptor cyclic?}
    D -- Yes --> E[Handle cyclic descriptor]
    E --> F[Break iteration]
    D -- No --> G[Remove descriptor from running transactions]
    G --> H[Get callback function from descriptor]
    H --> I{Is callback valid?}
    I -- Yes --> J[Unlock channel lock]
    J --> K[Invoke callback function]
    K --> L[Reacquire channel lock]
    I -- No --> L
    L --> M[Run dependencies for descriptor]
    M --> N[Free the descriptor]
    C --> O{More descriptors?}
    O -- Yes --> C
    O -- No --> P[Release channel lock]
    P --> Q[End xilinx_dma_chan_desc_cleanup]

Function xilinx_dma_do_tasklet(unsigned long data)

xilinx_dma_do_tasklet: The function of xilinx_dma_do_tasklet is to perform cleanup operations for a specified DMA channel descriptor.

parameters: The parameters of this Function. · parameter1: unsigned long data - This parameter is a pointer cast to an unsigned long, which represents the data associated with the DMA channel.

Code Description: The xilinx_dma_do_tasklet function is defined as a static function, meaning it has internal linkage and is only accessible within the file it is defined in. The function takes a single parameter, data, which is expected to be a pointer to a xilinx_dma_chan structure, cast to an unsigned long. Inside the function, this data is cast back to a pointer of type struct xilinx_dma_chan.

The function then calls xilinx_dma_chan_desc_cleanup(chan), where chan is the pointer to the DMA channel structure. This call is responsible for cleaning up any resources or descriptors associated with the specified DMA channel. The cleanup process is crucial for maintaining system stability and preventing resource leaks, especially in a DMA context where channels may be frequently allocated and deallocated.

Note: It is important to ensure that the data passed to this function is valid and correctly represents a xilinx_dma_chan structure. Improper usage may lead to undefined behavior or system crashes. Additionally, since this function is intended to be used as a tasklet, it should be scheduled appropriately within the kernel's tasklet framework to ensure it executes in the correct context.

graph TD
    A[Start xilinx_dma_do_tasklet] --> B[Cast data to xilinx_dma_chan pointer]
    B --> C[Call xilinx_dma_chan_desc_cleanup]
    C --> D[End xilinx_dma_do_tasklet]

Function xilinx_dma_alloc_chan_resources(struct dma_chan *dchan)

xilinx_dma_alloc_chan_resources: The function of xilinx_dma_alloc_chan_resources is to allocate resources for a DMA channel in the Xilinx DMA driver.

parameters: The parameters of this Function. · dchan: A pointer to the dma_chan structure representing the DMA channel for which resources are being allocated.

Code Description: The xilinx_dma_alloc_chan_resources function begins by converting the provided dma_chan pointer into a xilinx_dma_chan structure. It first checks if the channel has already been allocated resources by verifying if the descriptor pool (desc_pool) is non-null. If resources have already been allocated, the function returns 0, indicating success.

For channels configured as AXI DMA (XDMA_TYPE_AXIDMA), the function allocates a coherent memory buffer for the descriptor segments. This allocation is done using dma_zalloc_coherent, which ensures that the memory is zeroed and suitable for DMA operations. If the allocation fails, an error message is logged, and the function returns -ENOMEM to indicate memory allocation failure.

In addition to the main descriptor segment, the function allocates a separate segment for cyclic DMA mode, which is necessary for programming the tail descriptor register. Again, if this allocation fails, the function cleans up by freeing the previously allocated descriptor segment and returns -ENOMEM.

For other DMA types, such as CDMA (XDMA_TYPE_CDMA) and VDMA (XDMA_TYPE_VDMA), the function creates a DMA pool for descriptor allocation using dma_pool_create. If the descriptor pool creation fails for these types, an error message is logged, and the function returns -ENOMEM.

After successfully allocating the necessary resources, the function initializes the DMA cookie for the channel using dma_cookie_init. It also sets up interrupt handling for AXI DMA channels by configuring the DMA control register to enable all interrupts. If the channel supports scatter-gather mode (has_sg) and is of type CDMA, it configures the DMA control register to enable scatter-gather mode.

Finally, the function returns 0 to indicate successful allocation of channel resources.

Note: It is important to ensure that the DMA channel is not already allocated before calling this function, as it will return immediately without performing any operations if resources are already present. Additionally, proper error handling should be implemented to manage memory allocation failures.

Output Example: A successful call to xilinx_dma_alloc_chan_resources with a valid dchan pointer would return 0, indicating that the resources for the DMA channel have been successfully allocated. If the allocation fails due to insufficient memory, the function would return -ENOMEM, and an error message would be logged indicating the failure.

graph TD
    A[Start] --> B[Get channel from dma_chan]
    B --> C{Check if desc_pool is allocated}
    C -- Yes --> D[Return 0]
    C -- No --> E{Check dma_config dmatype}
    E -- AXI DMA --> F[Allocate buffer descriptors]
    F --> G{Check allocation success}
    G -- No --> H[Log error for descriptor allocation]
    H --> I[Return -ENOMEM]
    G -- Yes --> J[Allocate cyclic descriptor segment]
    J --> K{Check allocation success}
    K -- No --> L[Log error for cyclic descriptor allocation]
    L --> M[Free allocated descriptors]
    M --> I
    K -- Yes --> N[Set physical address for cyclic segment]
    N --> O[Initialize descriptor list]
    O --> P[Loop through descriptors]
    P --> Q[Set next descriptor pointers]
    Q --> R[Add to free segment list]
    R --> S[End Loop]
    E -- CDMA --> T[Create CDMA descriptor pool]
    E -- VDMA --> U[Create VDMA descriptor pool]
    T --> V{Check pool allocation success}
    U --> V
    V -- No --> W[Log error for descriptor pool allocation]
    W --> I
    V -- Yes --> X[Initialize dma_cookie]
    X --> Y{Check dma_config dmatype}
    Y -- AXI DMA --> Z[Enable interrupts]
    Y -- CDMA with sg --> AA[Set SG mode]
    AA --> AB[Return 0]
    Z --> AB
    AB --> AC[End]

Function xilinx_dma_tx_status(struct dma_chan *dchan,

                dma_cookie_t cookie, 
                struct dma_tx_state *txstate)

xilinx_dma_tx_status: The function of xilinx_dma_tx_status is to retrieve the transmission status of a DMA channel.

parameters: The parameters of this Function. · dchan: A pointer to the DMA channel structure for which the status is being queried.
· cookie: A unique identifier for the DMA transaction, used to track the status of the specific transfer.
· txstate: A pointer to a dma_tx_state structure that will be populated with the status information.

Code Description: The xilinx_dma_tx_status function begins by converting the provided DMA channel pointer (dchan) to a specific xilinx_dma_chan structure. It then initializes several local variables, including a pointer for the transmission descriptor, a pointer for the transmission segment, a pointer for the hardware descriptor, and an enumeration for the return status. The function also initializes a variable to hold the residue value, which indicates the amount of data remaining to be transferred.

The function first calls dma_cookie_status to check the status of the DMA transaction identified by the provided cookie. If the transaction is complete or if the txstate pointer is null, the function returns the status immediately.

Next, if the DMA type is identified as XDMA_TYPE_AXIDMA, the function acquires a spinlock to ensure thread safety while accessing shared resources. It retrieves the last active transmission descriptor from the active list of the channel. If the channel supports scatter-gather (SG) transfers, the function iterates through each segment of the descriptor, calculating the residue by summing the differences between the control and status registers of the hardware descriptor for each segment. After completing the calculations, the spinlock is released.

The residue value is then stored in the channel structure. Depending on whether the channel operates in cyclic mode, the function sets the residue in the txstate structure accordingly, either using the buffer index or the calculated residue.

Finally, the function returns the status obtained from the initial dma_cookie_status call.

Note: It is important to ensure that the txstate pointer is valid before passing it to the function. Additionally, the function assumes that the DMA channel is properly configured and that the active list contains valid descriptors.

Output Example: A possible return value of the function could be DMA_COMPLETE if the transaction has finished successfully, or DMA_IN_PROGRESS if the transaction is still ongoing.

graph TD
    A[Start xilinx_dma_tx_status] --> B[Get channel from dchan]
    B --> C[Get DMA cookie status]
    C --> D{Check cookie status}
    D -->|DMA_COMPLETE| E[Return DMA_COMPLETE]
    D -->|No txstate| E
    D -->|Other| F[Check DMA type]
    F -->|AXIDMA| G[Acquire lock]
    G --> H[Get last active descriptor]
    H --> I{Check if has_sg}
    I -->|Yes| J[Iterate through segments]
    J --> K[Calculate residue]
    K --> L[Update residue]
    I -->|No| L
    G --> M[Release lock]
    L --> N{Check if cyclic}
    N -->|Yes| O[Set residue to buf_idx]
    N -->|No| P[Set residue to residue]
    O --> Q[Return ret]
    P --> Q

Function xilinx_dma_stop_transfer(struct xilinx_dma_chan *chan)

xilinx_dma_stop_transfer: The function of xilinx_dma_stop_transfer is to stop the DMA transfer for a specified channel and ensure that the hardware has halted.

parameters: The parameters of this Function. · chan: A pointer to a struct xilinx_dma_chan that represents the DMA channel to be stopped.

Code Description: The xilinx_dma_stop_transfer function is a static function that takes a pointer to a xilinx_dma_chan structure as its parameter. The purpose of this function is to stop an ongoing DMA transfer on the specified channel.

The function begins by declaring a variable val of type u32, which will be used to hold the status of the DMA hardware. The first operation within the function is a call to the dma_ctrl_clr function, which clears the RUNSTOP bit in the DMA control register (DMACR) for the specified channel. This action effectively instructs the DMA hardware to stop the current transfer operation.

Following the clearing of the RUNSTOP bit, the function enters a polling mechanism to wait for the hardware to confirm that it has halted. This is achieved through the xilinx_dma_poll_timeout function, which checks the DMA status register (DMASR) for the HALTED condition. The polling continues until the HALTED bit is set, indicating that the DMA transfer has successfully stopped. The function also specifies a timeout mechanism, defined by the constant XILINX_DMA_LOOP_COUNT, to prevent indefinite waiting in case the hardware fails to halt.

The function ultimately returns the result of the polling operation, which indicates whether the DMA transfer was successfully stopped or if a timeout occurred.

Note: It is important to ensure that the DMA channel is properly initialized before calling this function. Additionally, users should be aware of the potential for timeouts and handle the return value accordingly to ensure robust error handling in their applications.

Output Example: A possible return value of the function could be 0, indicating that the DMA transfer was successfully stopped, or a negative error code if a timeout occurred before the hardware halted.

graph TD
    A[Start xilinx_dma_stop_transfer] --> B[Clear DMA control register]
    B --> C[Wait for hardware to halt]
    C --> D[Poll DMA status register]
    D --> E[Check if DMA is halted]
    E -->|Yes| F[Return success]
    E -->|No| G[Continue polling]
    G --> D
    F --> H[End xilinx_dma_stop_transfer]
    H -->|Return result| I[End]

Function xilinx_cdma_stop_transfer(struct xilinx_dma_chan *chan)

xilinx_cdma_stop_transfer: The function of xilinx_cdma_stop_transfer is to stop the transfer process of a specified Xilinx DMA channel.

parameters: The parameters of this Function. · chan: A pointer to a struct xilinx_dma_chan, which represents the DMA channel that is to be stopped.

Code Description: The xilinx_cdma_stop_transfer function is a static function that takes a pointer to a xilinx_dma_chan structure as its parameter. The purpose of this function is to halt the ongoing data transfer on the specified DMA channel.

Within the function, a variable val of type u32 is declared to hold the status value of the DMA channel. The function then calls xilinx_dma_poll_timeout, which is a utility function designed to poll the DMA status register (DMASR) until the channel is idle. The parameters passed to this polling function include: - chan: the DMA channel structure pointer. - XILINX_DMA_REG_DMASR: the register address for the DMA status. - val: the variable that will store the read status value. - val & XILINX_DMA_DMASR_IDLE: a condition that checks if the DMA channel is idle. - 0: the timeout value, indicating that there is no specific timeout limit set for this operation. - XILINX_DMA_LOOP_COUNT: the maximum number of polling attempts before giving up.

The function ultimately returns the result of the xilinx_dma_poll_timeout call, which indicates whether the operation was successful or if it timed out.

Note: It is important to ensure that the DMA channel is correctly initialized before calling this function. Additionally, the caller should handle the return value appropriately to determine if the transfer was successfully stopped or if an error occurred during the polling process.

Output Example: A possible return value of the function could be 0, indicating that the DMA channel has successfully transitioned to the idle state, or a negative error code indicating a failure in stopping the transfer.

graph TD
    A[Start xilinx_cdma_stop_transfer] --> B[Initialize variable val]
    B --> C[Call xilinx_dma_poll_timeout]
    C --> D[Check DMA status register]
    D --> E[Check if DMA is idle]
    E --> F[Return result from xilinx_dma_poll_timeout]
    F --> G[End xilinx_cdma_stop_transfer]

Function xilinx_dma_start(struct xilinx_dma_chan *chan)

xilinx_dma_start: The function of xilinx_dma_start is to initiate the DMA channel operation by setting the appropriate control register and polling the status register to ensure the channel has started successfully.

parameters: The parameters of this Function. · chan: A pointer to a struct xilinx_dma_chan that represents the DMA channel to be started.

Code Description: The xilinx_dma_start function is responsible for starting a specified DMA channel. It begins by setting the DMA control register (DMACR) to the RUNSTOP state, which is necessary to initiate the DMA operation. This is achieved through the dma_ctrl_set function, which takes the channel pointer, the register address (XILINX_DMA_REG_DMACR), and the value (XILINX_DMA_DMACR_RUNSTOP) to be written.

Following the control register update, the function enters a polling mechanism to wait for the hardware to confirm that the DMA channel has started. This is done using the xilinx_dma_poll_timeout function, which checks the DMA status register (DMASR) for the HALTED bit. The function will continue to poll until the HALTED bit is cleared, indicating that the DMA channel is no longer halted and has started successfully. The polling is limited by a predefined loop count (XILINX_DMA_LOOP_COUNT) to prevent indefinite waiting.

If the polling indicates an error (i.e., the DMA channel does not start within the allowed time), an error message is logged using dev_err, which includes the channel pointer and the current status of the DMA channel read from the DMASR. Additionally, the error state of the channel is marked by setting the err field of the channel structure to true.

Note: It is important to ensure that the DMA channel is properly configured before calling this function. The function assumes that the hardware is ready to accept commands and that the channel is not already in use. Proper error handling should be implemented to manage any potential issues during the start process.

graph TD
    A[Start xilinx_dma_start function] --> B[Set DMA control register to RUNSTOP]
    B --> C[Wait for hardware to start]
    C --> D[Poll DMA status register]
    D --> E{Check if DMA is not halted}
    E -- Yes --> F[Continue execution]
    E -- No --> G[Log error message]
    G --> H[Set channel error flag to true]
    F --> I[End xilinx_dma_start function]
    H --> I

Function xilinx_vdma_start_transfer(struct xilinx_dma_chan *chan)

xilinx_vdma_start_transfer: The function of xilinx_vdma_start_transfer is to initiate a data transfer on a Xilinx Video Direct Memory Access (VDMA) channel.

parameters: The parameters of this Function. · chan: A pointer to a struct xilinx_dma_chan that represents the DMA channel to be used for the transfer.

Code Description: The xilinx_vdma_start_transfer function is responsible for starting a data transfer on a specified Xilinx DMA channel. It begins by checking the state of the channel to ensure that it is not in an error state and is idle. If the channel is busy or has encountered an error, the function returns early without initiating a transfer.

The function retrieves the configuration settings associated with the DMA channel and checks if there are any pending descriptors in the channel's pending list. If the pending list is empty, the function exits without performing any operations.

Next, the function identifies the first and last descriptors in the pending list. It also retrieves the last segment of the last descriptor, which is necessary for configuring the hardware for the transfer. If the channel supports scatter-gather (SG) transfers, the current descriptor's physical address is written to the DMA control register.

The function then configures various hardware settings based on the configuration structure. This includes enabling or disabling vertical flipping, setting frame count enable, and configuring circular mode based on the presence of scatter-gather or parking settings.

The function updates the park pointer register based on the direction of the transfer (memory to device or device to memory) and the number of submitted descriptors. After configuring the hardware, it calls the xilinx_dma_start function to start the DMA engine.

If no errors have occurred, the function proceeds to start the actual data transfer. For scatter-gather transfers, it writes the physical address of the last segment to the tail descriptor register and moves the descriptors from the pending list to the active list. For direct register mode, it writes the start addresses and other parameters for each segment in the descriptor.

Finally, the function updates the channel's state to indicate that it is no longer idle, allowing for subsequent transfers to be initiated.

Note: It is important to ensure that the channel is in a valid state before calling this function. The function assumes that it is called with the appropriate locks held to prevent concurrent access issues.

Output Example: The function does not return a value, but it modifies the state of the DMA channel and the associated hardware registers to initiate the transfer process.

graph TD
    A[Start xilinx_vdma_start_transfer] --> B[Check if channel has error]
    B -->|Yes| C[Return]
    B -->|No| D[Check if channel is idle]
    D -->|No| C
    D -->|Yes| E[Check if pending list is empty]
    E -->|Yes| C
    E -->|No| F[Get first and last descriptors from pending list]
    F --> G[Get last segment from tail descriptor]
    F --> H[Check if channel has scatter-gather]
    H -->|Yes| I[Write current descriptor to DMA control register]
    H -->|No| J[Skip writing current descriptor]
    K[Configure hardware using config structure]
    K --> L[Check if vertical flip is enabled]
    L -->|Yes| M[Read and update vertical flip register]
    L -->|No| N[Skip vertical flip configuration]
    O[Read DMA control register]
    P[Check if frame count is enabled]
    P -->|Yes| Q[Enable frame count in control register]
    P -->|No| R[Disable frame count in control register]
    S[Check if circular mode should be enabled]
    S -->|Yes| T[Enable circular mode]
    S -->|No| U[Disable circular mode]
    V[Write updated control register]
    W[Get park pointer and update based on direction]
    X[Start the hardware]
    Y[Check if channel has error after starting]
    Y -->|Yes| C
    Y -->|No| Z[Check if channel has scatter-gather]
    Z -->|Yes| AA[Write tail descriptor to DMA register]
    Z -->|No| AB[Process segments for direct mode]
    AB --> AC[Loop through segments and write addresses]
    AC --> AD[Write last segment parameters]
    AD --> AE[Update descriptor counts]
    AE --> AF[Update active list]
    AG[Set channel to idle state]
    AF --> AG
    AG --> C[End xilinx_vdma_start_transfer]

Function xilinx_cdma_start_transfer(struct xilinx_dma_chan *chan)

xilinx_cdma_start_transfer: The function of xilinx_cdma_start_transfer is to initiate a DMA transfer for the specified channel.

parameters: The parameters of this Function. · parameter1: struct xilinx_dma_chan *chan - A pointer to the DMA channel structure that contains the necessary information for the transfer.

Code Description: The xilinx_cdma_start_transfer function is responsible for starting a DMA transfer on a specified channel. It first checks if there are any errors associated with the channel or if the channel is currently idle. If the channel is not idle or if there are no pending descriptors in the channel's pending list, the function returns immediately without initiating a transfer.

The function retrieves the head and tail descriptors from the pending list of the channel. It also obtains the last segment of the tail descriptor. If the number of pending descriptors is less than or equal to a predefined maximum coalescing value, the function updates the control register to reflect the number of pending descriptors.

If the channel supports scatter-gather (SG) mode, the function clears and then sets the SG mode in the control register. It writes the physical address of the head descriptor to the current descriptor register and the physical address of the tail segment to the tail descriptor register, effectively preparing the DMA engine to start the transfer.

In the case where the channel does not support SG mode, the function retrieves the first segment from the head descriptor and prepares the source and destination addresses for the transfer by writing them to the appropriate registers. It also writes the control information to the buffer transfer length register to start the transfer.

Finally, the function moves the pending descriptors to the active list, resets the pending descriptor count, and marks the channel as no longer idle, indicating that a transfer is in progress.

Note: It is important to ensure that the channel is idle and that there are pending descriptors before calling this function. Additionally, the function assumes that the DMA channel and its associated structures are properly initialized before use.

Output Example: The function does not return a value, but upon successful execution, it will initiate a DMA transfer, which can be verified by checking the status of the DMA channel and the active list of descriptors.

graph TD
    A[Start xilinx_cdma_start_transfer] --> B[Check if channel has error]
    B -->|Yes| C[Return]
    B -->|No| D[Check if channel is idle]
    D -->|No| C
    D -->|Yes| E[Check if pending list is empty]
    E -->|Yes| C
    E -->|No| F[Get head descriptor from pending list]
    F --> G[Get tail descriptor from pending list]
    G --> H[Get tail segment from tail descriptor segments]
    H --> I[Check if descriptor pending count is less than or equal to max]
    I -->|Yes| J[Update control register for coalesce]
    I -->|No| K[Check if channel has scatter-gather]
    K -->|Yes| L[Clear scatter-gather mode in control register]
    L --> M[Set scatter-gather mode in control register]
    M --> N[Write head descriptor physical address to current descriptor]
    N --> O[Write tail segment physical address to tail descriptor]
    K -->|No| P[Get first segment from head descriptor segments]
    P --> Q[Get hardware descriptor from segment]
    Q --> R[Write source address to source address register]
    R --> S[Write destination address to destination address register]
    S --> T[Start transfer by writing to buffer transfer threshold]
    T --> U[Splice pending list to active list]
    U --> V[Reset descriptor pending count]
    V --> W[Set channel to not idle]
    W --> C[End]

Function xilinx_dma_start_transfer(struct xilinx_dma_chan *chan)

xilinx_dma_start_transfer: The function of xilinx_dma_start_transfer is to initiate the transfer process for a Xilinx DMA channel.

parameters: The parameters of this Function. · chan: A pointer to a struct xilinx_dma_chan that represents the DMA channel to be used for the transfer.

Code Description: The xilinx_dma_start_transfer function is responsible for starting the DMA transfer for a specified channel. It begins by checking if the channel has encountered an error or if it is currently idle. If either condition is not met, the function returns immediately, preventing any transfer from starting.

Next, the function checks if there are any pending descriptors in the channel's pending list. If the list is empty, it also returns without initiating a transfer. If there are pending descriptors, it retrieves the head and tail descriptors from the pending list, as well as the last segment of the tail descriptor.

The function then reads the DMA control register to configure the transfer settings. If the number of pending descriptors is within the maximum coalesce limit, it updates the control register to reflect the current count of pending descriptors.

Depending on the configuration of the DMA channel (whether it supports scatter-gather and whether it is in multi-channel mode), the function writes the physical address of the head descriptor to the appropriate current descriptor register. It also handles the case where the transfer direction is from memory to device or vice versa, ensuring the correct destination is set.

After setting up the current descriptor, the function calls xilinx_dma_start to begin the transfer process. It checks again for any errors after starting the transfer.

If the channel supports scatter-gather, the function determines whether to set the tail descriptor based on whether the transfer is cyclic or not. If the channel does not support scatter-gather, it retrieves the first segment from the head descriptor and writes the source/destination address and buffer transfer size to the appropriate registers.

Finally, the function moves the pending descriptors to the active list, resets the pending descriptor count, and marks the channel as no longer idle, indicating that a transfer is in progress.

Note: It is important to ensure that the DMA channel is properly configured and that there are no errors before calling this function. Additionally, the function assumes that the pending list is managed correctly and that descriptors are added and removed as needed.

Output Example: The function does not return a value, but it modifies the state of the DMA channel and the associated registers to reflect the initiation of a transfer. The expected outcome is that the DMA transfer begins successfully, with the active list containing the descriptors that are currently being processed.

graph TD
    A[Start xilinx_dma_start_transfer] --> B[Check if channel has error]
    B -->|Yes| C[Return]
    B -->|No| D[Check if channel is idle]
    D -->|No| C
    D -->|Yes| E[Check if pending list is empty]
    E -->|Yes| C
    E -->|No| F[Get head descriptor]
    F --> G[Get tail descriptor]
    G --> H[Get tail segment]
    H --> I[Read DMA control register]
    I --> J[Check if descriptor count is within limit]
    J -->|Yes| K[Update coalesce max in register]
    J -->|No| L[Check if channel has scatter-gather]
    L -->|Yes| M[Check if device is mcdma]
    M -->|No| N[Write current descriptor address]
    M -->|Yes| O[Check transfer direction]
    O -->|MEM_TO_DEV| P[Write current descriptor address]
    O -->|DEV_TO_MEM| Q[Check if tdest is set]
    Q -->|No| R[Write current descriptor address]
    Q -->|Yes| S[Write current descriptor address with tdest]
    L -->|No| T[Get first segment from head descriptor]
    T --> U[Get hardware descriptor]
    U --> V[Write source/destination address]
    V --> W[Write buffer transfer length]
    N --> X[Start DMA transfer]
    P --> X
    R --> X
    S --> X
    X --> Y[Splice pending list to active list]
    Y --> Z[Reset pending count]
    Z --> AA[Set channel to idle state]
    AA --> AB[End xilinx_dma_start_transfer]

Function xilinx_dma_issue_pending(struct dma_chan *dchan)

xilinx_dma_issue_pending: The function of xilinx_dma_issue_pending is to initiate a pending DMA transfer for a specified DMA channel.

parameters: The parameters of this Function. · dchan: A pointer to the dma_chan structure representing the DMA channel that is to have its pending transfer issued.

Code Description: The xilinx_dma_issue_pending function is designed to handle the process of issuing a pending DMA transfer for a given DMA channel. It begins by converting the generic dma_chan pointer, dchan, into a specific xilinx_dma_chan pointer using the to_xilinx_chan macro. This conversion allows the function to access the specific properties and methods associated with the Xilinx DMA channel.

The function then declares a variable named flags to store the state of the interrupt flags. It uses the spin_lock_irqsave function to acquire a spinlock associated with the channel's lock while saving the current state of the interrupt flags. This ensures that the critical section of code that follows is executed without interruption, preventing race conditions that could occur if other threads attempt to access the same channel simultaneously.

Within the critical section, the function calls the start_transfer method of the channel, which is responsible for initiating the actual transfer process. This method is expected to handle the specifics of starting the DMA transfer, such as configuring hardware registers or triggering the DMA engine.

Finally, the function releases the spinlock using spin_unlock_irqrestore, restoring the previous state of the interrupt flags. This ensures that the system can continue to respond to interrupts as needed after the critical section has been executed.

Note: It is important to ensure that the DMA channel is properly configured and that no other operations are being performed on the channel while this function is executing to avoid potential conflicts or data corruption.

graph TD
    A[Start xilinx_dma_issue_pending] --> B[Get xilinx_dma_chan from dma_chan]
    B --> C[Save current interrupt flags]
    C --> D[Acquire lock on chan->lock]
    D --> E[Call start_transfer function on chan]
    E --> F[Release lock on chan->lock]
    F --> G[Restore interrupt flags]
    G --> H[End xilinx_dma_issue_pending]

Function xilinx_dma_complete_descriptor(struct xilinx_dma_chan *chan)

xilinx_dma_complete_descriptor: The function of xilinx_dma_complete_descriptor is to complete the DMA transactions associated with the active descriptors in a given DMA channel.

parameters: The parameters of this Function. · chan: A pointer to a struct xilinx_dma_chan that represents the DMA channel whose active descriptors are to be processed.

Code Description: The xilinx_dma_complete_descriptor function is designed to handle the completion of DMA transactions for a specific DMA channel. It operates under the assumption that the function is called while holding a lock, ensuring thread safety when accessing shared resources.

The function begins by checking if the active list of descriptors for the specified channel is empty using the list_empty function. If the active list is empty, the function returns immediately, as there are no descriptors to process.

If there are active descriptors, the function enters a loop using list_for_each_entry_safe, which iterates over each descriptor in the active list. This loop is safe for deletion of nodes from the list while iterating, as it uses the next pointer to keep track of the subsequent node.

Within the loop, each descriptor (desc) is removed from the active list using list_del. The function then checks if the descriptor is not cyclic. If the descriptor is not cyclic, it calls dma_cookie_complete, passing the async_tx member of the descriptor to mark the transaction as complete. This function typically updates the status of the DMA transaction and may release resources associated with it.

After processing the descriptor, it is added to the done list of the channel using list_add_tail, which appends the descriptor to the end of the done list. This allows for later retrieval or processing of completed transactions.

Note: It is important to ensure that the function is called with the appropriate locks held to prevent race conditions when accessing the active and done lists. Additionally, the function assumes that the descriptors are properly initialized and that the DMA channel is in a valid state.

Output Example: After executing this function, the active list of the specified DMA channel will be empty if all descriptors were processed, and the completed descriptors will be moved to the done list, ready for further handling. The return value of the function is void, as it does not return any data.

graph TD
    A[Start xilinx_dma_complete_descriptor] --> B[Check if active_list is empty]
    B -->|Yes| C[Return from function]
    B -->|No| D[Iterate over active_list]
    D --> E[Remove descriptor from active_list]
    E --> F[Check if descriptor is cyclic]
    F -->|No| G[Complete DMA cookie]
    F --> H[Add descriptor to done_list]
    G --> H
    H --> D
    D -->|No more descriptors| I[End xilinx_dma_complete_descriptor]

Function xilinx_dma_reset(struct xilinx_dma_chan *chan)

xilinx_dma_reset: The function of xilinx_dma_reset is to reset the specified Xilinx DMA channel.

parameters: The parameters of this Function. · chan: A pointer to the xilinx_dma_chan structure representing the DMA channel to be reset.

Code Description: The xilinx_dma_reset function initiates a reset sequence for a specified Xilinx DMA channel. It begins by setting the DMA control register to initiate the reset process using the dma_ctrl_set function, which writes the XILINX_DMA_DMACR_RESET value to the XILINX_DMA_REG_DMACR register.

Following this, the function enters a polling loop to monitor the status of the reset operation. It utilizes the xilinx_dma_poll_timeout function to repeatedly check the DMA control register until the reset bit is cleared, indicating that the hardware has completed the reset. The polling continues until either the reset is confirmed or a timeout occurs, which is controlled by the XILINX_DMA_LOOP_COUNT constant.

If the polling indicates a timeout (i.e., the reset bit remains set), an error message is logged using dev_err, detailing the current values of the control and status registers. The function then returns an error code of -ETIMEDOUT to signal that the reset operation did not complete in the expected timeframe.

If the reset completes successfully, the function updates the channel's state by setting the err field to false, marking the channel as idle, and resetting the descriptor submission count to zero. Finally, it returns the error code, which will be zero if the reset was successful.

Note: It is important to ensure that the DMA channel is not actively processing data when invoking this reset function, as this could lead to undefined behavior or data corruption. Proper error handling should be implemented to manage the return values effectively.

Output Example: A successful call to xilinx_dma_reset may return 0, indicating that the reset was completed without any issues. In contrast, if the reset times out, the function would return -ETIMEDOUT, along with an error message detailing the state of the DMA control and status registers.

graph TD
    A[Start xilinx_dma_reset function] --> B[Set DMA control register to reset]
    B --> C[Wait for hardware to finish reset]
    C --> D{Check reset status}
    D -->|Reset complete| E[Clear error flag]
    D -->|Reset not complete| F[Log reset timeout error]
    F --> G[Return timeout error]
    E --> H[Set channel to idle]
    H --> I[Reset descriptor submit count]
    I --> J[Return success or error code]
    G --> J
    J[End xilinx_dma_reset function]

Function xilinx_dma_chan_reset(struct xilinx_dma_chan *chan)

xilinx_dma_chan_reset: The function of xilinx_dma_chan_reset is to reset a Xilinx DMA channel and enable its interrupts.

parameters: The parameters of this Function. · chan: A pointer to a struct xilinx_dma_chan that represents the DMA channel to be reset.

Code Description: The xilinx_dma_chan_reset function is designed to reset a specified Xilinx DMA channel and configure it to enable interrupts. The function begins by declaring an integer variable err to capture any error codes that may arise during the execution of the reset process.

The first operation within the function is a call to xilinx_dma_reset(chan), which attempts to reset the DMA channel specified by the chan parameter. If this reset operation returns a non-zero value, indicating an error, the function immediately returns this error code, effectively terminating the operation.

If the reset is successful (i.e., err is zero), the function proceeds to enable interrupts for the DMA channel. This is accomplished by calling the dma_ctrl_set function, which sets the DMA control register (XILINX_DMA_REG_DMACR) to a value that enables all interrupt requests (XILINX_DMA_DMAXR_ALL_IRQ_MASK).

Finally, if both operations (resetting the channel and enabling interrupts) are successful, the function returns 0, indicating that the operation completed without any errors.

Note: It is important to ensure that the DMA channel is in a state that allows for resetting before calling this function. Additionally, proper error handling should be implemented to manage any potential issues that may arise during the reset process.

Output Example: A successful execution of the function will return 0, while an unsuccessful execution may return an error code such as -1, indicating a failure in resetting the DMA channel.

flowchart TD
    A[Start xilinx_dma_chan_reset] --> B[Call xilinx_dma_reset]
    B --> C{Check error}
    C -->|Yes| D[Return error]
    C -->|No| E[Call dma_ctrl_set]
    E --> F[End xilinx_dma_chan_reset]
    D --> F

Function xilinx_dma_irq_handler(int irq, void *data)

xilinx_dma_irq_handler: The function of xilinx_dma_irq_handler is to handle interrupts for the Xilinx DMA channel.

parameters: The parameters of this Function. · parameter1: int irq - The interrupt request number associated with the DMA channel. · parameter2: void *data - A pointer to the DMA channel structure that contains channel-specific information.

Code Description: The xilinx_dma_irq_handler function is designed to manage the interrupt requests generated by the Xilinx DMA controller. Upon invocation, it first retrieves the DMA channel structure from the provided data pointer. It then reads the status of the DMA controller by accessing the DMASR (DMA Status Register) to determine if any interrupts have occurred. If no relevant interrupts are detected, the function returns IRQ_NONE, indicating that the interrupt was not handled.

If interrupts are present, the function acknowledges them by writing back to the DMASR register, specifically targeting the bits that correspond to the interrupts. The function then checks for error conditions indicated by the DMASR. If an error interrupt is detected, it evaluates whether the error is recoverable based on the channel's configuration. If the error is not recoverable or if the flush-on-fsync option is not enabled, an error message is logged, and the error state is flagged in the channel structure.

The function also checks for a delay count interrupt, which indicates that the device is taking too long to complete a transfer. If this condition is met, a debug message is logged to inform about the excessive inter-packet latency.

Furthermore, if a frame count interrupt is detected, the function acquires a spinlock to ensure thread safety while completing the current descriptor. It then marks the channel as idle, initiates the start of a new transfer, and increments the buffer index. After completing these operations, the spinlock is released.

Finally, the function schedules a tasklet associated with the DMA channel to handle any further processing required after the interrupt handling. The function concludes by returning IRQ_HANDLED, indicating that the interrupt was successfully processed.

Note: It is important to ensure that the DMA channel structure is properly initialized before invoking this handler. Additionally, developers should be aware of the implications of enabling or disabling the flush-on-fsync option, as it affects error handling behavior.

Output Example: A possible return value of the function could be IRQ_HANDLED, indicating that the interrupt has been successfully processed. If no relevant interrupts were detected, the return value would be IRQ_NONE.

graph TD
    A[Start xilinx_dma_irq_handler] --> B[Read status from DMA control register]
    B --> C{Check if any IRQ is set}
    C -->|No| D[Return IRQ_NONE]
    C -->|Yes| E[Acknowledge interrupts]
    E --> F{Check for error IRQ}
    F -->|Yes| G[Read error status]
    G --> H{Check if flush on fsync is enabled}
    H -->|No| I[Log error and set channel error flag]
    H -->|Yes| J{Check for non-recoverable errors}
    J -->|Yes| I
    J -->|No| K[Clear recoverable errors]
    F -->|No| L{Check for delay count IRQ}
    L -->|Yes| M[Log inter-packet latency issue]
    L -->|No| N{Check for frame count IRQ}
    N -->|Yes| O[Lock channel and complete descriptor]
    O --> P[Set channel idle]
    P --> Q[Start transfer]
    Q --> R[Increment buffer index]
    R --> S[Unlock channel]
    N -->|No| T[Schedule tasklet]
    T --> U[Return IRQ_HANDLED]
    D --> U

Function append_desc_queue(struct xilinx_dma_chan *chan,

              struct xilinx_dma_tx_descriptor *desc)

append_desc_queue: The function of append_desc_queue is to add a new DMA transaction descriptor to the pending list of a specified DMA channel.

parameters: The parameters of this Function. · parameter1: struct xilinx_dma_chan chan - A pointer to the DMA channel structure where the descriptor will be appended. · parameter2: struct xilinx_dma_tx_descriptor desc - A pointer to the transaction descriptor that is to be added to the pending list.

Code Description: The append_desc_queue function is responsible for managing the queue of DMA transaction descriptors for a specific DMA channel. It first checks if the pending list of descriptors for the channel is empty. If it is, the function proceeds directly to append the new descriptor to the list.

If the pending list is not empty, the function retrieves the last descriptor in the list and determines the type of DMA configuration being used (VDMA, CDMA, or AXIDMA). Based on this type, it accesses the last segment of the last descriptor and updates its next descriptor pointer to point to the physical address of the new descriptor being added. This effectively links the new descriptor to the existing chain of descriptors.

After handling the hardware descriptor linkage, the function appends the new software descriptor to the pending list of the channel. It also increments the count of pending descriptors. If the channel supports scatter-gather (SG) and is using VDMA, the function checks if the count of pending descriptors exceeds the maximum allowed frames. If it does, a debug message is logged, and the pending count is capped at the maximum number of frames.

Note: It is important to ensure that the DMA channel and descriptor structures are properly initialized before calling this function. Additionally, developers should be aware of the implications of exceeding the maximum number of pending descriptors, as this may lead to unexpected behavior or performance issues.

graph TD
    A[Start append_desc_queue] --> B[Check if pending_list is empty]
    B -->|Yes| C[Go to append]
    B -->|No| D[Get tail_desc from pending_list]
    D --> E[Check dma_config dmatype]
    E -->|VDMA| F[Get tail_segment from tail_desc segments]
    E -->|CDMA| G[Get cdma_tail_segment from tail_desc segments]
    E -->|AXIDMA| H[Get axidma_tail_segment from tail_desc segments]
    F --> I[Set tail_segment hw.next_desc to desc async_tx phys]
    G --> J[Set cdma_tail_segment hw.next_desc to desc async_tx phys]
    H --> K[Set axidma_tail_segment hw.next_desc to desc async_tx phys]
    I --> L[Go to append]
    J --> L
    K --> L
    L[Add desc node to pending_list] --> M[Increment desc_pendingcount]
    M --> N[Check if has_sg and dmatype is VDMA]
    N -->|Yes| O[Check if desc_pendingcount exceeds num_frms]
    O -->|Yes| P[Log desc pendingcount is too high]
    O -->|No| Q[End]
    N -->|No| Q
    P --> R[Set desc_pendingcount to num_frms]
    R --> Q
    Q[End append_desc_queue]

Function xilinx_dma_tx_submit(struct dma_async_tx_descriptor *tx)

xilinx_dma_tx_submit: The function of xilinx_dma_tx_submit is to submit a DMA transaction descriptor for processing in a Xilinx DMA channel.

parameters: The parameters of this Function. · tx: A pointer to a dma_async_tx_descriptor structure representing the transaction descriptor to be submitted.

Code Description: The xilinx_dma_tx_submit function is responsible for submitting a DMA transaction descriptor to a Xilinx DMA channel. It begins by converting the provided transaction descriptor pointer (tx) into a specific Xilinx DMA transaction descriptor (desc) and retrieves the associated DMA channel (chan).

The function first checks if the channel is in cyclic mode. If it is, the function frees the transaction descriptor and returns an error code (-EBUSY), indicating that the channel is busy. Next, it checks for any errors in the channel. If an error is detected, the function attempts to reset the channel using xilinx_dma_chan_reset. If the reset fails, it returns the error code.

To ensure thread safety, the function acquires a spinlock on the channel's lock before proceeding. It assigns a DMA cookie to the transaction descriptor using dma_cookie_assign, which uniquely identifies the transaction. The transaction descriptor is then appended to the channel's pending descriptor queue. If the transaction descriptor is marked as cyclic, the function updates the channel's cyclic status accordingly.

Finally, the function releases the spinlock and returns the assigned DMA cookie, indicating successful submission of the transaction descriptor.

Note: It is important to ensure that the DMA channel is not in cyclic mode before submitting a transaction. Additionally, proper error handling should be implemented to manage any issues that arise during channel resets.

Output Example: A possible return value of the function could be a valid dma_cookie_t value, such as 1, indicating that the transaction descriptor has been successfully submitted and assigned a unique identifier.

graph TD
    A[Start xilinx_dma_tx_submit] --> B[Get tx descriptor]
    B --> C[Get xilinx channel]
    C --> D{Is channel cyclic?}
    D -- Yes --> E[Free tx descriptor]
    E --> F[Return -EBUSY]
    D -- No --> G{Is channel error?}
    G -- Yes --> H[Reset xilinx channel]
    H --> I{Is reset successful?}
    I -- No --> F
    I -- Yes --> J[Acquire lock]
    J --> K[Assign dma cookie]
    K --> L[Append descriptor to pending queue]
    L --> M{Is descriptor cyclic?}
    M -- Yes --> N[Set channel cyclic to true]
    N --> O[Release lock]
    M -- No --> O
    O --> P[Return dma cookie]
    G -- No --> J
    F --> Q[End]
    P --> Q

Function xilinx_dma_terminate_all(struct dma_chan *dchan)

xilinx_dma_terminate_all: The function of xilinx_dma_terminate_all is to terminate all ongoing DMA transfers for a specified DMA channel.

parameters: The parameters of this Function. · dchan: A pointer to the dma_chan structure representing the DMA channel to be terminated.

Code Description: The xilinx_dma_terminate_all function is designed to safely stop and reset a DMA channel. It first converts the generic DMA channel pointer (dchan) to a specific xilinx_dma_chan structure pointer (chan) using the to_xilinx_chan macro. The function then checks if the channel is not in cyclic mode. If it is not cyclic, it attempts to stop the ongoing transfer by calling the stop_transfer method associated with the channel. If the transfer cannot be stopped, an error message is logged, and the error state of the channel is set to true.

Following the stop operation, the function calls xilinx_dma_chan_reset to reset the channel to a known state. It then proceeds to free all descriptors associated with the channel by invoking xilinx_dma_free_descriptors. The idle state of the channel is set to true, indicating that it is no longer active.

If the channel was operating in cyclic mode, the function modifies the DMA control register (DMACR) to disable the cyclic buffer by clearing the appropriate bitmask. The cyclic flag for the channel is then set to false.

Additionally, if the DMA device type is identified as XDMA_TYPE_CDMA and the channel has scatter-gather capabilities (has_sg), the function clears the scatter-gather mode in the DMACR register.

The function concludes by returning 0, indicating successful termination of the DMA channel.

Note: It is important to ensure that the DMA channel is not in use before calling this function to avoid potential conflicts or data corruption. Proper error handling should be implemented to manage any issues that arise during the stopping of the transfer.

Output Example: The function will return 0 upon successful termination of the DMA channel, indicating that all operations were completed without errors.

graph TD
    A[Start xilinx_dma_terminate_all] --> B[Convert dma_chan to xilinx_dma_chan]
    B --> C{Check if channel is cyclic}
    C -->|No| D[Stop transfer using stop_transfer function]
    D --> E{Check for error}
    E -->|Yes| F[Log error message and set channel error flag]
    E -->|No| G[Continue]
    C -->|Yes| H[Skip stopping transfer]
    G --> I[Reset xilinx_dma channel]
    I --> J[Free all descriptors in the lists]
    J --> K[Set channel idle to true]
    K --> L{Check if channel is cyclic}
    L -->|Yes| M[Read DMACR register]
    M --> N[Clear cyclic BD enable mask]
    N --> O[Write updated DMACR register]
    O --> P[Set channel cyclic to false]
    L -->|No| Q[Skip cyclic handling]
    Q --> R{Check if DMA type is CDMA and has scatter-gather}
    R -->|Yes| S[Clear SG mode in DMACR register]
    R -->|No| T[Skip SG mode clearing]
    T --> U[Return 0]
    F --> U
    H --> U

Function xilinx_vdma_channel_set_config(struct dma_chan *dchan,

                struct xilinx_vdma_config *cfg)

xilinx_vdma_channel_set_config: The function of xilinx_vdma_channel_set_config is to configure the settings of a Xilinx Video Direct Memory Access (VDMA) channel.

parameters: The parameters of this Function. · dchan: A pointer to a dma_chan structure representing the DMA channel to be configured.
· cfg: A pointer to a xilinx_vdma_config structure containing the configuration settings to be applied to the DMA channel.

Code Description: The xilinx_vdma_channel_set_config function is responsible for setting various configuration parameters for a specified Xilinx VDMA channel. The function begins by converting the generic DMA channel pointer (dchan) to a specific Xilinx DMA channel pointer (chan) using the to_xilinx_chan macro. It then checks if the reset flag in the configuration structure (cfg) is set. If it is, the function calls xilinx_dma_chan_reset to reset the channel and returns immediately.

Next, the function reads the current DMA control register (dmacr) value for the channel. It updates the channel's configuration structure with various parameters from the cfg structure, including frame delay (frm_dly), park settings (park), and genlock settings (gen_lock and master). If genlock is enabled and the channel supports it, the function modifies the dmacr to enable genlock and set the master configuration.

The function also configures frame count enable (frm_cnt_en) and vertical flip enable (vflip_en) settings. If the park setting is enabled, it assigns the park frame value; otherwise, it sets it to -1. The coalescing and delay settings are updated, and the function ensures that these values do not exceed their respective maximum limits defined by XILINX_DMA_DMACR_FRAME_COUNT_MAX and XILINX_DMA_DMACR_DELAY_MAX.

Finally, the function handles the FSync source selection by clearing the relevant bits in the dmacr and setting the external FSync value from the cfg structure. After all configurations are applied, the updated dmacr value is written back to the DMA control register. The function concludes by returning 0 to indicate successful execution.

Note: It is important to ensure that the configuration values provided in the cfg structure are valid and within the defined limits to avoid unexpected behavior. Additionally, the reset operation should be performed with caution, as it will clear the current configuration of the channel.

Output Example: A successful execution of the function will return 0, indicating that the configuration has been applied without errors.

graph TD
    A[Start] --> B[Check if cfg reset]
    B -->|Yes| C[Call xilinx_dma_chan_reset]
    B -->|No| D[Read dmacr from DMA control]
    D --> E[Set channel configuration parameters]
    E --> F[Check if gen_lock is enabled]
    F -->|Yes| G[Update dmacr for gen_lock and master]
    F -->|No| H[Skip gen_lock update]
    G --> I[Set frm_cnt_en and vflip_en]
    H --> I
    I --> J[Check if park is enabled]
    J -->|Yes| K[Set park_frm]
    J -->|No| L[Set park_frm to -1]
    K --> M[Set coalesc and delay]
    L --> M
    M --> N[Check coalesc value]
    N -->|Valid| O[Update dmacr with coalesc]
    N -->|Invalid| P[Skip coalesc update]
    O --> Q[Check delay value]
    P --> Q
    Q -->|Valid| R[Update dmacr with delay]
    Q -->|Invalid| S[Skip delay update]
    R --> T[Set FSync Source in dmacr]
    S --> T
    T --> U[Write dmacr back to DMA control]
    U --> V[Return 0]
    V --> W[End]

Function xilinx_dma_chan_remove(struct xilinx_dma_chan *chan)

xilinx_dma_chan_remove: The function of xilinx_dma_chan_remove is to safely remove a DMA channel by disabling interrupts, freeing resources, and unlinking the channel from its device list.

parameters: The parameters of this Function. · chan: A pointer to the xilinx_dma_chan structure representing the DMA channel to be removed.

Code Description: The xilinx_dma_chan_remove function performs several critical operations to ensure the safe removal of a DMA channel.

  1. Disable all interrupts: The function begins by calling the dma_ctrl_clr function, which clears the interrupt control register (DMACR) for the specified DMA channel. This is done using the XILINX_DMA_DMAXR_ALL_IRQ_MASK to ensure that all interrupts associated with the channel are disabled, preventing any further interrupt handling while the channel is being removed.

  2. Free IRQ: The function checks if the IRQ (interrupt request line) associated with the channel is greater than zero. If it is, the free_irq function is called to release the IRQ, passing the IRQ number and the channel pointer. This step is crucial to avoid memory leaks and ensure that the IRQ can be reused by other components in the system.

  3. Kill tasklet: The tasklet_kill function is invoked with the tasklet associated with the DMA channel. This function ensures that any pending tasklet work is completed and that the tasklet is safely removed from the system. Tasklets are used for deferred work in the Linux kernel, and this step is necessary to clean up any ongoing operations related to the DMA channel.

  4. Remove from device list: Finally, the function calls list_del to unlink the channel's device node from the common device list. This operation ensures that the channel is no longer part of the device's active list, effectively removing it from the system.

Note: It is important to ensure that this function is called in a context where it is safe to manipulate the DMA channel and its associated resources. Proper synchronization mechanisms should be in place to prevent race conditions during the removal process. Additionally, developers should verify that the channel is not in use before invoking this function to avoid potential data corruption or system instability.

graph TD
    A[Start xilinx_dma_chan_remove] --> B[Disable all interrupts]
    B --> C{Check if irq is greater than 0}
    C -->|Yes| D[Free irq associated with chan]
    C -->|No| E[Skip freeing irq]
    D --> F[Kill tasklet associated with chan]
    E --> F
    F --> G[Remove chan from device node list]
    G --> H[End xilinx_dma_chan_remove]

Function axidma_clk_init(struct platform_device pdev, struct clk *axi_clk,

            struct clk **tx_clk,  struct clk **rx_clk, 
            struct clk **sg_clk,  struct clk **tmp_clk)

axidma_clk_init: The function of axidma_clk_init is to initialize and enable the necessary clocks for the AXI DMA controller.

parameters: The parameters of this Function. · pdev: A pointer to the platform_device structure representing the device for which the clocks are being initialized.
· axi_clk: A pointer to a pointer where the AXI clock will be stored.
· tx_clk: A pointer to a pointer where the transmit clock will be stored.
· rx_clk: A pointer to a pointer where the receive clock will be stored.
· sg_clk: A pointer to a pointer where the scatter-gather clock will be stored.
· tmp_clk: A pointer to a pointer where a temporary clock will be stored (initialized to NULL).

Code Description: The axidma_clk_init function begins by initializing the tmp_clk pointer to NULL. It then attempts to retrieve various clock resources associated with the device using the devm_clk_get function. The clocks being retrieved include the AXI Lite clock (s_axi_lite_aclk), the transmit clock (m_axi_mm2s_aclk), the receive clock (m_axi_s2mm_aclk), and the scatter-gather clock (m_axi_sg_aclk). If any of these clock retrievals fail (indicated by returning an error pointer), the function logs an error message and returns the corresponding error code.

Once the clocks are successfully retrieved, the function proceeds to prepare and enable each clock in sequence. It first enables the AXI clock, followed by the transmit clock, the receive clock, and finally the scatter-gather clock. If enabling any clock fails, the function logs an error message and disables any previously enabled clocks in reverse order to ensure proper cleanup. The function ultimately returns 0 on success, or an error code if any of the operations fail.

Note: It is important to ensure that the platform_device structure passed to the function is valid and that the clock names used in devm_clk_get match those defined in the device tree or hardware configuration. Proper error handling is crucial to avoid resource leaks and ensure that all clocks are disabled if an error occurs during initialization.

Output Example: A successful execution of the function will return 0, indicating that all clocks have been initialized and enabled correctly. If an error occurs, the function may return a negative error code, such as -ENOENT if a clock could not be found, or -EBUSY if a clock could not be enabled.

graph TD
    A[Start axidma_clk_init function] --> B[Initialize tmp_clk to NULL]
    B --> C[Get axi_clk using devm_clk_get]
    C --> D{Is axi_clk an error?}
    D -- Yes --> E[Log error for axi_clk]
    D -- No --> F[Get tx_clk using devm_clk_get]
    F --> G{Is tx_clk an error?}
    G -- Yes --> H[Set tx_clk to NULL]
    G -- No --> I[Get rx_clk using devm_clk_get]
    I --> J{Is rx_clk an error?}
    J -- Yes --> K[Set rx_clk to NULL]
    J -- No --> L[Get sg_clk using devm_clk_get]
    L --> M{Is sg_clk an error?}
    M -- Yes --> N[Set sg_clk to NULL]
    M -- No --> O[Prepare and enable axi_clk]
    O --> P{Is enabling axi_clk an error?}
    P -- Yes --> Q[Log error for axi_clk]
    P -- No --> R[Prepare and enable tx_clk]
    R --> S{Is enabling tx_clk an error?}
    S -- Yes --> T[Log error for tx_clk]
    S -- No --> U[Prepare and enable rx_clk]
    U --> V{Is enabling rx_clk an error?}
    V -- Yes --> W[Log error for rx_clk]
    V -- No --> X[Prepare and enable sg_clk]
    X --> Y{Is enabling sg_clk an error?}
    Y -- Yes --> Z[Log error for sg_clk]
    Y -- No --> AA[Return 0]

    T --> AB[Disable and unprepare axi_clk]
    W --> AC[Disable and unprepare tx_clk]
    Z --> AD[Disable and unprepare rx_clk]

    AB --> AE[Return error]
    AC --> AE
    AD --> AE

Function axicdma_clk_init(struct platform_device pdev, struct clk *axi_clk,

            struct clk **dev_clk,  struct clk **tmp_clk, 
            struct clk **tmp1_clk,  struct clk **tmp2_clk)

axicdma_clk_init: The function of axicdma_clk_init is to initialize the clock resources required for the AXI DMA controller.

parameters: The parameters of this Function. · pdev: A pointer to the platform_device structure representing the device for which the clocks are being initialized.
· axi_clk: A pointer to a pointer where the AXI clock will be stored after initialization.
· dev_clk: A pointer to a pointer where the device clock will be stored after initialization.
· tmp_clk: A pointer to a pointer for temporary clock storage, initialized to NULL.
· tmp1_clk: A pointer to a pointer for temporary clock storage, initialized to NULL.
· tmp2_clk: A pointer to a pointer for temporary clock storage, initialized to NULL.

Code Description: The axicdma_clk_init function is responsible for obtaining and enabling the necessary clocks for the AXI DMA controller. Initially, it sets the temporary clock pointers (tmp_clk, tmp1_clk, tmp2_clk) to NULL. It then attempts to retrieve the AXI clock ("s_axi_lite_aclk") using the devm_clk_get function. If this retrieval fails, an error message is logged, and the error code is returned. The same process is repeated for the device clock ("m_axi_aclk"). If both clocks are successfully retrieved, the function proceeds to enable them using clk_prepare_enable. If enabling either clock fails, the function logs an error message and disables the previously enabled AXI clock to ensure proper resource management. If all operations are successful, the function returns 0, indicating successful initialization.

Note: It is important to ensure that the platform_device structure passed to the function is valid and that the clock names used in devm_clk_get match those defined in the device tree or hardware configuration. Proper error handling is crucial to avoid resource leaks.

Output Example: A successful call to axicdma_clk_init might return 0, indicating that both clocks have been initialized and enabled without any errors. If there is an issue retrieving the AXI clock, it might return a negative error code, such as -ENOENT, indicating that the clock could not be found.

graph TD
    A[Start axicdma_clk_init function] --> B[Initialize temporary clock pointers to NULL]
    B --> C[Get axi_clk using devm_clk_get]
    C --> D{Check if axi_clk is an error}
    D -- Yes --> E[Retrieve error code from axi_clk]
    E --> F[Log error message for axi_clk]
    F --> G[Return error code]
    D -- No --> H[Get dev_clk using devm_clk_get]
    H --> I{Check if dev_clk is an error}
    I -- Yes --> J[Retrieve error code from dev_clk]
    J --> K[Log error message for dev_clk]
    K --> G
    I -- No --> L[Prepare and enable axi_clk]
    L --> M{Check if enabling axi_clk failed}
    M -- Yes --> N[Log error message for axi_clk]
    N --> O[Disable and unprepare axi_clk]
    O --> G
    M -- No --> P[Prepare and enable dev_clk]
    P --> Q{Check if enabling dev_clk failed}
    Q -- Yes --> R[Log error message for dev_clk]
    R --> O
    Q -- No --> S[Return success]
    G --> T[End axicdma_clk_init function]

Function axivdma_clk_init(struct platform_device pdev, struct clk *axi_clk,

            struct clk **tx_clk,  struct clk **txs_clk, 
            struct clk **rx_clk,  struct clk **rxs_clk)

axivdma_clk_init: The function of axivdma_clk_init is to initialize and enable the necessary clocks for the AXI Video Direct Memory Access (DMA) controller.

parameters: The parameters of this Function. · pdev: A pointer to the platform_device structure representing the device for which the clocks are being initialized.
· axi_clk: A pointer to a pointer that will hold the reference to the AXI Lite clock.
· tx_clk: A pointer to a pointer that will hold the reference to the AXI MM2S (Memory-Mapped to Stream) clock.
· txs_clk: A pointer to a pointer that will hold the reference to the AXI Stream MM2S clock.
· rx_clk: A pointer to a pointer that will hold the reference to the AXI S2MM (Stream to Memory-Mapped) clock.
· rxs_clk: A pointer to a pointer that will hold the reference to the AXI Stream S2MM clock.

Code Description: The axivdma_clk_init function begins by attempting to retrieve the AXI Lite clock using the devm_clk_get function, which allocates and manages the clock resource for the device. If the retrieval fails, an error message is logged, and the error code is returned. The function then proceeds to retrieve additional clocks for transmission (tx_clk, txs_clk) and reception (rx_clk, rxs_clk). If any of these clocks cannot be retrieved, they are set to NULL, indicating that they are not available.

Once all necessary clocks are retrieved, the function attempts to prepare and enable each clock in sequence. If enabling any clock fails, the function logs an error message and disables any previously enabled clocks in reverse order to ensure proper resource management. The function ultimately returns 0 on success, indicating that all clocks have been successfully initialized and enabled.

Note: It is important to ensure that the platform_device structure passed to the function is valid and that the clock names correspond to those defined in the device tree or hardware configuration. Proper error handling is crucial to avoid resource leaks.

Output Example: A successful execution of the function would return 0, indicating that all clocks have been initialized and enabled correctly. If an error occurs during the process, a negative error code will be returned, such as -ENOENT if a clock could not be found or -EBUSY if a clock could not be enabled.

graph TD
    A[Start axivdma_clk_init] --> B[Get axi_clk]
    B --> C{Is axi_clk valid?}
    C -- Yes --> D[Get tx_clk]
    C -- No --> E[Log error for axi_clk]
    E --> F[Return error]
    D --> G{Is tx_clk valid?}
    G -- Yes --> H[Get txs_clk]
    G -- No --> I[Set tx_clk to NULL]
    I --> H
    H --> J{Is txs_clk valid?}
    J -- Yes --> K[Get rx_clk]
    J -- No --> L[Set txs_clk to NULL]
    L --> K
    K --> M{Is rx_clk valid?}
    M -- Yes --> N[Get rxs_clk]
    M -- No --> O[Set rx_clk to NULL]
    O --> N
    N --> P{Is rxs_clk valid?}
    P -- Yes --> Q[Prepare and enable axi_clk]
    P -- No --> R[Set rxs_clk to NULL]
    R --> Q
    Q --> S{Is enabling axi_clk successful?}
    S -- Yes --> T[Prepare and enable tx_clk]
    S -- No --> U[Log error for axi_clk]
    U --> F
    T --> V{Is enabling tx_clk successful?}
    V -- Yes --> W[Prepare and enable txs_clk]
    V -- No --> X[Log error for tx_clk]
    X --> Y[Disable axi_clk]
    Y --> F
    W --> Z{Is enabling txs_clk successful?}
    Z -- Yes --> AA[Prepare and enable rx_clk]
    Z -- No --> AB[Log error for txs_clk]
    AB --> AC[Disable tx_clk]
    AC --> Y
    AA --> AD{Is enabling rx_clk successful?}
    AD -- Yes --> AE[Prepare and enable rxs_clk]
    AD -- No --> AF[Log error for rx_clk]
    AF --> AG[Disable txs_clk]
    AG --> Y
    AE --> AH{Is enabling rxs_clk successful?}
    AH -- Yes --> AI[Return success]
    AH -- No --> AJ[Log error for rxs_clk]
    AJ --> AK[Disable rx_clk]
    AK --> Y
    Y --> AL[Disable txs_clk]
    AL --> AM[Disable tx_clk]
    AM --> AN[Disable axi_clk]
    AN --> F

Function xdma_disable_allclks(struct xilinx_dma_device *xdev)

xdma_disable_allclks: The function of xdma_disable_allclks is to disable and unprepare all clock signals associated with the xilinx_dma_device.

parameters: The parameters of this Function. · xdev: A pointer to a struct xilinx_dma_device that represents the DMA device whose clocks are to be disabled.

Code Description: The xdma_disable_allclks function is a static function designed to manage the clock signals of a xilinx_dma_device. It takes a single parameter, xdev, which is a pointer to the xilinx_dma_device structure. This structure contains references to various clock signals used by the device.

The function performs the following operations: 1. It calls the clk_disable_unprepare function for each clock signal associated with the device. This includes: - xdev->rxs_clk: The receive side clock signal. - xdev->rx_clk: The receive clock signal. - xdev->txs_clk: The transmit side clock signal. - xdev->tx_clk: The transmit clock signal. - xdev->axi_clk: The AXI interface clock signal.

The clk_disable_unprepare function is responsible for disabling the specified clock and releasing any resources associated with it. By calling this function for each clock signal, xdma_disable_allclks ensures that all clocks are properly disabled, preventing any unintended operation of the DMA device when it is not in use.

Note: It is important to ensure that this function is called when the DMA device is no longer needed or before the device is removed from the system. Failing to disable the clocks may lead to power consumption issues or unintended behavior of the device.

graph TD
    A[Start xdma_disable_allclks] --> B[Disable receive stream clock]
    B --> C[Disable receive clock]
    C --> D[Disable transmit stream clock]
    D --> E[Disable transmit clock]
    E --> F[Disable AXI clock]
    F --> G[End xdma_disable_allclks]

Function xilinx_dma_chan_probe(struct xilinx_dma_device *xdev,

              struct device_node *node,  int chan_id)

xilinx_dma_chan_probe: The function of xilinx_dma_chan_probe is to initialize and configure a DMA channel for a Xilinx DMA device.

parameters: The parameters of this Function. · xdev: A pointer to the xilinx_dma_device structure representing the DMA device. · node: A pointer to the device_node structure representing the device tree node for the DMA channel. · chan_id: An integer representing the channel ID to be assigned to the DMA channel.

Code Description: The xilinx_dma_chan_probe function is responsible for setting up a DMA channel within a Xilinx DMA device. It begins by allocating memory for the xilinx_dma_chan structure, which holds the channel's configuration and state. If memory allocation fails, the function returns -ENOMEM to indicate an out-of-memory error.

The function initializes various fields of the channel structure, including device pointers, descriptor pending count, external address, and a flag indicating whether the channel is idle. It also initializes several linked lists that manage the state of pending, done, active, and free segments.

Next, the function retrieves properties from the device tree node, such as whether the channel includes Direct Register Access (DRE) and the data width. If the data width exceeds 8 bytes, DRE is disabled. The function also sets the copy alignment based on the data width.

The function checks the compatibility of the device node with various Xilinx DMA channel types (e.g., MM2S and S2MM) and configures the channel's direction, ID, and control offsets accordingly. It also handles specific configurations for vertical flipping if applicable.

An interrupt is requested for the channel, and if this fails, an error message is logged, and the function returns the error code. The function then sets the appropriate transfer start and stop functions based on the DMA type configured in the device.

A tasklet is initialized for the channel to handle deferred processing. The channel is added to the DMA engine's list of channels, and the channel ID is stored in the device's channel array.

Finally, the function attempts to reset the channel. If the reset fails, an error message is logged, and the function returns the error code. If all operations are successful, the function returns 0, indicating successful initialization of the DMA channel.

Note: It is important to ensure that the device tree node is correctly configured with the necessary properties for the DMA channel to function properly. Additionally, proper error handling should be implemented to manage any failures during initialization.

Output Example: A successful return value from the function would be 0, indicating that the DMA channel has been initialized correctly. If an error occurs, the function may return values such as -ENOMEM for memory allocation failure or -EINVAL for invalid device node compatibility.

graph TD
    A[Start xilinx_dma_chan_probe] --> B[Allocate and initialize channel structure]
    B --> C{Check allocation success}
    C -->|No| D[Return -ENOMEM]
    C -->|Yes| E[Set channel properties]
    E --> F[Retrieve channel properties from device tree]
    F --> G[Check for DRE support]
    G --> H{Is data width > 8 bytes?}
    H -->|Yes| I[Set has_dre to false]
    H -->|No| J[Continue]
    J --> K{Check device compatibility}
    K -->|MM2S| L[Set channel direction to DMA_MEM_TO_DEV]
    K -->|S2MM| M[Set channel direction to DMA_DEV_TO_MEM]
    K -->|Invalid| N[Return -EINVAL]
    L --> O[Request interrupt]
    M --> O
    O --> P{Check IRQ request success}
    P -->|No| Q[Return IRQ request error]
    P -->|Yes| R[Set transfer functions based on DMA type]
    R --> S[Initialize tasklet]
    S --> T[Add channel to DMA engine channels list]
    T --> U[Reset the channel]
    U --> V{Check reset success}
    V -->|No| W[Return reset error]
    V -->|Yes| X[Return 0]
    D --> Z[End]
    Q --> Z
    W --> Z

Function xilinx_dma_child_probe(struct xilinx_dma_device *xdev,

                struct device_node *node)

xilinx_dma_child_probe: The function of xilinx_dma_child_probe is to probe and initialize DMA channels for a given Xilinx DMA device.

parameters: The parameters of this Function. · parameter1: struct xilinx_dma_device xdev - A pointer to the Xilinx DMA device structure that is being probed. · parameter2: struct device_node node - A pointer to the device node representing the DMA device in the device tree.

Code Description: The xilinx_dma_child_probe function begins by declaring local variables ret, i, and nr_channels, initializing nr_channels to 1. It then attempts to read the "dma-channels" property from the provided device node using the of_property_read_u32 function. If the property is not found (indicated by a negative return value) and if the mcdma member of the xdev structure is set, a warning message is logged indicating that the "dma-channels" property is missing.

Next, the function enters a loop that iterates from 0 to nr_channels - 1. In each iteration, it calls the xilinx_dma_chan_probe function to initialize a DMA channel, passing the xdev pointer, the node pointer, and the current channel ID (which is incremented with each call). After all channels have been probed, the total number of channels in the xdev structure is updated by adding nr_channels to the existing nr_channels value.

Finally, the function returns 0, indicating successful completion of the probing process.

Note: It is important to ensure that the device node contains the "dma-channels" property when initializing DMA channels, as its absence may lead to warnings and potentially affect the functionality of the DMA device.

Output Example: A successful execution of the function would result in the return value of 0, indicating that the DMA channels have been probed and initialized correctly. If the "dma-channels" property is missing, a warning will be logged, but the function will still return 0.

graph TD
    A[Start xilinx_dma_child_probe] --> B[Read dma-channels property]
    B --> C{Check if read was successful}
    C -->|Yes| D[Set nr_channels to read value]
    C -->|No| E[Check if mcdma is true]
    E -->|Yes| F[Log warning for missing dma-channels property]
    E -->|No| G[Continue without warning]
    D --> H[Loop through nr_channels]
    H --> I[Probe dma channel]
    I --> J[Increment chan_id]
    H -->|Repeat for each channel| H
    H --> K[Update nr_channels in xdev]
    K --> L[Return 0]
    L --> M[End xilinx_dma_child_probe]

Function xilinx_dma_probe(struct platform_device *pdev)

xilinx_dma_probe: The function of xilinx_dma_probe is to initialize and set up the Xilinx DMA engine device.

parameters: The parameters of this Function. · pdev: A pointer to the platform_device structure representing the device being probed.

Code Description: The xilinx_dma_probe function is responsible for initializing the Xilinx DMA engine when the device is probed by the kernel. It begins by defining a function pointer for clock initialization, which is set to the axivdma_clk_init function. The device node associated with the platform device is retrieved, and a new xilinx_dma_device structure is allocated and initialized. If the device node is valid, the function attempts to match it against known device IDs to configure the DMA settings accordingly.

The function then calls the clock initialization function, passing the platform device and pointers to the clock variables. If the initialization fails, it returns the error code. Next, it retrieves the I/O memory resource for the device and maps it into the device's address space. If this mapping fails, it returns the corresponding error.

The function reads various properties from the device tree, such as whether scatter-gather (SG) is supported, the maximum buffer length, and specific DMA engine configurations based on the type of DMA being used (AXIDMA or VDMA). It also sets the DMA mask bits based on the address width property read from the device tree.

The DMA engine is then initialized, and capabilities are set based on the DMA type. The function prepares the DMA engine's channel resources and registers the DMA engine with the core. It also initializes child nodes representing DMA channels and registers the DMA controller with the device tree.

Finally, the function logs the successful probing of the DMA engine and returns 0. If any errors occur during the process, it performs cleanup by disabling clocks and removing any allocated channel resources before returning the error code.

Note: It is essential to ensure that the device tree properties are correctly defined for the DMA engine to function as expected. The function handles various DMA types and configurations, so understanding the specific requirements for each type is crucial.

Output Example: A successful return value from the function would be 0, indicating that the Xilinx DMA engine has been successfully probed and initialized. If an error occurs, the function may return a negative error code, such as -ENOMEM for memory allocation failure or other specific error codes based on the encountered issue.

graph TD
    A[Start xilinx_dma_probe] --> B[Allocate DMA engine structure]
    B --> C{Check allocation success}
    C -- Yes --> D[Initialize device structure]
    C -- No --> E[Return -ENOMEM]

    D --> F[Match device tree node]
    F --> G{Is match valid?}
    G -- Yes --> H[Set DMA config and clock init]
    G -- No --> I[Continue without config]

    H --> J[Call clock initialization]
    I --> J

    J --> K{Check clock init success}
    K -- Yes --> L[Request and map I/O memory]
    K -- No --> E

    L --> M{Check I/O memory mapping success}
    M -- Yes --> N[Retrieve DMA properties]
    M -- No --> E

    N --> O[Check DMA type]
    O --> P{Is DMA type AXIDMA?}
    P -- Yes --> Q[Handle AXIDMA specific properties]
    P -- No --> R{Is DMA type VDMA?}
    R -- Yes --> S[Handle VDMA specific properties]
    R -- No --> T[Continue with common properties]

    Q --> U[Set max buffer length]
    S --> V[Read num frames and flush fsync]
    T --> W[Read addr width]

    W --> X{Check addr width}
    X -- Yes --> Y[Set external address flag]
    X -- No --> Z[Set internal address flag]

    Y --> AA[Set DMA mask bits]
    Z --> AA

    AA --> AB[Initialize DMA engine]
    AB --> AC[Set channel resources]
    AC --> AD[Initialize channels]

    AD --> AE{Check child nodes}
    AE -- Yes --> AF[Probe child nodes]
    AE -- No --> AG[Register DMA engine]

    AF --> AG

    AG --> AH[Register DMA controller]
    AH --> AI{Check registration success}
    AI -- Yes --> AJ[Log driver probed message]
    AI -- No --> AK[Handle registration error]

    AJ --> AL[Return 0]
    AK --> AM[Disable clocks and clean up]
    AM --> AL

    AL --> AN[End xilinx_dma_probe]

Function xilinx_dma_remove(struct platform_device *pdev)

xilinx_dma_remove: The function of xilinx_dma_remove is to cleanly remove a Xilinx DMA device from the system.

parameters: The parameters of this Function. · pdev: A pointer to the platform_device structure representing the device to be removed.

Code Description: The xilinx_dma_remove function is responsible for the cleanup and removal of a Xilinx DMA device from the system. It begins by retrieving the associated xilinx_dma_device structure using the platform_get_drvdata function, which allows access to the device-specific data stored in the platform device.

The function then calls of_dma_controller_free with the device's device tree node to release any resources allocated for the DMA controller. This is crucial for preventing memory leaks and ensuring that the DMA controller is properly deactivated.

Next, the function unregisters the DMA device from the asynchronous DMA framework using dma_async_device_unregister. This step is essential to notify the system that the DMA device is no longer available for use, allowing other components to safely interact with the system.

The function then enters a loop that iterates over all DMA channels associated with the device. For each channel that is not NULL, it calls xilinx_dma_chan_remove to perform any necessary cleanup for that specific channel. This ensures that all resources related to the DMA channels are properly released.

Finally, the function calls xdma_disable_allclks to disable all clocks associated with the DMA device, ensuring that no unnecessary power is consumed after the device has been removed.

The function concludes by returning 0, indicating successful completion of the removal process.

Note: It is important to ensure that this function is called in the appropriate context, typically during the device removal process, to avoid resource leaks and ensure system stability.

Output Example: The function will return 0 upon successful execution, indicating that the Xilinx DMA device has been removed without errors.

graph TD
    A[Start xilinx_dma_remove] --> B[Get device data from platform]
    B --> C[Free DMA controller resources]
    C --> D[Unregister async DMA device]
    D --> E[Loop through DMA channels]
    E --> F{Is channel available?}
    F -- Yes --> G[Remove DMA channel]
    F -- No --> H[Continue to next channel]
    G --> H
    H --> E
    E --> I[Disable all clocks]
    I --> J[Return success]
    J --> K[End xilinx_dma_remove]