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

fmc_operations: use a different reprogram

parent f1a948ae
No related merge requests found
...@@ -184,7 +184,7 @@ this document): ...@@ -184,7 +184,7 @@ this document):
struct fmc_operations { struct fmc_operations {
uint32_t (*readl)(struct fmc_device *fmc, int offset); uint32_t (*readl)(struct fmc_device *fmc, int offset);
void (*writel)(struct fmc_device *fmc, uint32_t value, int offset); void (*writel)(struct fmc_device *fmc, uint32_t value, int offset);
int (*reprogram)(struct fmc_device *fmc, void *data, int len); int (*reprogram)(struct fmc_device *fmc, char *gateware);
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);
void (*irq_ack)(struct fmc_device *fmc); void (*irq_ack)(struct fmc_device *fmc);
...@@ -214,10 +214,11 @@ The individual methods perform the following tasks: ...@@ -214,10 +214,11 @@ The individual methods perform the following tasks:
The carrier enumerates FMC devices by loading a standard (or The carrier enumerates FMC devices by loading a standard (or
@i{golden} FPGA binary that allows EEPROM access. Each driver, then, @i{golden} FPGA binary that allows EEPROM access. Each driver, then,
will need to reprogram the FPGA for its own use by calling this will need to reprogram the FPGA by calling this
function. If @i{reprogram} is called with NULL arguments, the function. If the name argument is NULL,
carrier will reprogram the golden binary -- which will happen the carrier will reprogram the golden binary. If the gateware name
after @i{remove} time in any case. has been overridden through module parameters (in a carrier-specific
way) the file loaded will match the parameters.
@item irq_request @item irq_request
@itemx irq_ack @itemx irq_ack
......
...@@ -2,7 +2,6 @@ ...@@ -2,7 +2,6 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/firmware.h>
#include <linux/fmc.h> #include <linux/fmc.h>
#include "spec.h" #include "spec.h"
...@@ -21,31 +20,15 @@ irqreturn_t t_handler(int irq, void *dev_id) ...@@ -21,31 +20,15 @@ irqreturn_t t_handler(int irq, void *dev_id)
int t_probe(struct fmc_device *fmc) int t_probe(struct fmc_device *fmc)
{ {
int ret; int ret;
struct device *dev = fmc->hwdev;
ret = fmc->op->irq_request(fmc, t_handler, "fmc-trivial", 0); ret = fmc->op->irq_request(fmc, t_handler, "fmc-trivial", 0);
if (ret < 0) if (ret < 0)
return ret; return ret;
if (t_filename) { /* Reprogram, but only if specified in the arguments */
const struct firmware *fw; ret = fmc->op->reprogram(fmc, "");
if (ret < 0)
ret = request_firmware(&fw, t_filename, dev); fmc->op->irq_free(fmc);
if (ret < 0) {
dev_warn(dev, "request firmware \"%s\": error %i\n",
t_filename, ret);
ret = 0; /* not fatal */
} else {
ret = fmc->op->reprogram(fmc, (void *)fw->data,
fw->size);
}
if (ret <0) {
dev_err(dev, "write firmware \"%s\": error %i\n",
t_filename, ret);
ret = 0; /* not fatal, either (lazy me) */
}
release_firmware(fw);
}
return ret; return ret;
} }
......
...@@ -36,7 +36,7 @@ struct fmc_driver { ...@@ -36,7 +36,7 @@ struct fmc_driver {
struct fmc_operations { struct fmc_operations {
uint32_t (*readl)(struct fmc_device *fmc, int offset); uint32_t (*readl)(struct fmc_device *fmc, int offset);
void (*writel)(struct fmc_device *fmc, uint32_t value, int offset); void (*writel)(struct fmc_device *fmc, uint32_t value, int offset);
int (*reprogram)(struct fmc_device *fmc, void *data, int len); int (*reprogram)(struct fmc_device *fmc, char *gateware);
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);
void (*irq_ack)(struct fmc_device *fmc); void (*irq_ack)(struct fmc_device *fmc);
......
...@@ -18,11 +18,36 @@ module_param_named(test_irq, spec_test_irq, int, 0444); ...@@ -18,11 +18,36 @@ 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) static int spec_reprogram(struct fmc_device *fmc, char *gw)
{ {
struct spec_dev *spec = fmc->carrier_data; struct spec_dev *spec = fmc->carrier_data;
const struct firmware *fw;
struct device *dev = fmc->hwdev;
int ret;
if (!gw)
return 0;
if (!strlen(gw)) {
/* FIXME: use module parameters */
return 0;
}
return spec_load_fpga(spec, data, len); /* spec-pci.c */ ret = request_firmware(&fw, gw, dev);
if (ret < 0) {
dev_warn(dev, "request firmware \"%s\": error %i\n", gw, ret);
goto out;
}
ret = spec_load_fpga(spec, fw->data, fw->size);
if (ret <0) {
dev_err(dev, "write firmware \"%s\": error %i\n", gw, ret);
goto out;
}
/* FIXME: load lm32 */
out:
release_firmware(fw);
return ret;
} }
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,
......
...@@ -10,7 +10,6 @@ ...@@ -10,7 +10,6 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/firmware.h>
#include <linux/fmc.h> #include <linux/fmc.h>
#include <linux/fmc-sdb.h> #include <linux/fmc-sdb.h>
#include "wr-nic.h" #include "wr-nic.h"
...@@ -32,7 +31,6 @@ int wrn_probe(struct fmc_device *fmc) ...@@ -32,7 +31,6 @@ int wrn_probe(struct fmc_device *fmc)
{ {
int ret = 0; int ret = 0;
struct device *dev = fmc->hwdev; struct device *dev = fmc->hwdev;
const struct firmware *fw;
struct wrn_drvdata *dd; struct wrn_drvdata *dd;
/* Driver data */ /* Driver data */
...@@ -41,41 +39,34 @@ int wrn_probe(struct fmc_device *fmc) ...@@ -41,41 +39,34 @@ int wrn_probe(struct fmc_device *fmc)
return -ENOMEM; return -ENOMEM;
fmc_set_drvdata(fmc, dd); fmc_set_drvdata(fmc, dd);
/* We first write a new binary within the spec */ /* We first write a new binary (and lm32) within the spec */
if (wrn_filename) { ret = fmc->op->reprogram(fmc, WRN_GATEWARE_DEFAULT_NAME);
if (ret <0) {
ret = request_firmware(&fw, wrn_filename, dev); dev_err(dev, "write firmware \"%s\": error %i\n",
if (ret < 0) { wrn_filename, ret);
dev_warn(dev, "request firmware \"%s\": error %i\n", goto out;
wrn_filename, ret);
goto out;
}
ret = fmc->op->reprogram(fmc, (void *)fw->data, fw->size);
if (ret <0) {
dev_err(dev, "write firmware \"%s\": error %i\n",
wrn_filename, ret);
goto out_fw;
}
} }
/* Verify that we have SDB at offset 0x63000 */ /* Verify that we have SDB at offset 0x63000 */
if (fmc_readl(fmc, 0x63000) != 0x5344422d) { if (fmc_readl(fmc, 0x63000) != 0x5344422d) {
dev_err(dev, "Can't find SDB magic\n"); dev_err(dev, "Can't find SDB magic\n");
ret = -ENODEV; ret = -ENODEV;
goto out_fw; goto out;
} }
dev_info(dev, "Gateware successfully loaded\n"); dev_info(dev, "Gateware successfully loaded\n");
if ( (ret = fmc_scan_sdb_tree(fmc, 0x63000)) < 0) { if ( (ret = fmc_scan_sdb_tree(fmc, 0x63000)) < 0) {
dev_err(dev, "scan fmc failed %i\n", ret); dev_err(dev, "scan fmc failed %i\n", ret);
goto out_fw; goto out;
} }
fmc_show_sdb_tree(fmc); fmc_show_sdb_tree(fmc);
/* FIXME: load lm32 */
/* Register the gpio stuff, if we have kernel support */ /* Register the gpio stuff, if we have kernel support */
ret = wrn_gpio_init(fmc); ret = wrn_gpio_init(fmc);
if (ret < 0) if (ret < 0)
goto out_fw; goto out;
/* The netword device */ /* The netword device */
ret = wrn_eth_init(fmc); ret = wrn_eth_init(fmc);
...@@ -94,8 +85,6 @@ out_nic: ...@@ -94,8 +85,6 @@ out_nic:
wrn_eth_exit(fmc); wrn_eth_exit(fmc);
out_gpio: out_gpio:
wrn_gpio_exit(fmc); wrn_gpio_exit(fmc);
out_fw:
release_firmware(fw);
out: out:
return ret; return ret;
} }
......
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