Commit b0353f9f authored by Alessandro Rubini's avatar Alessandro Rubini

added reprogram method, with some shake up

parent d829a534
......@@ -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 */
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,
char *name, int flags)
{
......@@ -86,7 +93,7 @@ static int spec_write_ee(struct fmc_device *fmc, int pos,
static struct fmc_operations spec_fmc_operations = {
/* no readl/writel because we have the base pointer */
/* FIXME: reprogram */
.reprogram = spec_reprogram,
.irq_request = spec_irq_request,
.irq_ack = spec_irq_ack,
.irq_free = spec_irq_free,
......
......@@ -28,25 +28,15 @@ static char *spec_fw_name = "fmc/spec-init.bin";
module_param_named(fw_name, spec_fw_name, charp, 0444);
/* 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;
int i, wrote;
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 */
wrote = loader_low_level(0 /* unused fd */,
spec->remap[2], fw->data, fw->size);
spec->remap[2], data, size);
j = jiffies + 2 * HZ;
/* Wait for DONE interrupt */
while(1) {
......@@ -54,23 +44,37 @@ static int spec_load_fpga(struct spec_dev *spec)
i = readl(spec->remap[2] + FCL_IRQ);
if (i & 0x8) {
dev_info(dev, "FPGA programming sucessful\n");
goto out;
return 0;
}
if(i & 0x4) {
dev_err(dev, "FPGA program error after %i writes\n",
wrote);
err = -ETIMEDOUT;
goto out;
return -ETIMEDOUT;
}
if (time_after(jiffies, j)) {
dev_err(dev, "FPGA timeout after %i writes\n", wrote);
err = -ETIMEDOUT;
goto out;
return -ETIMEDOUT;
}
}
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);
return err;
}
......@@ -114,7 +118,7 @@ static int __devinit spec_probe(struct pci_dev *pdev,
/* 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)
goto out_unmap;
......
......@@ -115,6 +115,9 @@ static inline void gennum_mask_val(struct spec_dev *spec,
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 */
extern int spec_fmc_create(struct spec_dev *spec);
......
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