Commit 5a287e79 authored by Miguel Gómez Sexto's avatar Miguel Gómez Sexto

Module params added to the driver. Device LUN gets calculated according to

parameters.
Signed-off-by: Miguel Gómez Sexto's avatarMiguel Gomez <magomez@igalia.com>
parent ee1d4096
...@@ -19,6 +19,20 @@ ...@@ -19,6 +19,20 @@
#include "tdc.h" #include "tdc.h"
#include "hw/tdc_regs.h" #include "hw/tdc_regs.h"
int lun[MAX_DEVICES];
unsigned int nlun;
module_param_array(lun, int, &nlun, S_IRUGO);
int bus[MAX_DEVICES];
unsigned int nbus;
module_param_array(bus, int, &nbus, S_IRUGO);
int slot[MAX_DEVICES];
unsigned int nslot;
module_param_array(slot, int, &nslot, S_IRUGO);
char *gateware = "eva_tdc_for_v2.bin";
module_param(gateware, charp, S_IRUGO);
void tdc_set_utc_time(struct spec_tdc *tdc, u32 value) void tdc_set_utc_time(struct spec_tdc *tdc, u32 value)
{ {
...@@ -28,8 +42,8 @@ void tdc_set_utc_time(struct spec_tdc *tdc, u32 value) ...@@ -28,8 +42,8 @@ void tdc_set_utc_time(struct spec_tdc *tdc, u32 value)
void tdc_set_local_utc_time(struct spec_tdc *tdc) void tdc_set_local_utc_time(struct spec_tdc *tdc)
{ {
struct timeval utc_time; struct timeval utc_time;
do_gettimeofday(&utc_time); do_gettimeofday(&utc_time);
tdc_set_utc_time(tdc, utc_time.tv_sec); tdc_set_utc_time(tdc, utc_time.tv_sec);
} }
...@@ -111,10 +125,30 @@ inline u32 tdc_get_circular_buffer_wr_pointer(struct spec_tdc *tdc) ...@@ -111,10 +125,30 @@ inline u32 tdc_get_circular_buffer_wr_pointer(struct spec_tdc *tdc)
return readl(tdc->base + TDC_CIRCULAR_BUF_PTR_R); return readl(tdc->base + TDC_CIRCULAR_BUF_PTR_R);
} }
static int check_parameters(void)
{
if (nlun < 0 || nlun > MAX_DEVICES) {
pr_err("Invalid number of devices (%d)", nlun);
return -EINVAL;
}
if ((nlun != nbus) || (nlun != nslot)) {
pr_err("Parameter mismatch: %d luns, %d buses and %d slots\n",
nlun, nbus, nslot);
return -EINVAL;
}
return 0;
}
static int tdc_init(void) static int tdc_init(void)
{ {
int err; int err;
err = check_parameters();
if (err < 0)
return err;
err = tdc_zio_init(); err = tdc_zio_init();
if (err < 0) if (err < 0)
return err; return err;
...@@ -124,7 +158,7 @@ static int tdc_init(void) ...@@ -124,7 +158,7 @@ static int tdc_init(void)
tdc_zio_exit(); tdc_zio_exit();
return err; return err;
} }
return 0; return 0;
} }
......
...@@ -191,16 +191,52 @@ irqreturn_t tdc_fmc_irq_handler(int irq, void *dev_id) ...@@ -191,16 +191,52 @@ irqreturn_t tdc_fmc_irq_handler(int irq, void *dev_id)
return IRQ_HANDLED; return IRQ_HANDLED;
} }
static int tdc_fmc_get_device_lun(struct fmc_device *dev)
{
struct spec_dev *spec;
struct pci_dev *pdev;
int i;
/* If there are no parameters defined, assign 1 as the default value */
if (nlun == 0) {
pr_info("No LUNs rules defined. Assigning default value 1\n");
return 1;
}
spec = dev->carrier_data;
pdev = spec->pdev;
for (i = 0; i < nlun; i++) {
if (PCI_SLOT(pdev->devfn) == slot[i] &&
pdev->bus->number == bus[i]) {
pr_info("Matched LUN %d for device in bus %d and slot %d\n",
lun[i], bus[i], slot[i]);
return lun[i];
}
}
pr_err("No LUN found for device in bus %d and slot %d\n",
pdev->bus->number, PCI_SLOT(pdev->devfn));
return -ENODEV;
}
int tdc_fmc_probe(struct fmc_device *dev) int tdc_fmc_probe(struct fmc_device *dev)
{ {
struct spec_tdc *tdc; struct spec_tdc *tdc;
struct spec_dev *spec; struct spec_dev *spec;
int ret, i; int ret, i, dev_lun;
char gateware_path[128];
if(strcmp(dev->carrier_name, "SPEC") != 0) if(strcmp(dev->carrier_name, "SPEC") != 0)
return -ENODEV; return -ENODEV;
ret = dev->op->reprogram(dev, &tdc_fmc_driver, "fmc/eva_tdc_for_v2.bin"); dev_lun = tdc_fmc_get_device_lun(dev);
if (dev_lun < 0)
return dev_lun;
sprintf(gateware_path, "fmc/%s", gateware);
pr_info("Using gateware %s\n", gateware_path);
ret = dev->op->reprogram(dev, &tdc_fmc_driver, gateware_path);
if (ret < 0) { if (ret < 0) {
pr_err("%s: error reprogramming the FPGA\n", __func__); pr_err("%s: error reprogramming the FPGA\n", __func__);
return -ENODEV; return -ENODEV;
...@@ -216,7 +252,7 @@ int tdc_fmc_probe(struct fmc_device *dev) ...@@ -216,7 +252,7 @@ int tdc_fmc_probe(struct fmc_device *dev)
spec = dev->carrier_data; spec = dev->carrier_data;
tdc->spec = spec; tdc->spec = spec;
spec->sub_priv = tdc; spec->sub_priv = tdc;
tdc->lun = 2; /* FIXME: this must be calculated from module params */ tdc->lun = dev_lun;
tdc->fmc = dev; tdc->fmc = dev;
tdc->base = dev->base; /* BAR 0 */ tdc->base = dev->base; /* BAR 0 */
tdc->gn412x_regs = spec->remap[2]; /* BAR 4 */ tdc->gn412x_regs = spec->remap[2]; /* BAR 4 */
......
...@@ -2,12 +2,22 @@ ...@@ -2,12 +2,22 @@
#define __FMC_TDC_H__ #define __FMC_TDC_H__
#define TDC_VERSION 1 #define TDC_VERSION 1
#define MAX_DEVICES 16
#include <linux/types.h> #include <linux/types.h>
#include <linux/workqueue.h> #include <linux/workqueue.h>
#include <linux/semaphore.h> #include <linux/semaphore.h>
#include "hw/tdc_regs.h" #include "hw/tdc_regs.h"
/* module parameters */
extern int lun[MAX_DEVICES];
extern unsigned int nlun;
extern int bus[MAX_DEVICES];
extern unsigned int nbus;
extern int slot[MAX_DEVICES];
extern unsigned int nslot;
extern char *gateware;
struct tdc_event { struct tdc_event {
u32 fine_time; /* In BIN (81 ps resolution) */ u32 fine_time; /* In BIN (81 ps resolution) */
u32 coarse_time; /* 8 ns resolution */ u32 coarse_time; /* 8 ns resolution */
......
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