Commit 8a5068c7 authored by Jens Korinth's avatar Jens Korinth

Backport new VC709 driver to Tapasco

parent 4f9d515b
...@@ -6,7 +6,7 @@ obj-m := ffLink.o ...@@ -6,7 +6,7 @@ obj-m := ffLink.o
# composition of files needed to compile # composition of files needed to compile
# one can exchange dual_dma_ctrl with cdma_dma_ctrl, when dma engine from Xilinx is used # one can exchange dual_dma_ctrl with cdma_dma_ctrl, when dma engine from Xilinx is used
ffLink-objs := pcie_device.o dual_dma_ctrl.o char_device_dma.o char_device_user.o ffLink_driver.o ffLink-objs := pcie_device.o blue_dma_ctrl.o char_device_dma.o char_device_user.o ffLink_driver.o dual_dma_ctrl.o dma_ctrl.o
# Path to kernel headers for compilation (path to home can be specific to os) # Path to kernel headers for compilation (path to home can be specific to os)
LNX=$(shell uname -r) LNX=$(shell uname -r)
......
// //
// Copyright (C) 2014 David de la Chevallerie, TU Darmstadt // Copyright (C) 2017 Jaco A. Hofmann, TU Darmstadt
// //
// This file is part of Tapasco (TPC). // This file is part of Tapasco (TPC).
// //
...@@ -17,8 +17,8 @@ ...@@ -17,8 +17,8 @@
// along with Tapasco. If not, see <http://www.gnu.org/licenses/>. // along with Tapasco. If not, see <http://www.gnu.org/licenses/>.
// //
/** /**
* @file cdma_dma_ctrl.c * @file dual_dma_ctrl.c
* @brief Implementation of Xilinx dma engine specific code * @brief Implementation of custom dma engine specific code
Strips the layout of the dma-registers and setup stuff to start a dma transfer Strips the layout of the dma-registers and setup stuff to start a dma transfer
in addition calls to acknowledge the interrupt in hw is given in addition calls to acknowledge the interrupt in hw is given
* */ * */
...@@ -30,21 +30,13 @@ ...@@ -30,21 +30,13 @@
/******************************************************************************/ /******************************************************************************/
/* Register Map and commands */ /* Register Map and commands */
#define REG_CDMACR 0x00 /* slv_reg0 = CDMA Control */ #define REG_HOST_ADDR 0x00 /* slv_reg0 = PCIe addr */
#define REG_CDMASR 0x04 /* slv_reg1 = CDMA Status */ #define REG_FPGA_ADDR 0x08 /* slv_reg1 = FPGA addr */
#define REG_CURDESC_PNTR 0x08 /* slv_reg2 = Current Descriptor Pointer */ #define REG_BTT 0x10 /* slv_reg2 = bytes to transfer */
#define REG_CURDESC_PNTR_MSB 0x0C /* slv_reg3 = Current Descriptor Pointer (MSB 32 bits) */ #define REG_CMD 0x20 /* slv_reg3 = CMD */
#define REG_TAILDESC_PNTR 0x10 /* slv_reg4 = Tail Descriptor Pointer */
#define REG_TAILDESC_PNTR_MSB 0x14 /* slv_reg5 = Tail Descriptor Pointer (MSB 32 bits) */
#define REG_SA 0x18 /* slv_reg6 = Source Address */
#define REG_SA_MSB 0x1C /* slv_reg7 = Source Address (MSB 32 bits) */
#define REG_DA 0x20 /* slv_reg8 = Destination Address */
#define REG_DA_MSB 0x24 /* slv_reg9 = Destination Address (MSB 32 bits) */
#define REG_BTT 0x28 /* slv_regA = Bytes to Transfer */
#define CMD_IRQ_EN 0x00001000 /* enables interrupt for transfers in control register */ #define CMD_READ 0x10001000 /* from m64 fpga memory to m64 host memory */
#define CMD_ACK 0x00001000 /* acknowledge data transfer to toggle interrupt in status register */ #define CMD_WRITE 0x10000001 /* from m64 host memory to m64 fpga memory */
#define PCIE_OFF 0x00000008 /* offset to address pcie core */
/* mutex to sequentialize access to dma registers */ /* mutex to sequentialize access to dma registers */
//static DEFINE_MUTEX(dma_regs_mutex); //static DEFINE_MUTEX(dma_regs_mutex);
...@@ -52,73 +44,14 @@ ...@@ -52,73 +44,14 @@
/******************************************************************************/ /******************************************************************************/
/* functions for irq-handling */ /* functions for irq-handling */
/**
* @brief Acknowledge interrupt in hardware and wake up corresponding process
* @param i minor node corresponding to this irq
* @return none
* */
void ack_irq(int i)
{
fflink_info("Handle device number %d\n", i);
/* ack interrupt */
pcie_writel(CMD_ACK, get_dev_addr(i) + REG_CDMASR);
/* Set priv data for more minor nodes accordingly */
wake_up_queue(i);
}
/** /**
* @brief Interrupt handler for dma engine 0 * @brief Interrupt handler for dma engine 0
* @param irq Interrupt number of calling line * @param irq Interrupt number of calling line
* @param dev_id magic number for interrupt sharing (not needed) * @param dev_id magic number for interrupt sharing (not needed)
* @return Tells OS, that irq is handled properly * @return Tells OS, that irq is handled properly
* */ * */
irqreturn_t intr_handler_dma_0(int irq, void * dev_id) irqreturn_t blue_dma_intr_handler(int irq, void * dev_id)
{
fflink_info("Interrupt called with irq %d\n", irq);
ack_irq(0);
return IRQ_HANDLED;
}
/**
* @brief Interrupt handler for dma engine 1
* @param irq Interrupt number of calling line
* @param dev_id magic number for interrupt sharing (not needed)
* @return Tells OS, that irq is handled properly
* */
irqreturn_t intr_handler_dma_1(int irq, void * dev_id)
{ {
fflink_info("Interrupt called with irq %d\n", irq);
ack_irq(1);
return IRQ_HANDLED;
}
/**
* @brief Interrupt handler for dma engine 2
* @param irq Interrupt number of calling line
* @param dev_id magic number for interrupt sharing (not needed)
* @return Tells OS, that irq is handled properly
* */
irqreturn_t intr_handler_dma_2(int irq, void * dev_id)
{
fflink_info("Interrupt called with irq %d\n", irq);
ack_irq(2);
return IRQ_HANDLED;
}
/**
* @brief Interrupt handler for dma engine 3
* @param irq Interrupt number of calling line
* @param dev_id magic number for interrupt sharing (not needed)
* @return Tells OS, that irq is handled properly
* */
irqreturn_t intr_handler_dma_3(int irq, void * dev_id)
{
fflink_info("Interrupt called with irq %d\n", irq);
ack_irq(3);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
...@@ -132,24 +65,22 @@ irqreturn_t intr_handler_dma_3(int irq, void * dev_id) ...@@ -132,24 +65,22 @@ irqreturn_t intr_handler_dma_3(int irq, void * dev_id)
* @param device_base_addr Address of dma engine registers * @param device_base_addr Address of dma engine registers
* @return none * @return none
* */ * */
void transmit_from_device(void * device_buffer, dma_addr_t host_handle, int btt, void * device_base_addr) void blue_dma_transmit_from_device(void * device_buffer, dma_addr_t host_handle, int btt, void * device_base_addr)
{ {
fflink_info("dev_buf %lX dma_handle %lX \nsize %d dev_base %lX\n", (unsigned long) device_buffer, (unsigned long) host_handle, btt, (unsigned long) device_base_addr); fflink_info("dev_buf %lX dma_handle %lX \nsize %d dev_base %lX\n", (unsigned long) device_buffer, (unsigned long) host_handle, btt, (unsigned long) device_base_addr);
//if(mutex_lock_interruptible(&dma_regs_mutex)) //if(mutex_lock_interruptible(&dma_regs_mutex))
// fflink_warn("got killed while aquiring the mutex\n"); // fflink_warn("got killed while aquiring the mutex\n");
/* activate interrupts */
pcie_writel(CMD_IRQ_EN, device_base_addr + REG_CDMACR);
/* SA */ /* SA */
pcie_writel((unsigned long) device_buffer, device_base_addr + REG_SA); pcie_writel((unsigned long)device_buffer, device_base_addr + REG_FPGA_ADDR);
pcie_writel(0, device_base_addr + REG_SA_MSB);
/* DA */ /* DA */
pcie_writel(host_handle, device_base_addr + REG_DA); pcie_writel(host_handle, device_base_addr + REG_HOST_ADDR);
pcie_writel(PCIE_OFF, device_base_addr + REG_DA_MSB); /* btt */
pcie_writel(btt, device_base_addr + REG_BTT);
/* presvious data have to be written first */ /* presvious data have to be written first */
wmb(); wmb();
/* btt and start */ /* start cmd */
pcie_writel(btt, device_base_addr + REG_BTT); pcie_writel(CMD_READ, device_base_addr + REG_CMD);
//mutex_unlock(&dma_regs_mutex); //mutex_unlock(&dma_regs_mutex);
} }
...@@ -162,24 +93,22 @@ void transmit_from_device(void * device_buffer, dma_addr_t host_handle, int btt, ...@@ -162,24 +93,22 @@ void transmit_from_device(void * device_buffer, dma_addr_t host_handle, int btt,
* @param device_base_addr Address of dma engine registers * @param device_base_addr Address of dma engine registers
* @return none * @return none
* */ * */
void transmit_to_device(void * device_buffer, dma_addr_t host_handle, int btt, void * device_base_addr) void blue_dma_transmit_to_device(void * device_buffer, dma_addr_t host_handle, int btt, void * device_base_addr)
{ {
fflink_info("dev_buf %lX dma_handle %lX \nsize %d dev_base %lX\n", (unsigned long) device_buffer, (unsigned long) host_handle, btt, (unsigned long) device_base_addr); fflink_info("dev_buf %lX dma_handle %lX \nsize %d dev_base %lX\n", (unsigned long) device_buffer, (unsigned long) host_handle, btt, (unsigned long) device_base_addr);
//if(mutex_lock_interruptible(&dma_regs_mutex)) //if(mutex_lock_interruptible(&dma_regs_mutex))
// fflink_warn("got killed while aquiring the mutex\n"); // fflink_warn("got killed while aquiring the mutex\n");
/* activate interrupts */
pcie_writel(CMD_IRQ_EN, device_base_addr + REG_CDMACR);
/* SA */ /* SA */
pcie_writel(host_handle, device_base_addr + REG_SA); pcie_writel(host_handle, device_base_addr + REG_HOST_ADDR);
pcie_writel(PCIE_OFF, device_base_addr + REG_SA_MSB);
/* DA */ /* DA */
pcie_writel((unsigned long) device_buffer, device_base_addr + REG_DA); pcie_writel((unsigned long)device_buffer, device_base_addr + REG_FPGA_ADDR);
pcie_writel(0, device_base_addr + REG_DA_MSB); /* btt */
pcie_writel(btt, device_base_addr + REG_BTT);
/* presvious data have to be written first */ /* presvious data have to be written first */
wmb(); wmb();
/* btt and start */ /* start cmd */
pcie_writel(btt, device_base_addr + REG_BTT); pcie_writel(CMD_WRITE, device_base_addr + REG_CMD);
//mutex_unlock(&dma_regs_mutex); //mutex_unlock(&dma_regs_mutex);
} }
......
This diff is collapsed.
...@@ -73,53 +73,31 @@ ...@@ -73,53 +73,31 @@
/******************************************************************************/ /******************************************************************************/
/* number of device, which will be created for dma engines */
#define FFLINK_DMA_NODES 1
/* activate double buffering ( == 1) */
#define FFLINK_DOUBLE_BUFFERING 2
/* physical address of dma core in register map from vivado */ /* physical address of dma core in register map from vivado */
#define DMA_BASE_ADDR_0 0x300000 #define DMA_BASE_ADDR_0 0x300000
#define DMA_BASE_ADDR_1 0x310000
#define DMA_BASE_ADDR_2 0x320000
#define DMA_BASE_ADDR_3 0x330000
#define AXI_CTRL_BASE_ADDR 0x100000 #define AXI_CTRL_BASE_ADDR 0x100000
/* BRAM standard address */ /* BRAM standard address */
#define RAM_BASE_ADDR_0 0x80000000 #define RAM_BASE_ADDR_0 0x80000000
#define RAM_BASE_ADDR_1 0xA0000000
#define RAM_BASE_ADDR_2 0xC0000000
#define RAM_BASE_ADDR_3 0xE0000000
/* to change buffer_size increase or decrease the order of pages */ /* to change buffer_size increase or decrease the order of pages */
#define BUFFER_ORDER (MAX_ORDER -1) #define BUFFER_ORDER (MAX_ORDER -1)
#define BUFFER_SIZE (PAGE_SIZE * (1 << BUFFER_ORDER)) #define BUFFER_SIZE (PAGE_SIZE * (1 << BUFFER_ORDER))
/* change size, when double buffering becomes activated */
#define DOUBLE_BUFFER_LIMIT 262144
#define BUFFER_SIZE_USED (PAGE_SIZE * (1 << (MAX_ORDER -3)))
/* device name to register fops with /* device name to register fops with
* fops will append a number to name for multiple minor nodes */ * fops will append a number to name for multiple minor nodes */
#define FFLINK_DMA_NAME "FFLINK_DMA_DEVICE" #define FFLINK_DMA_NAME "FFLINK_DMA_DEVICE"
/* Count of buffers allocated for each device in each direction */
#define PBUF_SIZE 3
/******************************************************************************/ /******************************************************************************/
/* struct array to hold data over multiple fops-calls */ /* struct array to hold data over multiple fops-calls */
struct priv_data_struct { struct priv_data_struct {
unsigned int minor; void * kvirt_h2l;
void * kvirt_l2h;
struct page * pbuf_h2l[PBUF_SIZE];
struct page * pbuf_l2h[PBUF_SIZE]; dma_addr_t dma_handle_h2l;
void * kvirt_pbuf_h2l[PBUF_SIZE]; dma_addr_t dma_handle_l2h;
void * kvirt_pbuf_l2h[PBUF_SIZE];
dma_addr_t dma_handle_h2l[PBUF_SIZE];
dma_addr_t dma_handle_l2h[PBUF_SIZE];
void * mem_addr_l2h; void * mem_addr_l2h;
void * mem_addr_h2l; void * mem_addr_h2l;
...@@ -133,9 +111,6 @@ struct priv_data_struct { ...@@ -133,9 +111,6 @@ struct priv_data_struct {
unsigned int cache_lsize; unsigned int cache_lsize;
unsigned int cache_mask; unsigned int cache_mask;
struct mutex mmap_rbuf_mutex;
struct mutex mmap_wbuf_mutex;
}; };
/******************************************************************************/ /******************************************************************************/
...@@ -146,28 +121,21 @@ static int dma_close(struct inode *, struct file *); ...@@ -146,28 +121,21 @@ static int dma_close(struct inode *, struct file *);
static long dma_ioctl(struct file *, unsigned int, unsigned long); static long dma_ioctl(struct file *, unsigned int, unsigned long);
static ssize_t dma_read(struct file *, char __user *, size_t count, loff_t *); static ssize_t dma_read(struct file *, char __user *, size_t count, loff_t *);
static ssize_t dma_write(struct file *, const char __user *, size_t count, loff_t *); static ssize_t dma_write(struct file *, const char __user *, size_t count, loff_t *);
static int dma_mmap(struct file *filp, struct vm_area_struct *vma);
/******************************************************************************/ /******************************************************************************/
/* helper functions called for sys-calls */ /* helper functions called for sys-calls */
static void dma_page_to_virt(struct priv_data_struct * p);
static unsigned int dma_cache_fit(unsigned int btt); static unsigned int dma_cache_fit(unsigned int btt);
static int dma_alloc_pbufs(struct page * p[], dma_addr_t handle[], gfp_t, int); static int dma_alloc_pbufs(void** p, dma_addr_t *handle, gfp_t zone, int direction);
static void dma_free_pbufs(struct page * p[], dma_addr_t handle[], int direction); static void dma_free_pbufs(void *p, dma_addr_t handle, int direction);
static void transmit_to_user(void *, void *, dma_addr_t, int); static void transmit_to_user(void *, void *, dma_addr_t, int);
static void transmit_from_user(void *, void *, dma_addr_t, int); static void transmit_from_user(void *, void *, dma_addr_t, int);
static unsigned int calc_transfer_size(int count);
static void switch_index(unsigned int * a, unsigned int * b);
/******************************************************************************/ /******************************************************************************/
/* overload function to exchange bounce-/double-buffering */ /* overload function to exchange bounce-/double-buffering */
static int read_with_double(int count, char __user *buf, void * mem_addr, struct priv_data_struct *p);
static int read_with_bounce(int count, char __user *buf, void * mem_addr, struct priv_data_struct *p); static int read_with_bounce(int count, char __user *buf, void * mem_addr, struct priv_data_struct *p);
static inline int read_device(int count, char __user *buf, void * mem_addr, struct priv_data_struct *p); static inline int read_device(int count, char __user *buf, void * mem_addr, struct priv_data_struct *p);
static int write_with_double(int count, const char __user *buf, void * mem_addr, struct priv_data_struct *p);
static int write_with_bounce(int count, const char __user *buf, void * mem_addr, struct priv_data_struct *p); static int write_with_bounce(int count, const char __user *buf, void * mem_addr, struct priv_data_struct *p);
static inline int write_device(int count, const char __user *buf, void * mem_addr, struct priv_data_struct *p); static inline int write_device(int count, const char __user *buf, void * mem_addr, struct priv_data_struct *p);
......
...@@ -43,6 +43,9 @@ struct pci_dev* get_pcie_dev(void); ...@@ -43,6 +43,9 @@ struct pci_dev* get_pcie_dev(void);
void pcie_writel(unsigned long data, void * addr); void pcie_writel(unsigned long data, void * addr);
unsigned long pcie_readl(void * addr); unsigned long pcie_readl(void * addr);
void pcie_writel_bar2(unsigned long data, void * addr);
unsigned long pcie_readl_bar2(void * addr);
/******************************************************************************/ /******************************************************************************/
#endif // __DEVICE_PCIE_H #endif // __DEVICE_PCIE_H
...@@ -67,12 +67,10 @@ ...@@ -67,12 +67,10 @@
/******************************************************************************/ /******************************************************************************/
void dma_ctrl_init(void * device_base_addr);
/* interrupt handler used by dma engines registered in pcie_device.c */ /* interrupt handler used by dma engines registered in pcie_device.c */
void ack_irq(int i); irqreturn_t intr_handler_dma(int irq, void * dev_id);
irqreturn_t intr_handler_dma_0(int irq, void * dev_id);
irqreturn_t intr_handler_dma_1(int irq, void * dev_id);
irqreturn_t intr_handler_dma_2(int irq, void * dev_id);
irqreturn_t intr_handler_dma_3(int irq, void * dev_id);
/* setting registers to start dma transfer specific to used engine (Xilinx, custom) */ /* setting registers to start dma transfer specific to used engine (Xilinx, custom) */
void transmit_from_device(void * device_buffer, dma_addr_t host_handle, int btt, void * device_base_addr); void transmit_from_device(void * device_buffer, dma_addr_t host_handle, int btt, void * device_base_addr);
...@@ -80,4 +78,13 @@ void transmit_to_device(void * device_buffer, dma_addr_t host_handle, int btt, v ...@@ -80,4 +78,13 @@ void transmit_to_device(void * device_buffer, dma_addr_t host_handle, int btt, v
/******************************************************************************/ /******************************************************************************/
/* DMA Specific implementations */
irqreturn_t blue_dma_intr_handler(int irq, void * dev_id);
void blue_dma_transmit_from_device(void * device_buffer, dma_addr_t host_handle, int btt, void * device_base_addr);
void blue_dma_transmit_to_device(void * device_buffer, dma_addr_t host_handle, int btt, void * device_base_addr);
irqreturn_t dual_dma_intr_handler_dma(int irq, void * dev_id);
void dual_dma_transmit_from_device(void * device_buffer, dma_addr_t host_handle, int btt, void * device_base_addr);
void dual_dma_transmit_to_device(void * device_buffer, dma_addr_t host_handle, int btt, void * device_base_addr);
#endif // __DMA_CTRL_H #endif // __DMA_CTRL_H
//
// Copyright (C) 2017 Jaco A. Hofmann, TU Darmstadt
//
// This file is part of Tapasco (TPC).
//
// Tapasco is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Tapasco is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with Tapasco. If not, see <http://www.gnu.org/licenses/>.
//
/**
* @file dual_dma_ctrl.c
* @brief Implementation of custom dma engine specific code
Strips the layout of the dma-registers and setup stuff to start a dma transfer
in addition calls to acknowledge the interrupt in hw is given
* */
/******************************************************************************/
#include "common/dma_ctrl.h"
/******************************************************************************/
/******************************************************************************/
/* functions for irq-handling */
#define REG_ID 0x18
typedef enum {
DMA_USED_DUAL = 0,
DMA_USED_BLUE = 1
} dma_used_t;
typedef irqreturn_t (*dma_intr_handler)(int , void *);
typedef void (*dma_from_device)(void *, dma_addr_t, int, void *);
typedef void (*dma_to_device)(void *, dma_addr_t , int , void *);
typedef struct {
dma_intr_handler intr;
dma_from_device from_dev;
dma_to_device to_dev;
} fflink_dma_t;
static dma_used_t dma_used;
static const fflink_dma_t fflink_dma[] = {
[DMA_USED_DUAL] = {
dual_dma_intr_handler_dma,
dual_dma_transmit_from_device,
dual_dma_transmit_to_device
},
[DMA_USED_BLUE] = {
blue_dma_intr_handler,
blue_dma_transmit_from_device,
blue_dma_transmit_to_device
}
};
void dma_ctrl_init(void * device_base_addr)
{
if(pcie_readl(device_base_addr + REG_ID) == 0xE5A0023) {
dma_used = DMA_USED_BLUE;
fflink_warn("Detected BlueDMA\n");
} else {
dma_used = DMA_USED_DUAL;
fflink_warn("Detected DualDMA\n");
}
}
/**
* @brief Interrupt handler for dma engine 0
* @param irq Interrupt number of calling line
* @param dev_id magic number for interrupt sharing (not needed)
* @return Tells OS, that irq is handled properly
* */
irqreturn_t intr_handler_dma(int irq, void * dev_id)
{
fflink_info("Interrupt called with irq %d\n", irq);
fflink_dma[dma_used].intr(irq, dev_id);
wake_up_queue(0);
return IRQ_HANDLED;
}
/******************************************************************************/
/**
* @brief Sets register of dma_engine to start a transfer from FPGA to Main memory
* @param device_buffer FPGA memory address
* @param host_handle Handle for platform independent memory address
* @param btt Bytes to transfer
* @param device_base_addr Address of dma engine registers
* @return none
* */
void transmit_from_device(void * device_buffer, dma_addr_t host_handle, int btt, void * device_base_addr)
{
fflink_dma[dma_used].from_dev(device_buffer, host_handle, btt, device_base_addr);
}
/**
* @brief Sets register of dma_engine to start a transfer from Main memory to FPGA
* @param device_buffer FPGA memory address
* @param host_handle Handle for platform independent memory address
* @param btt Bytes to transfer
* @param device_base_addr Address of dma engine registers
* @return none
* */
void transmit_to_device(void * device_buffer, dma_addr_t host_handle, int btt, void * device_base_addr)
{
fflink_dma[dma_used].to_dev(device_buffer, host_handle, btt, device_base_addr);
}
/******************************************************************************/
...@@ -48,73 +48,15 @@ ...@@ -48,73 +48,15 @@
/******************************************************************************/ /******************************************************************************/
/* functions for irq-handling */ /* functions for irq-handling */
/**
* @brief Acknowledge interrupt in hardware and wake up corresponding process
* @param i minor node corresponding to this irq
* @return none
* */
void ack_irq(int i)
{
fflink_info("Handle device number %d\n", i);
/* ack interrupt */
pcie_writel(CMD_ACK, get_dev_addr(i) + REG_CMD);
/* Set priv data for more minor nodes accordingly */
wake_up_queue(i);
}
/** /**
* @brief Interrupt handler for dma engine 0 * @brief Interrupt handler for dma engine 0
* @param irq Interrupt number of calling line * @param irq Interrupt number of calling line
* @param dev_id magic number for interrupt sharing (not needed) * @param dev_id magic number for interrupt sharing (not needed)
* @return Tells OS, that irq is handled properly * @return Tells OS, that irq is handled properly
* */ * */
irqreturn_t intr_handler_dma_0(int irq, void * dev_id) irqreturn_t dual_dma_intr_handler_dma(int irq, void * dev_id)
{
fflink_info("Interrupt called with irq %d\n", irq);
ack_irq(0);
return IRQ_HANDLED;
}
/**
* @brief Interrupt handler for dma engine 1
* @param irq Interrupt number of calling line
* @param dev_id magic number for interrupt sharing (not needed)
* @return Tells OS, that irq is handled properly
* */
irqreturn_t intr_handler_dma_1(int irq, void * dev_id)
{ {
fflink_info("Interrupt called with irq %d\n", irq); pcie_writel(CMD_ACK, get_dev_addr(0) + REG_CMD);
ack_irq(1);
return IRQ_HANDLED;
}
/**
* @brief Interrupt handler for dma engine 2
* @param irq Interrupt number of calling line
* @param dev_id magic number for interrupt sharing (not needed)
* @return Tells OS, that irq is handled properly
* */
irqreturn_t intr_handler_dma_2(int irq, void * dev_id)
{
fflink_info("Interrupt called with irq %d\n", irq);
ack_irq(2);
return IRQ_HANDLED;
}
/**
* @brief Interrupt handler for dma engine 3
* @param irq Interrupt number of calling line
* @param dev_id magic number for interrupt sharing (not needed)
* @return Tells OS, that irq is handled properly
* */
irqreturn_t intr_handler_dma_3(int irq, void * dev_id)
{
fflink_info("Interrupt called with irq %d\n", irq);
ack_irq(3);