Skip to content

Commit 9c0dda1

Browse files
Federico Vagagregkh
authored andcommitted
drivers/fmc: carrier can program FPGA on registration
The initial FPGA may require programming before it is useful. Signed-off-by: Federico Vaga <[email protected]> Tested-by: Pat Riehecky <[email protected]> Acked-by: Alessandro Rubini <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 15b1b0f commit 9c0dda1

File tree

3 files changed

+43
-3
lines changed

3 files changed

+43
-3
lines changed

drivers/fmc/fmc-core.c

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,21 @@ int fmc_device_register_n_gw(struct fmc_device **devs, int n,
280280
else
281281
dev_set_name(&fmc->dev, "%s-%04x", fmc->mezzanine_name,
282282
device_id);
283+
284+
if (gw) {
285+
/*
286+
* The carrier already know the bitstream to load
287+
* for this set of FMC mezzanines.
288+
*/
289+
ret = fmc->op->reprogram_raw(fmc, NULL,
290+
gw->bitstream, gw->len);
291+
if (ret) {
292+
dev_warn(fmc->hwdev,
293+
"Invalid gateware for FMC mezzanine\n");
294+
goto out;
295+
}
296+
}
297+
283298
ret = device_add(&fmc->dev);
284299
if (ret < 0) {
285300
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,
300315
out1:
301316
device_del(&fmc->dev);
302317
out:
303-
fmc_free_id_info(fmc);
304-
put_device(&fmc->dev);
305-
306318
kfree(devarray);
307319
for (i--; i >= 0; i--) {
308320
fmc_debug_exit(devs[i]);

drivers/fmc/fmc-sdb.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,30 @@ int fmc_free_sdb_tree(struct fmc_device *fmc)
126126
}
127127
EXPORT_SYMBOL(fmc_free_sdb_tree);
128128

129+
/* This helper calls reprogram and inizialized sdb as well */
130+
int fmc_reprogram_raw(struct fmc_device *fmc, struct fmc_driver *d,
131+
void *gw, unsigned long len, int sdb_entry)
132+
{
133+
int ret;
134+
135+
ret = fmc->op->reprogram_raw(fmc, d, gw, len);
136+
if (ret < 0)
137+
return ret;
138+
if (sdb_entry < 0)
139+
return ret;
140+
141+
/* We are required to find SDB at a given offset */
142+
ret = fmc_scan_sdb_tree(fmc, sdb_entry);
143+
if (ret < 0) {
144+
dev_err(&fmc->dev, "Can't find SDB at address 0x%x\n",
145+
sdb_entry);
146+
return -ENODEV;
147+
}
148+
149+
return 0;
150+
}
151+
EXPORT_SYMBOL(fmc_reprogram_raw);
152+
129153
/* This helper calls reprogram and inizialized sdb as well */
130154
int fmc_reprogram(struct fmc_device *fmc, struct fmc_driver *d, char *gw,
131155
int sdb_entry)

include/linux/fmc.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,8 @@ struct fmc_operations {
132132
uint32_t (*read32)(struct fmc_device *fmc, int offset);
133133
void (*write32)(struct fmc_device *fmc, uint32_t value, int offset);
134134
int (*validate)(struct fmc_device *fmc, struct fmc_driver *drv);
135+
int (*reprogram_raw)(struct fmc_device *f, struct fmc_driver *d,
136+
void *gw, unsigned long len);
135137
int (*reprogram)(struct fmc_device *f, struct fmc_driver *d, char *gw);
136138
int (*irq_request)(struct fmc_device *fmc, irq_handler_t h,
137139
char *name, int flags);
@@ -144,6 +146,8 @@ struct fmc_operations {
144146
};
145147

146148
/* Prefer this helper rather than calling of fmc->reprogram directly */
149+
int fmc_reprogram_raw(struct fmc_device *fmc, struct fmc_driver *d,
150+
void *gw, unsigned long len, int sdb_entry);
147151
extern int fmc_reprogram(struct fmc_device *f, struct fmc_driver *d, char *gw,
148152
int sdb_entry);
149153

0 commit comments

Comments
 (0)