mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-22 22:51:37 +00:00
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:
parent
15b1b0f0d8
commit
9c0dda1495
3 changed files with 43 additions and 3 deletions
|
@ -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,
|
||||||
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)
|
||||||
}
|
}
|
||||||
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 {
|
||||||
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 {
|
||||||
};
|
};
|
||||||
|
|
||||||
/* 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);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue