Commit 9c0dda14 authored by Federico Vaga's avatar Federico Vaga Committed by Greg Kroah-Hartman

drivers/fmc: carrier can program FPGA on registration

The initial FPGA may require programming before it is useful.
Signed-off-by: default avatarFederico Vaga <federico.vaga@cern.ch>
Tested-by: default avatarPat Riehecky <riehecky@fnal.gov>
Acked-by: default avatarAlessandro Rubini <rubini@gnudd.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 15b1b0f0
...@@ -280,6 +280,21 @@ int fmc_device_register_n_gw(struct fmc_device **devs, int n, ...@@ -280,6 +280,21 @@ int fmc_device_register_n_gw(struct fmc_device **devs, int n,
else else
dev_set_name(&fmc->dev, "%s-%04x", fmc->mezzanine_name, dev_set_name(&fmc->dev, "%s-%04x", fmc->mezzanine_name,
device_id); device_id);
if (gw) {
/*
* The carrier already know the bitstream to load
* for this set of FMC mezzanines.
*/
ret = fmc->op->reprogram_raw(fmc, NULL,
gw->bitstream, gw->len);
if (ret) {
dev_warn(fmc->hwdev,
"Invalid gateware for FMC mezzanine\n");
goto out;
}
}
ret = device_add(&fmc->dev); ret = device_add(&fmc->dev);
if (ret < 0) { if (ret < 0) {
dev_err(fmc->hwdev, "Slot %i: Failed in registering " dev_err(fmc->hwdev, "Slot %i: Failed in registering "
...@@ -300,9 +315,6 @@ int fmc_device_register_n_gw(struct fmc_device **devs, int n, ...@@ -300,9 +315,6 @@ int fmc_device_register_n_gw(struct fmc_device **devs, int n,
out1: out1:
device_del(&fmc->dev); device_del(&fmc->dev);
out: out:
fmc_free_id_info(fmc);
put_device(&fmc->dev);
kfree(devarray); kfree(devarray);
for (i--; i >= 0; i--) { for (i--; i >= 0; i--) {
fmc_debug_exit(devs[i]); fmc_debug_exit(devs[i]);
......
...@@ -126,6 +126,30 @@ int fmc_free_sdb_tree(struct fmc_device *fmc) ...@@ -126,6 +126,30 @@ int fmc_free_sdb_tree(struct fmc_device *fmc)
} }
EXPORT_SYMBOL(fmc_free_sdb_tree); EXPORT_SYMBOL(fmc_free_sdb_tree);
/* This helper calls reprogram and inizialized sdb as well */
int fmc_reprogram_raw(struct fmc_device *fmc, struct fmc_driver *d,
void *gw, unsigned long len, int sdb_entry)
{
int ret;
ret = fmc->op->reprogram_raw(fmc, d, gw, len);
if (ret < 0)
return ret;
if (sdb_entry < 0)
return ret;
/* We are required to find SDB at a given offset */
ret = fmc_scan_sdb_tree(fmc, sdb_entry);
if (ret < 0) {
dev_err(&fmc->dev, "Can't find SDB at address 0x%x\n",
sdb_entry);
return -ENODEV;
}
return 0;
}
EXPORT_SYMBOL(fmc_reprogram_raw);
/* This helper calls reprogram and inizialized sdb as well */ /* This helper calls reprogram and inizialized sdb as well */
int fmc_reprogram(struct fmc_device *fmc, struct fmc_driver *d, char *gw, int fmc_reprogram(struct fmc_device *fmc, struct fmc_driver *d, char *gw,
int sdb_entry) int sdb_entry)
......
...@@ -132,6 +132,8 @@ struct fmc_operations { ...@@ -132,6 +132,8 @@ struct fmc_operations {
uint32_t (*read32)(struct fmc_device *fmc, int offset); uint32_t (*read32)(struct fmc_device *fmc, int offset);
void (*write32)(struct fmc_device *fmc, uint32_t value, int offset); void (*write32)(struct fmc_device *fmc, uint32_t value, int offset);
int (*validate)(struct fmc_device *fmc, struct fmc_driver *drv); int (*validate)(struct fmc_device *fmc, struct fmc_driver *drv);
int (*reprogram_raw)(struct fmc_device *f, struct fmc_driver *d,
void *gw, unsigned long len);
int (*reprogram)(struct fmc_device *f, struct fmc_driver *d, char *gw); int (*reprogram)(struct fmc_device *f, struct fmc_driver *d, char *gw);
int (*irq_request)(struct fmc_device *fmc, irq_handler_t h, int (*irq_request)(struct fmc_device *fmc, irq_handler_t h,
char *name, int flags); char *name, int flags);
...@@ -144,6 +146,8 @@ struct fmc_operations { ...@@ -144,6 +146,8 @@ struct fmc_operations {
}; };
/* Prefer this helper rather than calling of fmc->reprogram directly */ /* Prefer this helper rather than calling of fmc->reprogram directly */
int fmc_reprogram_raw(struct fmc_device *fmc, struct fmc_driver *d,
void *gw, unsigned long len, int sdb_entry);
extern int fmc_reprogram(struct fmc_device *f, struct fmc_driver *d, char *gw, extern int fmc_reprogram(struct fmc_device *f, struct fmc_driver *d, char *gw,
int sdb_entry); int sdb_entry);
......
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