drivers/fmc: carrier can program FPGA on registration

The initial FPGA may require programming before it is useful.

Signed-off-by: Federico Vaga <federico.vaga@cern.ch>
Tested-by: Pat Riehecky <riehecky@fnal.gov>
Acked-by: Alessandro Rubini <rubini@gnudd.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Federico Vaga 2017-07-18 08:33:24 +02:00 коммит произвёл Greg Kroah-Hartman
Родитель 15b1b0f0d8
Коммит 9c0dda1495
3 изменённых файлов: 43 добавлений и 3 удалений

Просмотреть файл

@ -280,6 +280,21 @@ int fmc_device_register_n_gw(struct fmc_device **devs, int n,
else
dev_set_name(&fmc->dev, "%s-%04x", fmc->mezzanine_name,
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);
if (ret < 0) {
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,
out1:
device_del(&fmc->dev);
out:
fmc_free_id_info(fmc);
put_device(&fmc->dev);
kfree(devarray);
for (i--; i >= 0; i--) {
fmc_debug_exit(devs[i]);

Просмотреть файл

@ -126,6 +126,30 @@ int fmc_free_sdb_tree(struct fmc_device *fmc)
}
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 */
int fmc_reprogram(struct fmc_device *fmc, struct fmc_driver *d, char *gw,
int sdb_entry)

Просмотреть файл

@ -132,6 +132,8 @@ struct fmc_operations {
uint32_t (*read32)(struct fmc_device *fmc, int offset);
void (*write32)(struct fmc_device *fmc, uint32_t value, int offset);
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 (*irq_request)(struct fmc_device *fmc, irq_handler_t h,
char *name, int flags);
@ -144,6 +146,8 @@ struct fmc_operations {
};
/* 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,
int sdb_entry);