Skip to content
Snippets Groups Projects
Commit 63418c1a authored by Alessandro Rubini's avatar Alessandro Rubini
Browse files

kernel (various): enable multi-irq


Signed-off-by: default avatarAlessandro Rubini <rubini@gnudd.com>
parent 2b7bd302
Branches
Tags
No related merge requests found
...@@ -50,7 +50,9 @@ ...@@ -50,7 +50,9 @@
#define WRN_WRC_DEFAULT_NAME "fmc/wr_nic_dio-wrc.bin" #define WRN_WRC_DEFAULT_NAME "fmc/wr_nic_dio-wrc.bin"
/* the various interrupt sources for the VIC */ /* the various interrupt sources for the VIC */
#define WRN_VIC_MASK_NIC 0x0002 #define WRN_VIC_MASK_TXTSU 0x0001
#define WRN_VIC_MASK_NIC 0x0002
#define WRN_VIC_MASK_DIO 0x0004
/* This is somehow generic, but I find no better place at this time */ /* This is somehow generic, but I find no better place at this time */
#ifndef SET_HI32 #ifndef SET_HI32
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#define __WR_DIO_H__ #define __WR_DIO_H__
/* This should be included by both the kernel and the tools */ /* This should be included by both the kernel and the tools */
#ifdef __KERNEL__
#include "wbgen-regs/wr-dio-regs.h" #include "wbgen-regs/wr-dio-regs.h"
/* For GPIO we have no wb-gen header */ /* For GPIO we have no wb-gen header */
...@@ -26,6 +27,10 @@ struct wrn_gpio_block { ...@@ -26,6 +27,10 @@ struct wrn_gpio_block {
#define WRN_GPIO_OE_N(bit) (1 << ((4 * (bit)) + 1)) #define WRN_GPIO_OE_N(bit) (1 << ((4 * (bit)) + 1))
#define WRN_GPIO_TERM(bit) (1 << ((4 * (bit)) + 2)) #define WRN_GPIO_TERM(bit) (1 << ((4 * (bit)) + 2))
extern irqreturn_t wrn_dio_interrupt(struct fmc_device *fmc);
#endif /* __KERNEL__ */
enum wr_dio_cmd_name { enum wr_dio_cmd_name {
WR_DIO_CMD_PULSE, WR_DIO_CMD_PULSE,
WR_DIO_CMD_STAMP, WR_DIO_CMD_STAMP,
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include <linux/fmc.h> #include <linux/fmc.h>
#include <linux/fmc-sdb.h> #include <linux/fmc-sdb.h>
#include <linux/ktime.h> #include <linux/ktime.h>
#include <linux/platform_device.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include "spec-nic.h" #include "spec-nic.h"
#include "wr_nic/wr-nic.h" #include "wr_nic/wr-nic.h"
...@@ -321,3 +322,14 @@ out: ...@@ -321,3 +322,14 @@ out:
} }
return ret; return ret;
} }
irqreturn_t wrn_dio_interrupt(struct fmc_device *fmc)
{
struct platform_device *pdev = fmc->mezzanine_data;
struct wrn_drvdata *drvdata = pdev->dev.platform_data;
struct DIO_WB __iomem *dio = drvdata->wrdio_base;
printk("%s: %x %x\n", __func__, readl(&dio->EIC_IMR),
readl(&dio->EIC_ISR));
return IRQ_NONE;
}
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include <linux/fmc-sdb.h> #include <linux/fmc-sdb.h>
#include "spec.h" #include "spec.h"
#include "spec-nic.h" #include "spec-nic.h"
#include "wr-dio.h"
#include "wr_nic/wr-nic.h" #include "wr_nic/wr-nic.h"
#include "wbgen-regs/vic-regs.h" #include "wbgen-regs/vic-regs.h"
...@@ -58,15 +59,15 @@ irqreturn_t wrn_handler(int irq, void *dev_id) ...@@ -58,15 +59,15 @@ irqreturn_t wrn_handler(int irq, void *dev_id)
drvdata = pdev->dev.platform_data; drvdata = pdev->dev.platform_data;
vic = (typeof(vic))drvdata->vic_base; vic = (typeof(vic))drvdata->vic_base;
mask = readl(&vic->RISR); while ( (mask = readl(&vic->RISR)) ) {
while (mask & WRN_VIC_MASK_NIC) { if (mask & WRN_VIC_MASK_NIC)
ret = wrn_interrupt(irq, drvdata->wrn); ret = wrn_interrupt(irq, drvdata->wrn);
mask = readl(&vic->RISR); if (mask & WRN_VIC_MASK_TXTSU)
ret = wrn_tstamp_interrupt(irq, drvdata->wrn);
if (mask & WRN_VIC_MASK_DIO)
ret = wrn_dio_interrupt(fmc /* different arg! */);
writel(mask, &vic->EOIR);
} }
writel(WRN_VIC_MASK_NIC, &vic->EOIR);
if (mask)
printk("%s: irq %i (mask %x)\n", __func__, irq, mask);
fmc->op->irq_ack(fmc); fmc->op->irq_ack(fmc);
/* after ack, disable and re-enable the irq, so to force an edge */ /* after ack, disable and re-enable the irq, so to force an edge */
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment