[PATCH 07/14] staging: comedi: daqboard2000: check result of FPGA programming

Ian Abbott abbotti at mev.co.uk
Wed Jan 4 10:55:40 UTC 2017


According to an old, GPL'ed Linux driver at
<ftp://ftp.mccdaq.com/downloads/iotech_software/DaqBoard_1000_2000_Series/Linux_driver_kernelv2.4.x/>,
after programming the FPGA, the General Purpose Input (USERI) of the PLX
PCI-9080 should go high shortly after a valid FPGA bitstream has been
loaded.  Add a new function `daqboard2000_wait_fpga_programmed()` to
wait for that, performing up to 200 checks over a 20 ms period (this is
loosely based on `pollFPGADone()` in the above-mentioned old driver).
Return 0 if the FPGA appears to have loaded successfully, or
`-ETIMEDOUT` if it runs out of checks.  Call it from the firmware
loading callback `daqboard2000_load_firmware()` after writing the
firmware to the FPGA to check it is programmed successfully.

Signed-off-by: Ian Abbott <abbotti at mev.co.uk>
---
 drivers/staging/comedi/drivers/daqboard2000.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/drivers/staging/comedi/drivers/daqboard2000.c b/drivers/staging/comedi/drivers/daqboard2000.c
index d6f30261db9b..4e3e81186bc3 100644
--- a/drivers/staging/comedi/drivers/daqboard2000.c
+++ b/drivers/staging/comedi/drivers/daqboard2000.c
@@ -501,6 +501,23 @@ static int daqboard2000_write_cpld(struct comedi_device *dev, u16 data)
 	return result;
 }
 
+static int daqboard2000_wait_fpga_programmed(struct comedi_device *dev)
+{
+	struct daqboard2000_private *devpriv = dev->private;
+	int i;
+
+	/* Time out after 200 tries -> 20ms */
+	for (i = 0; i < 200; i++) {
+		u32 cntrl = readl(devpriv->plx + PLX_REG_CNTRL);
+		/* General Purpose Input (USERI) set on FPGA "DONE". */
+		if (cntrl & PLX_CNTRL_USERI)
+			return 0;
+
+		usleep_range(100, 1000);
+	}
+	return -ETIMEDOUT;
+}
+
 static int daqboard2000_load_firmware(struct comedi_device *dev,
 				      const u8 *cpld_array, size_t len,
 				      unsigned long context)
@@ -551,6 +568,8 @@ static int daqboard2000_load_firmware(struct comedi_device *dev,
 			if (result)
 				break;
 		}
+		if (result == 0)
+			result = daqboard2000_wait_fpga_programmed(dev);
 		if (result == 0) {
 			daqboard2000_reset_local_bus(dev);
 			daqboard2000_reload_plx(dev);
-- 
2.11.0



More information about the devel mailing list