Commit 50a86c94 authored by Miguel Jimenez Lopez's avatar Miguel Jimenez Lopez

Update IRQ mechanism for SPEC driver.

parent 4fe1ede4
......@@ -158,30 +158,20 @@ static struct irq_chip spec_irq_gpio_chip = {
.irq_set_type = spec_irq_gpio_set_type,
};
// FIXME: To be commented
static int spec_irq_gpio_domain_select(struct irq_domain *d, struct irq_fwspec *fwspec,
enum irq_domain_bus_token bus_token)
{
char * name;
if(!d) {
printk("%s: IRQ Domain is NULL \n",__func__);
return 0;
}
if(!fwspec) {
printk("%s: Device node is NULL \n",__func__);
return 0;
}
name = (char *) fwspec->fwnode;
if (strcmp(d->name, name) == 0)
return 1;
else
//struct spec_dev *spec = d->host_data;
//struct device *dev = &spec->pdev->dev;
uint32_t dev_u32, req_u32;
if(fwspec->param_count != 1)
return 0;
return 0;
dev_u32 = 0;
req_u32 = fwspec->param[0];
return (dev_u32 == req_u32);
}
/**
......
......@@ -9,6 +9,10 @@
#include <linux/firmware.h>
#include <linux/types.h>
#include <linux/platform_device.h>
#include <linux/sched.h>
#include <linux/time.h>
#include <linux/delay.h>
#include <linux/workqueue.h>
#include <linux/fmc.h>
#include <linux/fmc-sdb.h>
......@@ -87,6 +91,7 @@ struct fpga_dev {
unsigned int n_cores; /**< Number of elements in the cores list **/
struct platform_device dev; /**< Linux platform device for the FPGA device **/
void *priv; /**< Private data for FPGA dev */
int dev_registered; /**< Linux platform device has been registered into system **/
};
......@@ -130,8 +135,16 @@ static void fpga_dev_release(struct device *dev){}
#define FPGA_DEV_CREATE(id,name_dev,vendor_id,product_id) \
FPGA_DEV_CREATE_FULL(id,name_dev,vendor_id,product_id,0,0)
// VIC FPGA device
#define FPGA_DEVS_VIC_DEV 0
#define FPGA_DEVS_VIC_DEV_NAME "spec-vic"
#define FPGA_DEVS_VIC_DEV_VIC 0
#define FPGA_DEVS_VIC_DEV_VIC_IRQ 9
#define FPGA_DEVS_VIC_DEV_NUM 1
#define FPGA_DEVS_VIC_DEV_PDEV_NAME "htvic-spec"
#define FPGA_DEVS_VIC_DEV_PDEV_RELEASE_F fpga_dev_release
// NIC FPGA device
#define FPGA_DEVS_NIC_DEV 0
#define FPGA_DEVS_NIC_DEV 1
#define FPGA_DEVS_NIC_DEV_NAME "spec-nic"
#define FPGA_DEVS_NIC_DEV_NIC 0
#define FPGA_DEVS_NIC_DEV_NIC_IRQ 1
......@@ -142,14 +155,6 @@ static void fpga_dev_release(struct device *dev){}
#define FPGA_DEVS_NIC_DEV_NUM 4
#define FPGA_DEVS_NIC_DEV_PDEV_NAME "spec-nic"
#define FPGA_DEVS_NIC_DEV_PDEV_RELEASE_F fpga_dev_release
// VIC FPGA device
#define FPGA_DEVS_VIC_DEV 1
#define FPGA_DEVS_VIC_DEV_NAME "spec-vic"
#define FPGA_DEVS_VIC_DEV_VIC 0
#define FPGA_DEVS_VIC_DEV_VIC_IRQ 9
#define FPGA_DEVS_VIC_DEV_NUM 1
#define FPGA_DEVS_VIC_DEV_PDEV_NAME "htvic-spec"
#define FPGA_DEVS_VIC_DEV_PDEV_RELEASE_F fpga_dev_release
// DIO FPGA device
#define FPGA_DEVS_DIO_DEV 2
#define FPGA_DEVS_DIO_DEV_NAME "spec-fmc-dio"
......@@ -164,6 +169,10 @@ static void fpga_dev_release(struct device *dev){}
// Global structure for FPGA devices
static struct fpga_dev fpga_devs[] =
{
/* VIC */
FPGA_DEVS_CREATE_BEGIN_DEV(FPGA_DEVS_VIC_DEV,FPGA_DEVS_VIC_DEV_NAME)
FPGA_DEV_CREATE_SFULL(FPGA_DEVS_VIC_DEV_VIC,SDB_VIC_NAME,SDB_CERN_VENDOR,SDB_VIC_PID,FPGA_DEVS_VIC_DEV_VIC_IRQ)
FPGA_DEVS_CREATE_END_DEV(FPGA_DEVS_VIC_DEV_NUM,FPGA_DEVS_VIC_DEV_PDEV_NAME,FPGA_DEVS_VIC_DEV_PDEV_RELEASE_F)
/* NIC */
FPGA_DEVS_CREATE_BEGIN_DEV(FPGA_DEVS_NIC_DEV,FPGA_DEVS_NIC_DEV_NAME)
FPGA_DEV_CREATE_SFULL(FPGA_DEVS_NIC_DEV_NIC,SDB_NIC_NAME,SDB_CERN_VENDOR,SDB_NIC_PID,FPGA_DEVS_NIC_DEV_NIC_IRQ)
......@@ -171,10 +180,6 @@ static struct fpga_dev fpga_devs[] =
FPGA_DEV_CREATE_SFULL(FPGA_DEVS_NIC_DEV_TXTSU,SDB_TXTSU_NAME,SDB_CERN_VENDOR,SDB_TXTSU_PID,FPGA_DEVS_NIC_DEV_TXTSU_IRQ)
FPGA_DEV_CREATE(FPGA_DEVS_NIC_DEV_PPSG,SDB_PPSG_NAME,SDB_CERN_VENDOR,SDB_PPSG_PID)
FPGA_DEVS_CREATE_END_DEV(FPGA_DEVS_NIC_DEV_NUM,FPGA_DEVS_NIC_DEV_PDEV_NAME,FPGA_DEVS_NIC_DEV_PDEV_RELEASE_F)
/* VIC */
FPGA_DEVS_CREATE_BEGIN_DEV(FPGA_DEVS_VIC_DEV,FPGA_DEVS_VIC_DEV_NAME)
FPGA_DEV_CREATE_SFULL(FPGA_DEVS_VIC_DEV_VIC,SDB_VIC_NAME,SDB_CERN_VENDOR,SDB_VIC_PID,FPGA_DEVS_VIC_DEV_VIC_IRQ)
FPGA_DEVS_CREATE_END_DEV(FPGA_DEVS_VIC_DEV_NUM,FPGA_DEVS_VIC_DEV_PDEV_NAME,FPGA_DEVS_VIC_DEV_PDEV_RELEASE_F)
/* DIO */
FPGA_DEVS_CREATE_BEGIN_DEV(FPGA_DEVS_DIO_DEV,FPGA_DEVS_DIO_DEV_NAME)
FPGA_DEV_CREATE_SFULL(FPGA_DEVS_DIO_DEV_DIO,SDB_DIO_NAME,SDB_7SOLS_VENDOR,SDB_DIO_PID,FPGA_DEVS_DIO_DEV_DIO_IRQ)
......@@ -196,7 +201,7 @@ static struct fpga_dev fpga_devs[] =
*
* @return 0 if success and a negative error code otherwise
*/
static int spec_sdb_fpga_dev_register(struct fmc_device *fmc, struct fpga_dev *fdev, void *priv)
static int spec_sdb_fpga_dev_register(struct fmc_device *fmc, struct fpga_dev *fdev)
{
signed long start;
unsigned long size;
......@@ -214,7 +219,7 @@ static int spec_sdb_fpga_dev_register(struct fmc_device *fmc, struct fpga_dev *f
if(fdev->cores[i].has_irq)
n_irqs++;
n_res = fdev->n_cores+n_irqs+1;
n_res = fdev->n_cores+n_irqs;
res = kzalloc(sizeof(*res)*n_res, GFP_KERNEL);
if(!res)
......@@ -248,16 +253,10 @@ static int spec_sdb_fpga_dev_register(struct fmc_device *fmc, struct fpga_dev *f
}
// Resource for the PCIe Bus identifiers
res[j].name = "PCIe-BUS";
res[j].flags = IORESOURCE_BUS;
res[j].start = spec->pdev->bus->number;
res[j].end = spec->pdev->devfn;
fdev->dev.resource = res;
fdev->dev.num_resources = n_res;
platform_set_drvdata(&fdev->dev,priv);
platform_set_drvdata(&fdev->dev,fdev->priv);
r = platform_device_register(&fdev->dev);
if(r) {
......@@ -271,6 +270,58 @@ static int spec_sdb_fpga_dev_register(struct fmc_device *fmc, struct fpga_dev *f
return r;
}
//static struct irq_domain * irq_find_irqdomain(uint32_t id)
static struct irq_domain * irq_find_irqdomain(struct device *dev)
{
struct irq_fwspec fwspec;
memset(&fwspec,0,sizeof(fwspec));
//fwspec.param_count = 1;
//fwspec.param[0] = id;
fwspec.param_count = 2;
fwspec.param[0] = (uint32_t) (((unsigned long) dev) >> 32);
fwspec.param[1] = (uint32_t) (((unsigned long) dev) & 0xFFFFFFFF);
return irq_find_matching_fwspec(&fwspec,DOMAIN_BUS_ANY);
}
struct work_struct fpga_cores_register_wq;
#define FPGA_CORES_REG_WQ_SLEEP_MS 1000
void spec_sdb_fpga_dev_register_wq(struct work_struct *work)
{
struct device *dev = &fpga_devs[FPGA_DEVS_VIC_DEV].dev.dev;
struct irq_domain *d;
struct fmc_device *fmc = fpga_devs[FPGA_DEVS_DIO_DEV].priv;
int i,j,r;
// Wait until VIC driver has been installed
while(dev->driver == NULL) {
msleep(FPGA_CORES_REG_WQ_SLEEP_MS);
}
// Map IRQs for the rest of the modules
d = irq_find_irqdomain(dev);
for(i = 1 ; i < ARRAY_SIZE(fpga_devs) ; i++) {
for(j = 0 ; j < fpga_devs[i].n_cores ; j++) {
if(fpga_devs[i].cores[j].has_irq) {
fpga_devs[i].cores[j].irq = irq_find_mapping(d,
fpga_devs[i].cores[j].irq);
}
}
}
// Register the rest of modules
for(i = 1 ; i < ARRAY_SIZE(fpga_devs) ; i++) {
r = spec_sdb_fpga_dev_register(fmc,&fpga_devs[i]);
if(r != 0)
dev_err(&fmc->dev,"%s: %s could not be registered! \n",
__func__,fpga_devs[i].name);
}
}
/**
* Register Linux platform devices for the all FPGA resources.
*
......@@ -282,21 +333,28 @@ int spec_sdb_fpga_dev_register_all(struct fmc_device *fmc)
{
int i;
int r;
void *priv;
for(i = 0 ; i < ARRAY_SIZE(fpga_devs) ; i++) {
if(i == FPGA_DEVS_DIO_DEV) {
priv = (void *) fmc;
}
else {
priv = (void *) fmc->fpga_base;
}
r = spec_sdb_fpga_dev_register(fmc,&fpga_devs[i],priv);
if(r != 0)
dev_err(&fmc->dev,"%s: %s could not be registered! \n",
__func__,fpga_devs[i].name);
}
struct spec_dev *spec = fmc->carrier_data;
struct irq_domain *domain = spec->gpio_domain;
// Init workqueue for the delayed registration
INIT_WORK(&fpga_cores_register_wq, spec_sdb_fpga_dev_register_wq);
// Set private information
for(i = 0 ; i < ARRAY_SIZE(fpga_devs) ; i++)
fpga_devs[i].priv = (i == FPGA_DEVS_DIO_DEV) ?
(void *) fmc : fmc->fpga_base;
// Find Linux IRQ for VIC
fpga_devs[FPGA_DEVS_VIC_DEV].cores[FPGA_DEVS_VIC_DEV_VIC].irq =
irq_find_mapping(domain, FPGA_DEVS_VIC_DEV_VIC_IRQ);
// Register VIC
r = spec_sdb_fpga_dev_register(fmc,&fpga_devs[FPGA_DEVS_VIC_DEV]);
if(r != 0)
dev_err(&fmc->dev,"%s: %s could not be registered! \n",
__func__,fpga_devs[0].name);
// Schedule worqueue
schedule_work(&fpga_cores_register_wq);
return 0;
}
......
Markdown is supported
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