Skip to content
Snippets Groups Projects
Commit b0353f9f authored by Alessandro Rubini's avatar Alessandro Rubini
Browse files

added reprogram method, with some shake up

parent d829a534
No related merge requests found
...@@ -18,6 +18,13 @@ module_param_named(test_irq, spec_test_irq, int, 0444); ...@@ -18,6 +18,13 @@ module_param_named(test_irq, spec_test_irq, int, 0444);
/* The main role of this file is offering the fmc_operations for the spec */ /* The main role of this file is offering the fmc_operations for the spec */
static int spec_reprogram(struct fmc_device *fmc, void *data, int len)
{
struct spec_dev *spec = fmc->carrier_data;
return spec_load_fpga(spec, data, len); /* spec-pci.c */
}
static int spec_irq_request(struct fmc_device *fmc, irq_handler_t handler, static int spec_irq_request(struct fmc_device *fmc, irq_handler_t handler,
char *name, int flags) char *name, int flags)
{ {
...@@ -86,7 +93,7 @@ static int spec_write_ee(struct fmc_device *fmc, int pos, ...@@ -86,7 +93,7 @@ static int spec_write_ee(struct fmc_device *fmc, int pos,
static struct fmc_operations spec_fmc_operations = { static struct fmc_operations spec_fmc_operations = {
/* no readl/writel because we have the base pointer */ /* no readl/writel because we have the base pointer */
/* FIXME: reprogram */ .reprogram = spec_reprogram,
.irq_request = spec_irq_request, .irq_request = spec_irq_request,
.irq_ack = spec_irq_ack, .irq_ack = spec_irq_ack,
.irq_free = spec_irq_free, .irq_free = spec_irq_free,
......
...@@ -28,25 +28,15 @@ static char *spec_fw_name = "fmc/spec-init.bin"; ...@@ -28,25 +28,15 @@ static char *spec_fw_name = "fmc/spec-init.bin";
module_param_named(fw_name, spec_fw_name, charp, 0444); module_param_named(fw_name, spec_fw_name, charp, 0444);
/* Load the FPGA. This bases on loader-ll.c, a kernel/user space thing */ /* Load the FPGA. This bases on loader-ll.c, a kernel/user space thing */
static int spec_load_fpga(struct spec_dev *spec) int spec_load_fpga(struct spec_dev *spec, const void *data, int size)
{ {
const struct firmware *fw;
struct device *dev = &spec->pdev->dev; struct device *dev = &spec->pdev->dev;
int i, wrote;
unsigned long j; unsigned long j;
int i, err = 0, wrote;
char *name = spec_fw_name; /* FIXME: temporary hack */
err = request_firmware(&fw, name, dev);
if (err < 0) {
dev_err(dev, "request firmware \"%s\": error %i\n", name, err);
return err;
}
dev_info(dev, "got file \"%s\", %i (0x%x) bytes\n",
spec_fw_name, fw->size, fw->size);
/* loader_low_level is designed to run from user space too */ /* loader_low_level is designed to run from user space too */
wrote = loader_low_level(0 /* unused fd */, wrote = loader_low_level(0 /* unused fd */,
spec->remap[2], fw->data, fw->size); spec->remap[2], data, size);
j = jiffies + 2 * HZ; j = jiffies + 2 * HZ;
/* Wait for DONE interrupt */ /* Wait for DONE interrupt */
while(1) { while(1) {
...@@ -54,23 +44,37 @@ static int spec_load_fpga(struct spec_dev *spec) ...@@ -54,23 +44,37 @@ static int spec_load_fpga(struct spec_dev *spec)
i = readl(spec->remap[2] + FCL_IRQ); i = readl(spec->remap[2] + FCL_IRQ);
if (i & 0x8) { if (i & 0x8) {
dev_info(dev, "FPGA programming sucessful\n"); dev_info(dev, "FPGA programming sucessful\n");
goto out; return 0;
} }
if(i & 0x4) { if(i & 0x4) {
dev_err(dev, "FPGA program error after %i writes\n", dev_err(dev, "FPGA program error after %i writes\n",
wrote); wrote);
err = -ETIMEDOUT; return -ETIMEDOUT;
goto out;
} }
if (time_after(jiffies, j)) { if (time_after(jiffies, j)) {
dev_err(dev, "FPGA timeout after %i writes\n", wrote); dev_err(dev, "FPGA timeout after %i writes\n", wrote);
err = -ETIMEDOUT; return -ETIMEDOUT;
goto out;
} }
} }
out: }
int spec_load_fpga_file(struct spec_dev *spec, char *name)
{
struct device *dev = &spec->pdev->dev;
const struct firmware *fw;
int err = 0;
err = request_firmware(&fw, name, dev);
if (err < 0) {
dev_err(dev, "request firmware \"%s\": error %i\n", name, err);
return err;
}
dev_info(dev, "got file \"%s\", %i (0x%x) bytes\n",
spec_fw_name, fw->size, fw->size);
err = spec_load_fpga(spec, fw->data, fw->size);
release_firmware(fw); release_firmware(fw);
return err; return err;
} }
...@@ -114,7 +118,7 @@ static int __devinit spec_probe(struct pci_dev *pdev, ...@@ -114,7 +118,7 @@ static int __devinit spec_probe(struct pci_dev *pdev,
/* Load the golden FPGA binary to read the eeprom */ /* Load the golden FPGA binary to read the eeprom */
ret = spec_load_fpga(spec); ret = spec_load_fpga_file(spec, spec_fw_name);
if (ret) if (ret)
goto out_unmap; goto out_unmap;
......
...@@ -115,6 +115,9 @@ static inline void gennum_mask_val(struct spec_dev *spec, ...@@ -115,6 +115,9 @@ static inline void gennum_mask_val(struct spec_dev *spec,
gennum_writel(spec, v, reg); gennum_writel(spec, v, reg);
} }
/* Functions in spec-pci.c */
extern int spec_load_fpga(struct spec_dev *spec, const void *data, int size);
extern int spec_load_fpga_file(struct spec_dev *spec, char *name);
/* Functions in spec-fmc.c, used by spec-pci.c */ /* Functions in spec-fmc.c, used by spec-pci.c */
extern int spec_fmc_create(struct spec_dev *spec); extern int spec_fmc_create(struct spec_dev *spec);
......
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