#include <linux/bitfield.h>
#include <linux/clk.h>
#include <linux/device.h>
#include <linux/dma-mapping.h>
#include <linux/dmaengine.h>
#include <linux/err.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_dma.h>
#include <linux/of_address.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/slab.h>
#include <linux/fpga/adi-axi-common.h>
#include <dt-bindings/dma/axi-dmac.h>
#include "dmaengine.h"
#include "virt-dma.h"
#define AXI_DMAC_REG_INTERFACE_DESC …
#define AXI_DMAC_DMA_SRC_TYPE_MSK …
#define AXI_DMAC_DMA_SRC_TYPE_GET(x) …
#define AXI_DMAC_DMA_SRC_WIDTH_MSK …
#define AXI_DMAC_DMA_SRC_WIDTH_GET(x) …
#define AXI_DMAC_DMA_DST_TYPE_MSK …
#define AXI_DMAC_DMA_DST_TYPE_GET(x) …
#define AXI_DMAC_DMA_DST_WIDTH_MSK …
#define AXI_DMAC_DMA_DST_WIDTH_GET(x) …
#define AXI_DMAC_REG_COHERENCY_DESC …
#define AXI_DMAC_DST_COHERENT_MSK …
#define AXI_DMAC_DST_COHERENT_GET(x) …
#define AXI_DMAC_REG_IRQ_MASK …
#define AXI_DMAC_REG_IRQ_PENDING …
#define AXI_DMAC_REG_IRQ_SOURCE …
#define AXI_DMAC_REG_CTRL …
#define AXI_DMAC_REG_TRANSFER_ID …
#define AXI_DMAC_REG_START_TRANSFER …
#define AXI_DMAC_REG_FLAGS …
#define AXI_DMAC_REG_DEST_ADDRESS …
#define AXI_DMAC_REG_SRC_ADDRESS …
#define AXI_DMAC_REG_X_LENGTH …
#define AXI_DMAC_REG_Y_LENGTH …
#define AXI_DMAC_REG_DEST_STRIDE …
#define AXI_DMAC_REG_SRC_STRIDE …
#define AXI_DMAC_REG_TRANSFER_DONE …
#define AXI_DMAC_REG_ACTIVE_TRANSFER_ID …
#define AXI_DMAC_REG_STATUS …
#define AXI_DMAC_REG_CURRENT_SRC_ADDR …
#define AXI_DMAC_REG_CURRENT_DEST_ADDR …
#define AXI_DMAC_REG_PARTIAL_XFER_LEN …
#define AXI_DMAC_REG_PARTIAL_XFER_ID …
#define AXI_DMAC_REG_CURRENT_SG_ID …
#define AXI_DMAC_REG_SG_ADDRESS …
#define AXI_DMAC_REG_SG_ADDRESS_HIGH …
#define AXI_DMAC_CTRL_ENABLE …
#define AXI_DMAC_CTRL_PAUSE …
#define AXI_DMAC_CTRL_ENABLE_SG …
#define AXI_DMAC_IRQ_SOT …
#define AXI_DMAC_IRQ_EOT …
#define AXI_DMAC_FLAG_CYCLIC …
#define AXI_DMAC_FLAG_LAST …
#define AXI_DMAC_FLAG_PARTIAL_REPORT …
#define AXI_DMAC_FLAG_PARTIAL_XFER_DONE …
#define AXI_DMAC_SG_UNUSED …
#define AXI_DMAC_HW_FLAG_LAST …
#define AXI_DMAC_HW_FLAG_IRQ …
struct axi_dmac_hw_desc { … };
struct axi_dmac_sg { … };
struct axi_dmac_desc { … };
struct axi_dmac_chan { … };
struct axi_dmac { … };
static struct axi_dmac *chan_to_axi_dmac(struct axi_dmac_chan *chan)
{ … }
static struct axi_dmac_chan *to_axi_dmac_chan(struct dma_chan *c)
{ … }
static struct axi_dmac_desc *to_axi_dmac_desc(struct virt_dma_desc *vdesc)
{ … }
static void axi_dmac_write(struct axi_dmac *axi_dmac, unsigned int reg,
unsigned int val)
{ … }
static int axi_dmac_read(struct axi_dmac *axi_dmac, unsigned int reg)
{ … }
static int axi_dmac_src_is_mem(struct axi_dmac_chan *chan)
{ … }
static int axi_dmac_dest_is_mem(struct axi_dmac_chan *chan)
{ … }
static bool axi_dmac_check_len(struct axi_dmac_chan *chan, unsigned int len)
{ … }
static bool axi_dmac_check_addr(struct axi_dmac_chan *chan, dma_addr_t addr)
{ … }
static void axi_dmac_start_transfer(struct axi_dmac_chan *chan)
{ … }
static struct axi_dmac_desc *axi_dmac_active_desc(struct axi_dmac_chan *chan)
{ … }
static inline unsigned int axi_dmac_total_sg_bytes(struct axi_dmac_chan *chan,
struct axi_dmac_sg *sg)
{ … }
static void axi_dmac_dequeue_partial_xfers(struct axi_dmac_chan *chan)
{ … }
static void axi_dmac_compute_residue(struct axi_dmac_chan *chan,
struct axi_dmac_desc *active)
{ … }
static bool axi_dmac_transfer_done(struct axi_dmac_chan *chan,
unsigned int completed_transfers)
{ … }
static irqreturn_t axi_dmac_interrupt_handler(int irq, void *devid)
{ … }
static int axi_dmac_terminate_all(struct dma_chan *c)
{ … }
static void axi_dmac_synchronize(struct dma_chan *c)
{ … }
static void axi_dmac_issue_pending(struct dma_chan *c)
{ … }
static struct axi_dmac_desc *
axi_dmac_alloc_desc(struct axi_dmac_chan *chan, unsigned int num_sgs)
{ … }
static void axi_dmac_free_desc(struct axi_dmac_desc *desc)
{ … }
static struct axi_dmac_sg *axi_dmac_fill_linear_sg(struct axi_dmac_chan *chan,
enum dma_transfer_direction direction, dma_addr_t addr,
unsigned int num_periods, unsigned int period_len,
struct axi_dmac_sg *sg)
{ … }
static struct dma_async_tx_descriptor *
axi_dmac_prep_peripheral_dma_vec(struct dma_chan *c, const struct dma_vec *vecs,
size_t nb, enum dma_transfer_direction direction,
unsigned long flags)
{ … }
static struct dma_async_tx_descriptor *axi_dmac_prep_slave_sg(
struct dma_chan *c, struct scatterlist *sgl,
unsigned int sg_len, enum dma_transfer_direction direction,
unsigned long flags, void *context)
{ … }
static struct dma_async_tx_descriptor *axi_dmac_prep_dma_cyclic(
struct dma_chan *c, dma_addr_t buf_addr, size_t buf_len,
size_t period_len, enum dma_transfer_direction direction,
unsigned long flags)
{ … }
static struct dma_async_tx_descriptor *axi_dmac_prep_interleaved(
struct dma_chan *c, struct dma_interleaved_template *xt,
unsigned long flags)
{ … }
static void axi_dmac_free_chan_resources(struct dma_chan *c)
{ … }
static void axi_dmac_desc_free(struct virt_dma_desc *vdesc)
{ … }
static bool axi_dmac_regmap_rdwr(struct device *dev, unsigned int reg)
{ … }
static const struct regmap_config axi_dmac_regmap_config = …;
static void axi_dmac_adjust_chan_params(struct axi_dmac_chan *chan)
{ … }
static int axi_dmac_parse_chan_dt(struct device_node *of_chan,
struct axi_dmac_chan *chan)
{ … }
static int axi_dmac_parse_dt(struct device *dev, struct axi_dmac *dmac)
{ … }
static int axi_dmac_read_chan_config(struct device *dev, struct axi_dmac *dmac)
{ … }
static int axi_dmac_detect_caps(struct axi_dmac *dmac, unsigned int version)
{ … }
static void axi_dmac_tasklet_kill(void *task)
{ … }
static void axi_dmac_free_dma_controller(void *of_node)
{ … }
static int axi_dmac_probe(struct platform_device *pdev)
{ … }
static const struct of_device_id axi_dmac_of_match_table[] = …;
MODULE_DEVICE_TABLE(of, axi_dmac_of_match_table);
static struct platform_driver axi_dmac_driver = …;
module_platform_driver(…) …;
MODULE_AUTHOR(…) …;
MODULE_DESCRIPTION(…) …;
MODULE_LICENSE(…) …;