<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
<META NAME="Generator" CONTENT="MS Exchange Server version 6.5.7652.24">
<TITLE>RE: [PATCH] [POWERPC] Xilinx: hwicap driver</TITLE>
</HEAD>
<BODY>
<!-- Converted from text/plain format -->
<BR>

<P><FONT SIZE=2>Grant,<BR>
<BR>
One of the modifications to the include files got lost, so this won't compile.&nbsp; I also have the corresponding update to booting-without-of.txt queued up.&nbsp; However, webmail won't show me the message id for the thread (grr.), so I'll send it tomorrow when I'm in the office.<BR>
<BR>
Steve<BR>
<BR>
-----Original Message-----<BR>
From: Stephen Neuendorffer [<A HREF="mailto:stephen.neuendorffer@xilinx.com">mailto:stephen.neuendorffer@xilinx.com</A>]<BR>
Sent: Fri 2/1/2008 1:12 PM<BR>
To: linuxppc-dev@ozlabs.org; grant.likely@secretlab.ca; jacmet@sunsite.dk; ntl@pobox.com<BR>
Cc: Stephen Neuendorffer<BR>
Subject: [PATCH] [POWERPC] Xilinx: hwicap driver<BR>
<BR>
This includes code for new fifo-based xps_hwicap in addition to the<BR>
older opb_hwicap, which has a significantly different interface.&nbsp; The<BR>
common code between the two drivers is largely shared.<BR>
<BR>
Significant differences exists between this driver and what is<BR>
supported in the EDK drivers.&nbsp; In particular, most of the<BR>
architecture-specific code for reconfiguring individual FPGA resources<BR>
has been removed.&nbsp; This functionality is likely better provided in a<BR>
user-space support library.&nbsp; In addition, read and write access is<BR>
supported.&nbsp; In addition, although the xps_hwicap cores support<BR>
interrupt-driver mode, this driver only supports polled operation, in<BR>
order to make the code simpler, and since the interrupt processing<BR>
overhead is likely to slow down the throughput under Linux.<BR>
<BR>
Signed-off-by: Stephen Neuendorffer &lt;stephen.neuendorffer@xilinx.com&gt;<BR>
<BR>
Fixed to add mutexes, and a few style issues.<BR>
<BR>
Acked-by: Grant Likely &lt;grant.likely@secretlab.ca&gt;<BR>
<BR>
---<BR>
<BR>
I will get this right eventually. :)<BR>
---<BR>
&nbsp;drivers/char/Kconfig&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp; 7 +<BR>
&nbsp;drivers/char/Makefile&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp; 1 +<BR>
&nbsp;drivers/char/xilinx_hwicap/Makefile&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp; 7 +<BR>
&nbsp;drivers/char/xilinx_hwicap/buffer_icap.c&nbsp;&nbsp; |&nbsp; 380 ++++++++++++<BR>
&nbsp;drivers/char/xilinx_hwicap/buffer_icap.h&nbsp;&nbsp; |&nbsp;&nbsp; 57 ++<BR>
&nbsp;drivers/char/xilinx_hwicap/fifo_icap.c&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp; 381 ++++++++++++<BR>
&nbsp;drivers/char/xilinx_hwicap/fifo_icap.h&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp; 62 ++<BR>
&nbsp;drivers/char/xilinx_hwicap/xilinx_hwicap.c |&nbsp; 904 ++++++++++++++++++++++++++++<BR>
&nbsp;drivers/char/xilinx_hwicap/xilinx_hwicap.h |&nbsp; 193 ++++++<BR>
&nbsp;9 files changed, 1992 insertions(+), 0 deletions(-)<BR>
&nbsp;create mode 100644 drivers/char/xilinx_hwicap/Makefile<BR>
&nbsp;create mode 100644 drivers/char/xilinx_hwicap/buffer_icap.c<BR>
&nbsp;create mode 100644 drivers/char/xilinx_hwicap/buffer_icap.h<BR>
&nbsp;create mode 100644 drivers/char/xilinx_hwicap/fifo_icap.c<BR>
&nbsp;create mode 100644 drivers/char/xilinx_hwicap/fifo_icap.h<BR>
&nbsp;create mode 100644 drivers/char/xilinx_hwicap/xilinx_hwicap.c<BR>
&nbsp;create mode 100644 drivers/char/xilinx_hwicap/xilinx_hwicap.h<BR>
<BR>
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig<BR>
index ef1ed5d..157ae2a 100644<BR>
--- a/drivers/char/Kconfig<BR>
+++ b/drivers/char/Kconfig<BR>
@@ -831,6 +831,13 @@ config DTLK<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; To compile this driver as a module, choose M here: the<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; module will be called dtlk.<BR>
<BR>
+config XILINX_HWICAP<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; tristate &quot;Xilinx HWICAP Support&quot;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; depends on XILINX_VIRTEX<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; help<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; This option enables support for Xilinx Internal Configuration<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; Access Port (ICAP) driver.<BR>
+<BR>
&nbsp;config R3964<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; tristate &quot;Siemens R3964 line discipline&quot;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ---help---<BR>
diff --git a/drivers/char/Makefile b/drivers/char/Makefile<BR>
index 07304d5..3a278a0 100644<BR>
--- a/drivers/char/Makefile<BR>
+++ b/drivers/char/Makefile<BR>
@@ -76,6 +76,7 @@ obj-$(CONFIG_EFI_RTC) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; += efirtc.o<BR>
&nbsp;obj-$(CONFIG_SGI_DS1286)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; += ds1286.o<BR>
&nbsp;obj-$(CONFIG_SGI_IP27_RTC)&nbsp;&nbsp;&nbsp;&nbsp; += ip27-rtc.o<BR>
&nbsp;obj-$(CONFIG_DS1302)&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; += ds1302.o<BR>
+obj-$(CONFIG_XILINX_HWICAP)&nbsp;&nbsp;&nbsp; += xilinx_hwicap/<BR>
&nbsp;ifeq ($(CONFIG_GENERIC_NVRAM),y)<BR>
&nbsp;&nbsp; obj-$(CONFIG_NVRAM)&nbsp; += generic_nvram.o<BR>
&nbsp;else<BR>
diff --git a/drivers/char/xilinx_hwicap/Makefile b/drivers/char/xilinx_hwicap/Makefile<BR>
new file mode 100644<BR>
index 0000000..5491cbc<BR>
--- /dev/null<BR>
+++ b/drivers/char/xilinx_hwicap/Makefile<BR>
@@ -0,0 +1,7 @@<BR>
+#<BR>
+# Makefile for the Xilinx OPB hwicap driver<BR>
+#<BR>
+<BR>
+obj-$(CONFIG_XILINX_HWICAP) += xilinx_hwicap_m.o<BR>
+<BR>
+xilinx_hwicap_m-y := xilinx_hwicap.o fifo_icap.o buffer_icap.o<BR>
diff --git a/drivers/char/xilinx_hwicap/buffer_icap.c b/drivers/char/xilinx_hwicap/buffer_icap.c<BR>
new file mode 100644<BR>
index 0000000..dfea2bd<BR>
--- /dev/null<BR>
+++ b/drivers/char/xilinx_hwicap/buffer_icap.c<BR>
@@ -0,0 +1,380 @@<BR>
+/*****************************************************************************<BR>
+ *<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; Author: Xilinx, Inc.<BR>
+ *<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; This program is free software; you can redistribute it and/or modify it<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; under the terms of the GNU General Public License as published by the<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; Free Software Foundation; either version 2 of the License, or (at your<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; option) any later version.<BR>
+ *<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION &quot;AS IS&quot;<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; SOLUTIONS FOR XILINX DEVICES.&nbsp; BY PROVIDING THIS DESIGN, CODE,<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; FOR YOUR IMPLEMENTATION.&nbsp; XILINX EXPRESSLY DISCLAIMS ANY<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; FOR A PARTICULAR PURPOSE.<BR>
+ *<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; Xilinx products are not intended for use in life support appliances,<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; devices, or systems. Use in such applications is expressly prohibited.<BR>
+ *<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; (c) Copyright 2003-2008 Xilinx Inc.<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; All rights reserved.<BR>
+ *<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; You should have received a copy of the GNU General Public License along<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; with this program; if not, write to the Free Software Foundation, Inc.,<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; 675 Mass Ave, Cambridge, MA 02139, USA.<BR>
+ *<BR>
+ *****************************************************************************/<BR>
+<BR>
+#include &quot;buffer_icap.h&quot;<BR>
+<BR>
+/* Indicates how many bytes will fit in a buffer. (1 BRAM) */<BR>
+#define XHI_MAX_BUFFER_BYTES&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2048<BR>
+#define XHI_MAX_BUFFER_INTS&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (XHI_MAX_BUFFER_BYTES &gt;&gt; 2)<BR>
+<BR>
+/* File access and error constants */<BR>
+#define XHI_DEVICE_READ_ERROR&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -1<BR>
+#define XHI_DEVICE_WRITE_ERROR&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -2<BR>
+#define XHI_BUFFER_OVERFLOW_ERROR&nbsp;&nbsp; -3<BR>
+<BR>
+#define XHI_DEVICE_READ&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0x1<BR>
+#define XHI_DEVICE_WRITE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0x0<BR>
+<BR>
+/* Constants for checking transfer status */<BR>
+#define XHI_CYCLE_DONE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0<BR>
+#define XHI_CYCLE_EXECUTING&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1<BR>
+<BR>
+/* buffer_icap register offsets */<BR>
+<BR>
+/* Size of transfer, read &amp; write */<BR>
+#define XHI_SIZE_REG_OFFSET&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0x800L<BR>
+/* offset into bram, read &amp; write */<BR>
+#define XHI_BRAM_OFFSET_REG_OFFSET 0x804L<BR>
+/* Read not Configure, direction of transfer.&nbsp; Write only */<BR>
+#define XHI_RNC_REG_OFFSET&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0x808L<BR>
+/* Indicates transfer complete. Read only */<BR>
+#define XHI_STATUS_REG_OFFSET&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0x80CL<BR>
+<BR>
+/* Constants for setting the RNC register */<BR>
+#define XHI_CONFIGURE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0x0UL<BR>
+#define XHI_READBACK&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0x1UL<BR>
+<BR>
+/* Constants for the Done register */<BR>
+#define XHI_NOT_FINISHED&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0x0UL<BR>
+#define XHI_FINISHED&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0x1UL<BR>
+<BR>
+#define XHI_BUFFER_START 0<BR>
+<BR>
+/**<BR>
+ * buffer_icap_get_status: Get the contents of the status register.<BR>
+ * @parameter base_address: is the base address of the device<BR>
+ *<BR>
+ * The status register contains the ICAP status and the done bit.<BR>
+ *<BR>
+ * D8 - cfgerr<BR>
+ * D7 - dalign<BR>
+ * D6 - rip<BR>
+ * D5 - in_abort_l<BR>
+ * D4 - Always 1<BR>
+ * D3 - Always 1<BR>
+ * D2 - Always 1<BR>
+ * D1 - Always 1<BR>
+ * D0 - Done bit<BR>
+ **/<BR>
+static inline u32 buffer_icap_get_status(void __iomem *base_address)<BR>
+{<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return in_be32(base_address + XHI_STATUS_REG_OFFSET);<BR>
+}<BR>
+<BR>
+/**<BR>
+ * buffer_icap_get_bram: Reads data from the storage buffer bram.<BR>
+ * @parameter base_address: contains the base address of the component.<BR>
+ * @parameter offset: The word offset from which the data should be read.<BR>
+ *<BR>
+ * A bram is used as a configuration memory cache.&nbsp; One frame of data can<BR>
+ * be stored in this &quot;storage buffer&quot;.<BR>
+ **/<BR>
+static inline u32 buffer_icap_get_bram(void __iomem *base_address,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u32 offset)<BR>
+{<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return in_be32(base_address + (offset &lt;&lt; 2));<BR>
+}<BR>
+<BR>
+/**<BR>
+ * buffer_icap_busy: Return true if the icap device is busy<BR>
+ * @parameter base_address: is the base address of the device<BR>
+ *<BR>
+ * The queries the low order bit of the status register, which<BR>
+ * indicates whether the current configuration or readback operation<BR>
+ * has completed.<BR>
+ **/<BR>
+static inline bool buffer_icap_busy(void __iomem *base_address)<BR>
+{<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return (buffer_icap_get_status(base_address) &amp; 1) == XHI_NOT_FINISHED;<BR>
+}<BR>
+<BR>
+/**<BR>
+ * buffer_icap_busy: Return true if the icap device is not busy<BR>
+ * @parameter base_address: is the base address of the device<BR>
+ *<BR>
+ * The queries the low order bit of the status register, which<BR>
+ * indicates whether the current configuration or readback operation<BR>
+ * has completed.<BR>
+ **/<BR>
+static inline bool buffer_icap_done(void __iomem *base_address)<BR>
+{<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return (buffer_icap_get_status(base_address) &amp; 1) == XHI_FINISHED;<BR>
+}<BR>
+<BR>
+/**<BR>
+ * buffer_icap_set_size: Set the size register.<BR>
+ * @parameter base_address: is the base address of the device<BR>
+ * @parameter data: The size in bytes.<BR>
+ *<BR>
+ * The size register holds the number of 8 bit bytes to transfer between<BR>
+ * bram and the icap (or icap to bram).<BR>
+ **/<BR>
+static inline void buffer_icap_set_size(void __iomem *base_address,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u32 data)<BR>
+{<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; out_be32(base_address + XHI_SIZE_REG_OFFSET, data);<BR>
+}<BR>
+<BR>
+/**<BR>
+ * buffer_icap_mSetoffsetReg: Set the bram offset register.<BR>
+ * @parameter base_address: contains the base address of the device.<BR>
+ * @parameter data: is the value to be written to the data register.<BR>
+ *<BR>
+ * The bram offset register holds the starting bram address to transfer<BR>
+ * data from during configuration or write data to during readback.<BR>
+ **/<BR>
+static inline void buffer_icap_set_offset(void __iomem *base_address,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u32 data)<BR>
+{<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; out_be32(base_address + XHI_BRAM_OFFSET_REG_OFFSET, data);<BR>
+}<BR>
+<BR>
+/**<BR>
+ * buffer_icap_set_rnc: Set the RNC (Readback not Configure) register.<BR>
+ * @parameter base_address: contains the base address of the device.<BR>
+ * @parameter data: is the value to be written to the data register.<BR>
+ *<BR>
+ * The RNC register determines the direction of the data transfer.&nbsp; It<BR>
+ * controls whether a configuration or readback take place.&nbsp; Writing to<BR>
+ * this register initiates the transfer.&nbsp; A value of 1 initiates a<BR>
+ * readback while writing a value of 0 initiates a configuration.<BR>
+ **/<BR>
+static inline void buffer_icap_set_rnc(void __iomem *base_address,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u32 data)<BR>
+{<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; out_be32(base_address + XHI_RNC_REG_OFFSET, data);<BR>
+}<BR>
+<BR>
+/**<BR>
+ * buffer_icap_set_bram: Write data to the storage buffer bram.<BR>
+ * @parameter base_address: contains the base address of the component.<BR>
+ * @parameter offset: The word offset at which the data should be written.<BR>
+ * @parameter data: The value to be written to the bram offset.<BR>
+ *<BR>
+ * A bram is used as a configuration memory cache.&nbsp; One frame of data can<BR>
+ * be stored in this &quot;storage buffer&quot;.<BR>
+ **/<BR>
+static inline void buffer_icap_set_bram(void __iomem *base_address,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u32 offset, u32 data)<BR>
+{<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; out_be32(base_address + (offset &lt;&lt; 2), data);<BR>
+}<BR>
+<BR>
+/**<BR>
+ * buffer_icap_device_read: Transfer bytes from ICAP to the storage buffer.<BR>
+ * @parameter drvdata: a pointer to the drvdata.<BR>
+ * @parameter offset: The storage buffer start address.<BR>
+ * @parameter count: The number of words (32 bit) to read from the<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; device (ICAP).<BR>
+ **/<BR>
+static int buffer_icap_device_read(struct hwicap_drvdata *drvdata,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u32 offset, u32 count)<BR>
+{<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; s32 retries = 0;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; void __iomem *base_address = drvdata-&gt;base_address;<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (buffer_icap_busy(base_address))<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return -EBUSY;<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ((offset + count) &gt; XHI_MAX_BUFFER_INTS)<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return -EINVAL;<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* setSize count*4 to get bytes. */<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; buffer_icap_set_size(base_address, (count &lt;&lt; 2));<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; buffer_icap_set_offset(base_address, offset);<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; buffer_icap_set_rnc(base_address, XHI_READBACK);<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while (buffer_icap_busy(base_address)) {<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; retries++;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (retries &gt; XHI_MAX_RETRIES)<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return -EBUSY;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 0;<BR>
+<BR>
+};<BR>
+<BR>
+/**<BR>
+ * buffer_icap_device_write: Transfer bytes from ICAP to the storage buffer.<BR>
+ * @parameter drvdata: a pointer to the drvdata.<BR>
+ * @parameter offset: The storage buffer start address.<BR>
+ * @parameter count: The number of words (32 bit) to read from the<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; device (ICAP).<BR>
+ **/<BR>
+static int buffer_icap_device_write(struct hwicap_drvdata *drvdata,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u32 offset, u32 count)<BR>
+{<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; s32 retries = 0;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; void __iomem *base_address = drvdata-&gt;base_address;<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (buffer_icap_busy(base_address))<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return -EBUSY;<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ((offset + count) &gt; XHI_MAX_BUFFER_INTS)<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return -EINVAL;<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* setSize count*4 to get bytes. */<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; buffer_icap_set_size(base_address, count &lt;&lt; 2);<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; buffer_icap_set_offset(base_address, offset);<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; buffer_icap_set_rnc(base_address, XHI_CONFIGURE);<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while (buffer_icap_busy(base_address)) {<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; retries++;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (retries &gt; XHI_MAX_RETRIES)<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return -EBUSY;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 0;<BR>
+<BR>
+};<BR>
+<BR>
+/**<BR>
+ * buffer_icap_reset: Reset the logic of the icap device.<BR>
+ * @parameter drvdata: a pointer to the drvdata.<BR>
+ *<BR>
+ * Writing to the status register resets the ICAP logic in an internal<BR>
+ * version of the core.&nbsp; For the version of the core published in EDK,<BR>
+ * this is a noop.<BR>
+ **/<BR>
+void buffer_icap_reset(struct hwicap_drvdata *drvdata)<BR>
+{<BR>
+&nbsp;&nbsp;&nbsp; out_be32(drvdata-&gt;base_address + XHI_STATUS_REG_OFFSET, 0xFEFE);<BR>
+}<BR>
+<BR>
+/**<BR>
+ * buffer_icap_set_configuration: Load a partial bitstream from system memory.<BR>
+ * @parameter drvdata: a pointer to the drvdata.<BR>
+ * @parameter data: Kernel address of the partial bitstream.<BR>
+ * @parameter size: the size of the partial bitstream in 32 bit words.<BR>
+ **/<BR>
+int buffer_icap_set_configuration(struct hwicap_drvdata *drvdata, u32 *data,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; u32 size)<BR>
+{<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int status;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; s32 buffer_count = 0;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; s32 num_writes = 0;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bool dirty = 0;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u32 i;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; void __iomem *base_address = drvdata-&gt;base_address;<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Loop through all the data */<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (i = 0, buffer_count = 0; i &lt; size; i++) {<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Copy data to bram */<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; buffer_icap_set_bram(base_address, buffer_count, data[i]);<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dirty = 1;<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (buffer_count &lt; XHI_MAX_BUFFER_INTS - 1) {<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; buffer_count++;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; continue;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Write data to ICAP */<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; status = buffer_icap_device_write(<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; drvdata,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; XHI_BUFFER_START,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; XHI_MAX_BUFFER_INTS);<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (status != 0) {<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* abort. */<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; buffer_icap_reset(drvdata);<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return status;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; buffer_count = 0;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; num_writes++;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dirty = 0;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Write unwritten data to ICAP */<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (dirty) {<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Write data to ICAP */<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; status = buffer_icap_device_write(drvdata, XHI_BUFFER_START,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; buffer_count);<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (status != 0) {<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* abort. */<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; buffer_icap_reset(drvdata);<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return status;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 0;<BR>
+};<BR>
+<BR>
+/**<BR>
+ * buffer_icap_get_configuration: Read configuration data from the device.<BR>
+ * @parameter drvdata: a pointer to the drvdata.<BR>
+ * @parameter data: Address of the data representing the partial bitstream<BR>
+ * @parameter size: the size of the partial bitstream in 32 bit words.<BR>
+ **/<BR>
+int buffer_icap_get_configuration(struct hwicap_drvdata *drvdata, u32 *data,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; u32 size)<BR>
+{<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int status;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; s32 buffer_count = 0;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; s32 read_count = 0;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u32 i;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; void __iomem *base_address = drvdata-&gt;base_address;<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Loop through all the data */<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (i = 0, buffer_count = XHI_MAX_BUFFER_INTS; i &lt; size; i++) {<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (buffer_count == XHI_MAX_BUFFER_INTS) {<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u32 words_remaining = size - i;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u32 words_to_read =<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; words_remaining &lt;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; XHI_MAX_BUFFER_INTS ? words_remaining :<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; XHI_MAX_BUFFER_INTS;<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Read data from ICAP */<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; status = buffer_icap_device_read(<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; drvdata,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; XHI_BUFFER_START,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; words_to_read);<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (status != 0) {<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* abort. */<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; buffer_icap_reset(drvdata);<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return status;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; buffer_count = 0;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; read_count++;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Copy data from bram */<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; data[i] = buffer_icap_get_bram(base_address, buffer_count);<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; buffer_count++;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 0;<BR>
+};<BR>
diff --git a/drivers/char/xilinx_hwicap/buffer_icap.h b/drivers/char/xilinx_hwicap/buffer_icap.h<BR>
new file mode 100644<BR>
index 0000000..0318495<BR>
--- /dev/null<BR>
+++ b/drivers/char/xilinx_hwicap/buffer_icap.h<BR>
@@ -0,0 +1,57 @@<BR>
+/*****************************************************************************<BR>
+ *<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; Author: Xilinx, Inc.<BR>
+ *<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; This program is free software; you can redistribute it and/or modify it<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; under the terms of the GNU General Public License as published by the<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; Free Software Foundation; either version 2 of the License, or (at your<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; option) any later version.<BR>
+ *<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION &quot;AS IS&quot;<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; SOLUTIONS FOR XILINX DEVICES.&nbsp; BY PROVIDING THIS DESIGN, CODE,<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; FOR YOUR IMPLEMENTATION.&nbsp; XILINX EXPRESSLY DISCLAIMS ANY<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; FOR A PARTICULAR PURPOSE.<BR>
+ *<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; Xilinx products are not intended for use in life support appliances,<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; devices, or systems. Use in such applications is expressly prohibited.<BR>
+ *<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; (c) Copyright 2003-2008 Xilinx Inc.<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; All rights reserved.<BR>
+ *<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; You should have received a copy of the GNU General Public License along<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; with this program; if not, write to the Free Software Foundation, Inc.,<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; 675 Mass Ave, Cambridge, MA 02139, USA.<BR>
+ *<BR>
+ *****************************************************************************/<BR>
+<BR>
+#ifndef XILINX_BUFFER_ICAP_H_&nbsp; /* prevent circular inclusions */<BR>
+#define XILINX_BUFFER_ICAP_H_&nbsp; /* by using protection macros */<BR>
+<BR>
+#include &lt;linux/types.h&gt;<BR>
+#include &lt;linux/cdev.h&gt;<BR>
+#include &lt;linux/version.h&gt;<BR>
+#include &lt;linux/platform_device.h&gt;<BR>
+<BR>
+#include &lt;asm/io.h&gt;<BR>
+#include &quot;xilinx_hwicap.h&quot;<BR>
+<BR>
+void buffer_icap_reset(struct hwicap_drvdata *drvdata);<BR>
+<BR>
+/* Loads a partial bitstream from system memory. */<BR>
+int buffer_icap_set_configuration(struct hwicap_drvdata *drvdata, u32 *data,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; u32 Size);<BR>
+<BR>
+/* Loads a partial bitstream from system memory. */<BR>
+int buffer_icap_get_configuration(struct hwicap_drvdata *drvdata, u32 *data,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; u32 Size);<BR>
+<BR>
+#endif<BR>
diff --git a/drivers/char/xilinx_hwicap/fifo_icap.c b/drivers/char/xilinx_hwicap/fifo_icap.c<BR>
new file mode 100644<BR>
index 0000000..0988314<BR>
--- /dev/null<BR>
+++ b/drivers/char/xilinx_hwicap/fifo_icap.c<BR>
@@ -0,0 +1,381 @@<BR>
+/*****************************************************************************<BR>
+ *<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; Author: Xilinx, Inc.<BR>
+ *<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; This program is free software; you can redistribute it and/or modify it<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; under the terms of the GNU General Public License as published by the<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; Free Software Foundation; either version 2 of the License, or (at your<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; option) any later version.<BR>
+ *<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION &quot;AS IS&quot;<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; SOLUTIONS FOR XILINX DEVICES.&nbsp; BY PROVIDING THIS DESIGN, CODE,<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; FOR YOUR IMPLEMENTATION.&nbsp; XILINX EXPRESSLY DISCLAIMS ANY<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; FOR A PARTICULAR PURPOSE.<BR>
+ *<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; Xilinx products are not intended for use in life support appliances,<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; devices, or systems. Use in such applications is expressly prohibited.<BR>
+ *<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; (c) Copyright 2007-2008 Xilinx Inc.<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; All rights reserved.<BR>
+ *<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; You should have received a copy of the GNU General Public License along<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; with this program; if not, write to the Free Software Foundation, Inc.,<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; 675 Mass Ave, Cambridge, MA 02139, USA.<BR>
+ *<BR>
+ *****************************************************************************/<BR>
+<BR>
+#include &quot;fifo_icap.h&quot;<BR>
+<BR>
+/* Register offsets for the XHwIcap device. */<BR>
+#define XHI_GIER_OFFSET&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0x1C&nbsp; /* Device Global Interrupt Enable Reg */<BR>
+#define XHI_IPISR_OFFSET 0x20&nbsp; /* Interrupt Status Register */<BR>
+#define XHI_IPIER_OFFSET 0x28&nbsp; /* Interrupt Enable Register */<BR>
+#define XHI_WF_OFFSET 0x100 /* Write FIFO */<BR>
+#define XHI_RF_OFFSET 0x104 /* Read FIFO */<BR>
+#define XHI_SZ_OFFSET 0x108 /* Size Register */<BR>
+#define XHI_CR_OFFSET 0x10C /* Control Register */<BR>
+#define XHI_SR_OFFSET 0x110 /* Status Register */<BR>
+#define XHI_WFV_OFFSET 0x114 /* Write FIFO Vacancy Register */<BR>
+#define XHI_RFO_OFFSET 0x118 /* Read FIFO Occupancy Register */<BR>
+<BR>
+/* Device Global Interrupt Enable Register (GIER) bit definitions */<BR>
+<BR>
+#define XHI_GIER_GIE_MASK 0x80000000 /* Global Interrupt enable Mask */<BR>
+<BR>
+/**<BR>
+ * HwIcap Device Interrupt Status/Enable Registers<BR>
+ *<BR>
+ * Interrupt Status Register (IPISR) : This register holds the<BR>
+ * interrupt status flags for the device. These bits are toggle on<BR>
+ * write.<BR>
+ *<BR>
+ * Interrupt Enable Register (IPIER) : This register is used to enable<BR>
+ * interrupt sources for the device.<BR>
+ * Writing a '1' to a bit enables the corresponding interrupt.<BR>
+ * Writing a '0' to a bit disables the corresponding interrupt.<BR>
+ *<BR>
+ * IPISR/IPIER registers have the same bit definitions and are only defined<BR>
+ * once.<BR>
+ */<BR>
+#define XHI_IPIXR_RFULL_MASK 0x00000008 /* Read FIFO Full */<BR>
+#define XHI_IPIXR_WEMPTY_MASK 0x00000004 /* Write FIFO Empty */<BR>
+#define XHI_IPIXR_RDP_MASK 0x00000002 /* Read FIFO half full */<BR>
+#define XHI_IPIXR_WRP_MASK 0x00000001 /* Write FIFO half full */<BR>
+#define XHI_IPIXR_ALL_MASK 0x0000000F /* Mask of all interrupts */<BR>
+<BR>
+/* Control Register (CR) */<BR>
+#define XHI_CR_SW_RESET_MASK 0x00000008 /* SW Reset Mask */<BR>
+#define XHI_CR_FIFO_CLR_MASK 0x00000004 /* FIFO Clear Mask */<BR>
+#define XHI_CR_READ_MASK 0x00000002 /* Read from ICAP to FIFO */<BR>
+#define XHI_CR_WRITE_MASK 0x00000001 /* Write from FIFO to ICAP */<BR>
+<BR>
+/* Status Register (SR) */<BR>
+#define XHI_SR_CFGERR_N_MASK 0x00000100 /* Config Error Mask */<BR>
+#define XHI_SR_DALIGN_MASK 0x00000080 /* Data Alignment Mask */<BR>
+#define XHI_SR_RIP_MASK 0x00000040 /* Read back Mask */<BR>
+#define XHI_SR_IN_ABORT_N_MASK 0x00000020 /* Select Map Abort Mask */<BR>
+#define XHI_SR_DONE_MASK 0x00000001 /* Done bit Mask&nbsp; */<BR>
+<BR>
+<BR>
+#define XHI_WFO_MAX_VACANCY 1024 /* Max Write FIFO Vacancy, in words */<BR>
+#define XHI_RFO_MAX_OCCUPANCY 256 /* Max Read FIFO Occupancy, in words */<BR>
+/* The maximum amount we can request from fifo_icap_get_configuration<BR>
+&nbsp;&nbsp; at once, in bytes. */<BR>
+#define XHI_MAX_READ_TRANSACTION_WORDS 0xFFF<BR>
+<BR>
+<BR>
+/**<BR>
+ * fifo_icap_fifo_write: Write data to the write FIFO.<BR>
+ * @parameter drvdata: a pointer to the drvdata.<BR>
+ * @parameter data: the 32-bit value to be written to the FIFO.<BR>
+ *<BR>
+ * This function will silently fail if the fifo is full.<BR>
+ **/<BR>
+static inline void fifo_icap_fifo_write(struct hwicap_drvdata *drvdata,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u32 data)<BR>
+{<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dev_dbg(drvdata-&gt;dev, &quot;fifo_write: %x\n&quot;, data);<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; out_be32(drvdata-&gt;base_address + XHI_WF_OFFSET, data);<BR>
+}<BR>
+<BR>
+/**<BR>
+ * fifo_icap_fifo_read: Read data from the Read FIFO.<BR>
+ * @parameter drvdata: a pointer to the drvdata.<BR>
+ *<BR>
+ * This function will silently fail if the fifo is empty.<BR>
+ **/<BR>
+static inline u32 fifo_icap_fifo_read(struct hwicap_drvdata *drvdata)<BR>
+{<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u32 data = in_be32(drvdata-&gt;base_address + XHI_RF_OFFSET);<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dev_dbg(drvdata-&gt;dev, &quot;fifo_read: %x\n&quot;, data);<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return data;<BR>
+}<BR>
+<BR>
+/**<BR>
+ * fifo_icap_set_read_size: Set the the size register.<BR>
+ * @parameter drvdata: a pointer to the drvdata.<BR>
+ * @parameter data: the size of the following read transaction, in words.<BR>
+ **/<BR>
+static inline void fifo_icap_set_read_size(struct hwicap_drvdata *drvdata,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u32 data)<BR>
+{<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; out_be32(drvdata-&gt;base_address + XHI_SZ_OFFSET, data);<BR>
+}<BR>
+<BR>
+/**<BR>
+ * fifo_icap_start_config: Initiate a configuration (write) to the device.<BR>
+ * @parameter drvdata: a pointer to the drvdata.<BR>
+ **/<BR>
+static inline void fifo_icap_start_config(struct hwicap_drvdata *drvdata)<BR>
+{<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; out_be32(drvdata-&gt;base_address + XHI_CR_OFFSET, XHI_CR_WRITE_MASK);<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dev_dbg(drvdata-&gt;dev, &quot;configuration started\n&quot;);<BR>
+}<BR>
+<BR>
+/**<BR>
+ * fifo_icap_start_readback: Initiate a readback from the device.<BR>
+ * @parameter drvdata: a pointer to the drvdata.<BR>
+ **/<BR>
+static inline void fifo_icap_start_readback(struct hwicap_drvdata *drvdata)<BR>
+{<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; out_be32(drvdata-&gt;base_address + XHI_CR_OFFSET, XHI_CR_READ_MASK);<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dev_dbg(drvdata-&gt;dev, &quot;readback started\n&quot;);<BR>
+}<BR>
+<BR>
+/**<BR>
+ * fifo_icap_busy: Return true if the ICAP is still processing a transaction.<BR>
+ * @parameter drvdata: a pointer to the drvdata.<BR>
+ **/<BR>
+static inline u32 fifo_icap_busy(struct hwicap_drvdata *drvdata)<BR>
+{<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u32 status = in_be32(drvdata-&gt;base_address + XHI_SR_OFFSET);<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dev_dbg(drvdata-&gt;dev, &quot;Getting status = %x\n&quot;, status);<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return (status &amp; XHI_SR_DONE_MASK) ? 0 : 1;<BR>
+}<BR>
+<BR>
+/**<BR>
+ * fifo_icap_write_fifo_vacancy: Query the write fifo available space.<BR>
+ * @parameter drvdata: a pointer to the drvdata.<BR>
+ *<BR>
+ * Return the number of words that can be safely pushed into the write fifo.<BR>
+ **/<BR>
+static inline u32 fifo_icap_write_fifo_vacancy(<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct hwicap_drvdata *drvdata)<BR>
+{<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return in_be32(drvdata-&gt;base_address + XHI_WFV_OFFSET);<BR>
+}<BR>
+<BR>
+/**<BR>
+ * fifo_icap_read_fifo_occupancy: Query the read fifo available data.<BR>
+ * @parameter drvdata: a pointer to the drvdata.<BR>
+ *<BR>
+ * Return the number of words that can be safely read from the read fifo.<BR>
+ **/<BR>
+static inline u32 fifo_icap_read_fifo_occupancy(<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct hwicap_drvdata *drvdata)<BR>
+{<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return in_be32(drvdata-&gt;base_address + XHI_RFO_OFFSET);<BR>
+}<BR>
+<BR>
+/**<BR>
+ * fifo_icap_set_configuration: Send configuration data to the ICAP.<BR>
+ * @parameter drvdata: a pointer to the drvdata.<BR>
+ * @parameter frame_buffer: a pointer to the data to be written to the<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ICAP device.<BR>
+ * @parameter num_words: the number of words (32 bit) to write to the ICAP<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; device.<BR>
+<BR>
+ * This function writes the given user data to the Write FIFO in<BR>
+ * polled mode and starts the transfer of the data to<BR>
+ * the ICAP device.<BR>
+ **/<BR>
+int fifo_icap_set_configuration(struct hwicap_drvdata *drvdata,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u32 *frame_buffer, u32 num_words)<BR>
+{<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u32 write_fifo_vacancy = 0;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u32 retries = 0;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u32 remaining_words;<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dev_dbg(drvdata-&gt;dev, &quot;fifo_set_configuration\n&quot;);<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /*<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * Check if the ICAP device is Busy with the last Read/Write<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (fifo_icap_busy(drvdata))<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return -EBUSY;<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /*<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * Set up the buffer pointer and the words to be transferred.<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; remaining_words = num_words;<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while (remaining_words &gt; 0) {<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /*<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * Wait until we have some data in the fifo.<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while (write_fifo_vacancy == 0) {<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; write_fifo_vacancy =<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fifo_icap_write_fifo_vacancy(drvdata);<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; retries++;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (retries &gt; XHI_MAX_RETRIES)<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return -EIO;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /*<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * Write data into the Write FIFO.<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while ((write_fifo_vacancy != 0) &amp;&amp;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (remaining_words &gt; 0)) {<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fifo_icap_fifo_write(drvdata, *frame_buffer);<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; remaining_words--;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; write_fifo_vacancy--;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; frame_buffer++;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Start pushing whatever is in the FIFO into the ICAP. */<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fifo_icap_start_config(drvdata);<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Wait until the write has finished. */<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while (fifo_icap_busy(drvdata)) {<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; retries++;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (retries &gt; XHI_MAX_RETRIES)<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dev_dbg(drvdata-&gt;dev, &quot;done fifo_set_configuration\n&quot;);<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /*<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * If the requested number of words have not been read from<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * the device then indicate failure.<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (remaining_words != 0)<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return -EIO;<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 0;<BR>
+}<BR>
+<BR>
+/**<BR>
+ * fifo_icap_get_configuration: Read configuration data from the device.<BR>
+ * @parameter drvdata: a pointer to the drvdata.<BR>
+ * @parameter data: Address of the data representing the partial bitstream<BR>
+ * @parameter size: the size of the partial bitstream in 32 bit words.<BR>
+ *<BR>
+ * This function reads the specified number of words from the ICAP device in<BR>
+ * the polled mode.<BR>
+ */<BR>
+int fifo_icap_get_configuration(struct hwicap_drvdata *drvdata,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u32 *frame_buffer, u32 num_words)<BR>
+{<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u32 read_fifo_occupancy = 0;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u32 retries = 0;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u32 *data = frame_buffer;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u32 remaining_words;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u32 words_to_read;<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dev_dbg(drvdata-&gt;dev, &quot;fifo_get_configuration\n&quot;);<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /*<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * Check if the ICAP device is Busy with the last Write/Read<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (fifo_icap_busy(drvdata))<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return -EBUSY;<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; remaining_words = num_words;<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while (remaining_words &gt; 0) {<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; words_to_read = remaining_words;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* The hardware has a limit on the number of words<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; that can be read at one time.&nbsp; */<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (words_to_read &gt; XHI_MAX_READ_TRANSACTION_WORDS)<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; words_to_read = XHI_MAX_READ_TRANSACTION_WORDS;<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; remaining_words -= words_to_read;<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fifo_icap_set_read_size(drvdata, words_to_read);<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fifo_icap_start_readback(drvdata);<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while (words_to_read &gt; 0) {<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Wait until we have some data in the fifo. */<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while (read_fifo_occupancy == 0) {<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; read_fifo_occupancy =<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fifo_icap_read_fifo_occupancy(drvdata);<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; retries++;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (retries &gt; XHI_MAX_RETRIES)<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return -EIO;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (read_fifo_occupancy &gt; words_to_read)<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; read_fifo_occupancy = words_to_read;<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; words_to_read -= read_fifo_occupancy;<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Read the data from the Read FIFO. */<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while (read_fifo_occupancy != 0) {<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *data++ = fifo_icap_fifo_read(drvdata);<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; read_fifo_occupancy--;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dev_dbg(drvdata-&gt;dev, &quot;done fifo_get_configuration\n&quot;);<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 0;<BR>
+}<BR>
+<BR>
+/**<BR>
+ * buffer_icap_reset: Reset the logic of the icap device.<BR>
+ * @parameter drvdata: a pointer to the drvdata.<BR>
+ *<BR>
+ * This function forces the software reset of the complete HWICAP device.<BR>
+ * All the registers will return to the default value and the FIFO is also<BR>
+ * flushed as a part of this software reset.<BR>
+ */<BR>
+void fifo_icap_reset(struct hwicap_drvdata *drvdata)<BR>
+{<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u32 reg_data;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /*<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * Reset the device by setting/clearing the RESET bit in the<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * Control Register.<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; reg_data = in_be32(drvdata-&gt;base_address + XHI_CR_OFFSET);<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; out_be32(drvdata-&gt;base_address + XHI_CR_OFFSET,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; reg_data | XHI_CR_SW_RESET_MASK);<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; out_be32(drvdata-&gt;base_address + XHI_CR_OFFSET,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; reg_data &amp; (~XHI_CR_SW_RESET_MASK));<BR>
+<BR>
+}<BR>
+<BR>
+/**<BR>
+ * fifo_icap_flush_fifo: This function flushes the FIFOs in the device.<BR>
+ * @parameter drvdata: a pointer to the drvdata.<BR>
+ */<BR>
+void fifo_icap_flush_fifo(struct hwicap_drvdata *drvdata)<BR>
+{<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u32 reg_data;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /*<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * Flush the FIFO by setting/clearing the FIFO Clear bit in the<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * Control Register.<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; reg_data = in_be32(drvdata-&gt;base_address + XHI_CR_OFFSET);<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; out_be32(drvdata-&gt;base_address + XHI_CR_OFFSET,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; reg_data | XHI_CR_FIFO_CLR_MASK);<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; out_be32(drvdata-&gt;base_address + XHI_CR_OFFSET,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; reg_data &amp; (~XHI_CR_FIFO_CLR_MASK));<BR>
+}<BR>
+<BR>
diff --git a/drivers/char/xilinx_hwicap/fifo_icap.h b/drivers/char/xilinx_hwicap/fifo_icap.h<BR>
new file mode 100644<BR>
index 0000000..4d3068d<BR>
--- /dev/null<BR>
+++ b/drivers/char/xilinx_hwicap/fifo_icap.h<BR>
@@ -0,0 +1,62 @@<BR>
+/*****************************************************************************<BR>
+ *<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; Author: Xilinx, Inc.<BR>
+ *<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; This program is free software; you can redistribute it and/or modify it<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; under the terms of the GNU General Public License as published by the<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; Free Software Foundation; either version 2 of the License, or (at your<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; option) any later version.<BR>
+ *<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION &quot;AS IS&quot;<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; SOLUTIONS FOR XILINX DEVICES.&nbsp; BY PROVIDING THIS DESIGN, CODE,<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; FOR YOUR IMPLEMENTATION.&nbsp; XILINX EXPRESSLY DISCLAIMS ANY<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; FOR A PARTICULAR PURPOSE.<BR>
+ *<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; Xilinx products are not intended for use in life support appliances,<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; devices, or systems. Use in such applications is expressly prohibited.<BR>
+ *<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; (c) Copyright 2007-2008 Xilinx Inc.<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; All rights reserved.<BR>
+ *<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; You should have received a copy of the GNU General Public License along<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; with this program; if not, write to the Free Software Foundation, Inc.,<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; 675 Mass Ave, Cambridge, MA 02139, USA.<BR>
+ *<BR>
+ *****************************************************************************/<BR>
+<BR>
+#ifndef XILINX_FIFO_ICAP_H_&nbsp;&nbsp;&nbsp; /* prevent circular inclusions */<BR>
+#define XILINX_FIFO_ICAP_H_&nbsp;&nbsp;&nbsp; /* by using protection macros */<BR>
+<BR>
+#include &lt;linux/types.h&gt;<BR>
+#include &lt;linux/cdev.h&gt;<BR>
+#include &lt;linux/version.h&gt;<BR>
+#include &lt;linux/platform_device.h&gt;<BR>
+<BR>
+#include &lt;asm/io.h&gt;<BR>
+#include &quot;xilinx_hwicap.h&quot;<BR>
+<BR>
+/* Reads integers from the device into the storage buffer. */<BR>
+int fifo_icap_get_configuration(<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct hwicap_drvdata *drvdata,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u32 *FrameBuffer,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u32 NumWords);<BR>
+<BR>
+/* Writes integers to the device from the storage buffer. */<BR>
+int fifo_icap_set_configuration(<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct hwicap_drvdata *drvdata,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u32 *FrameBuffer,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u32 NumWords);<BR>
+<BR>
+void fifo_icap_reset(struct hwicap_drvdata *drvdata);<BR>
+void fifo_icap_flush_fifo(struct hwicap_drvdata *drvdata);<BR>
+<BR>
+#endif<BR>
diff --git a/drivers/char/xilinx_hwicap/xilinx_hwicap.c b/drivers/char/xilinx_hwicap/xilinx_hwicap.c<BR>
new file mode 100644<BR>
index 0000000..24f6aef<BR>
--- /dev/null<BR>
+++ b/drivers/char/xilinx_hwicap/xilinx_hwicap.c<BR>
@@ -0,0 +1,904 @@<BR>
+/*****************************************************************************<BR>
+ *<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; Author: Xilinx, Inc.<BR>
+ *<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; This program is free software; you can redistribute it and/or modify it<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; under the terms of the GNU General Public License as published by the<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; Free Software Foundation; either version 2 of the License, or (at your<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; option) any later version.<BR>
+ *<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION &quot;AS IS&quot;<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; SOLUTIONS FOR XILINX DEVICES.&nbsp; BY PROVIDING THIS DESIGN, CODE,<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; FOR YOUR IMPLEMENTATION.&nbsp; XILINX EXPRESSLY DISCLAIMS ANY<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; FOR A PARTICULAR PURPOSE.<BR>
+ *<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; Xilinx products are not intended for use in life support appliances,<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; devices, or systems. Use in such applications is expressly prohibited.<BR>
+ *<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; (c) Copyright 2002 Xilinx Inc., Systems Engineering Group<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; (c) Copyright 2004 Xilinx Inc., Systems Engineering Group<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; (c) Copyright 2007-2008 Xilinx Inc.<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; All rights reserved.<BR>
+ *<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; You should have received a copy of the GNU General Public License along<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; with this program; if not, write to the Free Software Foundation, Inc.,<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; 675 Mass Ave, Cambridge, MA 02139, USA.<BR>
+ *<BR>
+ *****************************************************************************/<BR>
+<BR>
+/*<BR>
+ * This is the code behind /dev/xilinx_icap -- it allows a user-space<BR>
+ * application to use the Xilinx ICAP subsystem.<BR>
+ *<BR>
+ * The following operations are possible:<BR>
+ *<BR>
+ * open&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; open the port and initialize for access.<BR>
+ * release&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; release port<BR>
+ * write&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Write a bitstream to the configuration processor.<BR>
+ * read&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Read a data stream from the configuration processor.<BR>
+ *<BR>
+ * After being opened, the port is initialized and accessed to avoid a<BR>
+ * corrupted first read which may occur with some hardware.&nbsp; The port<BR>
+ * is left in a desynched state, requiring that a synch sequence be<BR>
+ * transmitted before any valid configuration data.&nbsp; A user will have<BR>
+ * exclusive access to the device while it remains open, and the state<BR>
+ * of the ICAP cannot be guaranteed after the device is closed.&nbsp; Note<BR>
+ * that a complete reset of the core and the state of the ICAP cannot<BR>
+ * be performed on many versions of the cores, hence users of this<BR>
+ * device should avoid making inconsistent accesses to the device.&nbsp; In<BR>
+ * particular, accessing the read interface, without first generating<BR>
+ * a write containing a readback packet can leave the ICAP in an<BR>
+ * inaccessible state.<BR>
+ *<BR>
+ * Note that in order to use the read interface, it is first necessary<BR>
+ * to write a request packet to the write interface.&nbsp; i.e., it is not<BR>
+ * possible to simply readback the bitstream (or any configuration<BR>
+ * bits) from a device without specifically requesting them first.<BR>
+ * The code to craft such packets is intended to be part of the<BR>
+ * user-space application code that uses this device.&nbsp; The simplest<BR>
+ * way to use this interface is simply:<BR>
+ *<BR>
+ * cp foo.bit /dev/xilinx_icap<BR>
+ *<BR>
+ * Note that unless foo.bit is an appropriately constructed partial<BR>
+ * bitstream, this has a high likelyhood of overwriting the design<BR>
+ * currently programmed in the FPGA.<BR>
+ */<BR>
+<BR>
+#include &lt;linux/version.h&gt;<BR>
+#include &lt;linux/module.h&gt;<BR>
+#include &lt;linux/kernel.h&gt;<BR>
+#include &lt;linux/types.h&gt;<BR>
+#include &lt;linux/ioport.h&gt;<BR>
+#include &lt;linux/interrupt.h&gt;<BR>
+#include &lt;linux/fcntl.h&gt;<BR>
+#include &lt;linux/init.h&gt;<BR>
+#include &lt;linux/poll.h&gt;<BR>
+#include &lt;linux/proc_fs.h&gt;<BR>
+#include &lt;asm/semaphore.h&gt;<BR>
+#include &lt;linux/sysctl.h&gt;<BR>
+#include &lt;linux/version.h&gt;<BR>
+#include &lt;linux/fs.h&gt;<BR>
+#include &lt;linux/cdev.h&gt;<BR>
+#include &lt;linux/platform_device.h&gt;<BR>
+<BR>
+#include &lt;asm/io.h&gt;<BR>
+#include &lt;asm/uaccess.h&gt;<BR>
+#include &lt;asm/system.h&gt;<BR>
+<BR>
+#ifdef CONFIG_OF<BR>
+/* For open firmware. */<BR>
+#include &lt;linux/of_device.h&gt;<BR>
+#include &lt;linux/of_platform.h&gt;<BR>
+#endif<BR>
+<BR>
+#include &quot;xilinx_hwicap.h&quot;<BR>
+#include &quot;buffer_icap.h&quot;<BR>
+#include &quot;fifo_icap.h&quot;<BR>
+<BR>
+#define DRIVER_NAME &quot;xilinx_icap&quot;<BR>
+<BR>
+#define HWICAP_REGS&nbsp;&nbsp; (0x10000)<BR>
+<BR>
+/* dynamically allocate device number */<BR>
+static int xhwicap_major;<BR>
+static int xhwicap_minor;<BR>
+#define HWICAP_DEVICES 1<BR>
+<BR>
+module_param(xhwicap_major, int, S_IRUGO);<BR>
+module_param(xhwicap_minor, int, S_IRUGO);<BR>
+<BR>
+/* An array, which is set to true when the device is registered. */<BR>
+static bool probed_devices[HWICAP_DEVICES];<BR>
+<BR>
+static struct class *icap_class;<BR>
+<BR>
+#define UNIMPLEMENTED 0xFFFF<BR>
+<BR>
+static const struct config_registers v2_config_registers = {<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .CRC = 0,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .FAR = 1,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .FDRI = 2,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .FDRO = 3,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .CMD = 4,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .CTL = 5,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .MASK = 6,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .STAT = 7,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .LOUT = 8,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .COR = 9,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .MFWR = 10,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .FLR = 11,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .KEY = 12,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .CBC = 13,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .IDCODE = 14,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .AXSS = UNIMPLEMENTED,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .C0R_1 = UNIMPLEMENTED,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .CSOB = UNIMPLEMENTED,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .WBSTAR = UNIMPLEMENTED,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .TIMER = UNIMPLEMENTED,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .BOOTSTS = UNIMPLEMENTED,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .CTL_1 = UNIMPLEMENTED,<BR>
+};<BR>
+<BR>
+static const struct config_registers v4_config_registers = {<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .CRC = 0,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .FAR = 1,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .FDRI = 2,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .FDRO = 3,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .CMD = 4,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .CTL = 5,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .MASK = 6,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .STAT = 7,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .LOUT = 8,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .COR = 9,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .MFWR = 10,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .FLR = UNIMPLEMENTED,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .KEY = UNIMPLEMENTED,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .CBC = 11,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .IDCODE = 12,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .AXSS = 13,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .C0R_1 = UNIMPLEMENTED,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .CSOB = UNIMPLEMENTED,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .WBSTAR = UNIMPLEMENTED,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .TIMER = UNIMPLEMENTED,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .BOOTSTS = UNIMPLEMENTED,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .CTL_1 = UNIMPLEMENTED,<BR>
+};<BR>
+static const struct config_registers v5_config_registers = {<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .CRC = 0,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .FAR = 1,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .FDRI = 2,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .FDRO = 3,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .CMD = 4,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .CTL = 5,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .MASK = 6,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .STAT = 7,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .LOUT = 8,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .COR = 9,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .MFWR = 10,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .FLR = UNIMPLEMENTED,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .KEY = UNIMPLEMENTED,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .CBC = 11,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .IDCODE = 12,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .AXSS = 13,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .C0R_1 = 14,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .CSOB = 15,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .WBSTAR = 16,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .TIMER = 17,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .BOOTSTS = 18,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .CTL_1 = 19,<BR>
+};<BR>
+<BR>
+/**<BR>
+ * hwicap_command_desync: Send a DESYNC command to the ICAP port.<BR>
+ * @parameter drvdata: a pointer to the drvdata.<BR>
+ *<BR>
+ * This command desynchronizes the ICAP After this command, a<BR>
+ * bitstream containing a NULL packet, followed by a SYNCH packet is<BR>
+ * required before the ICAP will recognize commands.<BR>
+ */<BR>
+int hwicap_command_desync(struct hwicap_drvdata *drvdata)<BR>
+{<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u32 buffer[4];<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u32 index = 0;<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /*<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * Create the data to be written to the ICAP.<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; buffer[index++] = hwicap_type_1_write(drvdata-&gt;config_regs-&gt;CMD) | 1;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; buffer[index++] = XHI_CMD_DESYNCH;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; buffer[index++] = XHI_NOOP_PACKET;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; buffer[index++] = XHI_NOOP_PACKET;<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /*<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * Write the data to the FIFO and intiate the transfer of data present<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * in the FIFO to the ICAP device.<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return drvdata-&gt;config-&gt;set_configuration(drvdata,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &amp;buffer[0], index);<BR>
+}<BR>
+<BR>
+/**<BR>
+ * hwicap_command_capture: Send a CAPTURE command to the ICAP port.<BR>
+ * @parameter drvdata: a pointer to the drvdata.<BR>
+ *<BR>
+ * This command captures all of the flip flop states so they will be<BR>
+ * available during readback.&nbsp; One can use this command instead of<BR>
+ * enabling the CAPTURE block in the design.<BR>
+ */<BR>
+int hwicap_command_capture(struct hwicap_drvdata *drvdata)<BR>
+{<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u32 buffer[7];<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u32 index = 0;<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /*<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * Create the data to be written to the ICAP.<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; buffer[index++] = XHI_DUMMY_PACKET;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; buffer[index++] = XHI_SYNC_PACKET;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; buffer[index++] = XHI_NOOP_PACKET;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; buffer[index++] = hwicap_type_1_write(drvdata-&gt;config_regs-&gt;CMD) | 1;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; buffer[index++] = XHI_CMD_GCAPTURE;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; buffer[index++] = XHI_DUMMY_PACKET;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; buffer[index++] = XHI_DUMMY_PACKET;<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /*<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * Write the data to the FIFO and intiate the transfer of data<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * present in the FIFO to the ICAP device.<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return drvdata-&gt;config-&gt;set_configuration(drvdata,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &amp;buffer[0], index);<BR>
+<BR>
+}<BR>
+<BR>
+/**<BR>
+ * hwicap_get_configuration_register: Query a configuration register.<BR>
+ * @parameter drvdata: a pointer to the drvdata.<BR>
+ * @parameter reg: a constant which represents the configuration<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; register value to be returned.<BR>
+ * &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Examples:&nbsp; XHI_IDCODE, XHI_FLR.<BR>
+ * @parameter RegData: returns the value of the register.<BR>
+ *<BR>
+ * Sends a query packet to the ICAP and then receives the response.<BR>
+ * The icap is left in Synched state.<BR>
+ */<BR>
+int hwicap_get_configuration_register(struct hwicap_drvdata *drvdata,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u32 reg, u32 *RegData)<BR>
+{<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int status;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u32 buffer[6];<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u32 index = 0;<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /*<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * Create the data to be written to the ICAP.<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; buffer[index++] = XHI_DUMMY_PACKET;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; buffer[index++] = XHI_SYNC_PACKET;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; buffer[index++] = XHI_NOOP_PACKET;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; buffer[index++] = hwicap_type_1_read(reg) | 1;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; buffer[index++] = XHI_NOOP_PACKET;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; buffer[index++] = XHI_NOOP_PACKET;<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /*<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * Write the data to the FIFO and intiate the transfer of data present<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * in the FIFO to the ICAP device.<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; status = drvdata-&gt;config-&gt;set_configuration(drvdata,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &amp;buffer[0], index);<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (status)<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return status;<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /*<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * Read the configuration register<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; status = drvdata-&gt;config-&gt;get_configuration(drvdata, RegData, 1);<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (status)<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return status;<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 0;<BR>
+}<BR>
+<BR>
+int hwicap_initialize_hwicap(struct hwicap_drvdata *drvdata)<BR>
+{<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int status;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u32 idcode;<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dev_dbg(drvdata-&gt;dev, &quot;initializing\n&quot;);<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Abort any current transaction, to make sure we have the<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * ICAP in a good state. */<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dev_dbg(drvdata-&gt;dev, &quot;Reset...\n&quot;);<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; drvdata-&gt;config-&gt;reset(drvdata);<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dev_dbg(drvdata-&gt;dev, &quot;Desync...\n&quot;);<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; status = hwicap_command_desync(drvdata);<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (status)<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return status;<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Attempt to read the IDCODE from ICAP.&nbsp; This<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * may not be returned correctly, due to the design of the<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * hardware.<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dev_dbg(drvdata-&gt;dev, &quot;Reading IDCODE...\n&quot;);<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; status = hwicap_get_configuration_register(<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; drvdata, drvdata-&gt;config_regs-&gt;IDCODE, &amp;idcode);<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dev_dbg(drvdata-&gt;dev, &quot;IDCODE = %x\n&quot;, idcode);<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (status)<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return status;<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dev_dbg(drvdata-&gt;dev, &quot;Desync...\n&quot;);<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; status = hwicap_command_desync(drvdata);<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (status)<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return status;<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 0;<BR>
+}<BR>
+<BR>
+static ssize_t<BR>
+hwicap_read(struct file *file, char *buf, size_t count, loff_t *ppos)<BR>
+{<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct hwicap_drvdata *drvdata = file-&gt;private_data;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ssize_t bytes_to_read = 0;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u32 *kbuf;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u32 words;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u32 bytes_remaining;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int status;<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (down_interruptible(&amp;drvdata-&gt;sem))<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return -ERESTARTSYS;<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (drvdata-&gt;read_buffer_in_use) {<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* If there are leftover bytes in the buffer, just */<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* return them and don't try to read more from the */<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* ICAP device. */<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bytes_to_read =<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (count &lt; drvdata-&gt;read_buffer_in_use) ? count :<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; drvdata-&gt;read_buffer_in_use;<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Return the data currently in the read buffer. */<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (copy_to_user(buf, drvdata-&gt;read_buffer, bytes_to_read)) {<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; status = -EFAULT;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; goto error;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; drvdata-&gt;read_buffer_in_use -= bytes_to_read;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; memcpy(drvdata-&gt;read_buffer + bytes_to_read,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; drvdata-&gt;read_buffer, 4 - bytes_to_read);<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else {<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Get new data from the ICAP, and return was was requested. */<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; kbuf = (u32 *) get_zeroed_page(GFP_KERNEL);<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!kbuf) {<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; status = -ENOMEM;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; goto error;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* The ICAP device is only able to read complete */<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* words.&nbsp; If a number of bytes that do not correspond */<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* to complete words is requested, then we read enough */<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* words to get the required number of bytes, and then */<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* save the remaining bytes for the next read. */<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Determine the number of words to read, rounding up */<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* if necessary. */<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; words = ((count + 3) &gt;&gt; 2);<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bytes_to_read = words &lt;&lt; 2;<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (bytes_to_read &gt; PAGE_SIZE)<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bytes_to_read = PAGE_SIZE;<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Ensure we only read a complete number of words. */<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bytes_remaining = bytes_to_read &amp; 3;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bytes_to_read &amp;= ~3;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; words = bytes_to_read &gt;&gt; 2;<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; status = drvdata-&gt;config-&gt;get_configuration(drvdata,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; kbuf, words);<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* If we didn't read correctly, then bail out. */<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (status) {<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; free_page((unsigned long)kbuf);<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; goto error;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* If we fail to return the data to the user, then bail out. */<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (copy_to_user(buf, kbuf, bytes_to_read)) {<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; free_page((unsigned long)kbuf);<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; status = -EFAULT;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; goto error;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; memcpy(kbuf, drvdata-&gt;read_buffer, bytes_remaining);<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; drvdata-&gt;read_buffer_in_use = bytes_remaining;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; free_page((unsigned long)kbuf);<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; status = bytes_to_read;<BR>
+ error:<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; up(&amp;drvdata-&gt;sem);<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return status;<BR>
+}<BR>
+<BR>
+static ssize_t<BR>
+hwicap_write(struct file *file, const char *buf,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; size_t count, loff_t *ppos)<BR>
+{<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct hwicap_drvdata *drvdata = file-&gt;private_data;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ssize_t written = 0;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ssize_t left = count;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u32 *kbuf;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ssize_t len;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ssize_t status;<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (down_interruptible(&amp;drvdata-&gt;sem))<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return -ERESTARTSYS;<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; left += drvdata-&gt;write_buffer_in_use;<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Only write multiples of 4 bytes. */<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (left &lt; 4) {<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; status = 0;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; goto error;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; kbuf = (u32 *) __get_free_page(GFP_KERNEL);<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!kbuf) {<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; status = -ENOMEM;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; goto error;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while (left &gt; 3) {<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* only write multiples of 4 bytes, so there might */<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* be as many as 3 bytes left (at the end). */<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; len = left;<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (len &gt; PAGE_SIZE)<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; len = PAGE_SIZE;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; len &amp;= ~3;<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (drvdata-&gt;write_buffer_in_use) {<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; memcpy(kbuf, drvdata-&gt;write_buffer,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; drvdata-&gt;write_buffer_in_use);<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (copy_from_user(<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; (((char *)kbuf) + (drvdata-&gt;write_buffer_in_use)),<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; buf + written,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; len - (drvdata-&gt;write_buffer_in_use))) {<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; free_page((unsigned long)kbuf);<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; status = -EFAULT;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; goto error;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else {<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (copy_from_user(kbuf, buf + written, len)) {<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; free_page((unsigned long)kbuf);<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; status = -EFAULT;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; goto error;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; status = drvdata-&gt;config-&gt;set_configuration(drvdata,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; kbuf, len &gt;&gt; 2);<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (status) {<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; free_page((unsigned long)kbuf);<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; status = -EFAULT;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; goto error;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (drvdata-&gt;write_buffer_in_use) {<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; len -= drvdata-&gt;write_buffer_in_use;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; left -= drvdata-&gt;write_buffer_in_use;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; drvdata-&gt;write_buffer_in_use = 0;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; written += len;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; left -= len;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ((left &gt; 0) &amp;&amp; (left &lt; 4)) {<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!copy_from_user(drvdata-&gt;write_buffer,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; buf + written, left)) {<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; drvdata-&gt;write_buffer_in_use = left;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; written += left;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; left = 0;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; free_page((unsigned long)kbuf);<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; status = written;<BR>
+ error:<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; up(&amp;drvdata-&gt;sem);<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return status;<BR>
+}<BR>
+<BR>
+static int hwicap_open(struct inode *inode, struct file *file)<BR>
+{<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct hwicap_drvdata *drvdata;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int status;<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; drvdata = container_of(inode-&gt;i_cdev, struct hwicap_drvdata, cdev);<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (down_interruptible(&amp;drvdata-&gt;sem))<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return -ERESTARTSYS;<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (drvdata-&gt;is_open) {<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; status = -EBUSY;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; goto error;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; status = hwicap_initialize_hwicap(drvdata);<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (status) {<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dev_err(drvdata-&gt;dev, &quot;Failed to open file&quot;);<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; goto error;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; file-&gt;private_data = drvdata;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; drvdata-&gt;write_buffer_in_use = 0;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; drvdata-&gt;read_buffer_in_use = 0;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; drvdata-&gt;is_open = 1;<BR>
+<BR>
+ error:<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; up(&amp;drvdata-&gt;sem);<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return status;<BR>
+}<BR>
+<BR>
+static int hwicap_release(struct inode *inode, struct file *file)<BR>
+{<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct hwicap_drvdata *drvdata = file-&gt;private_data;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int i;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int status = 0;<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (down_interruptible(&amp;drvdata-&gt;sem))<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return -ERESTARTSYS;<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (drvdata-&gt;write_buffer_in_use) {<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Flush write buffer. */<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (i = drvdata-&gt;write_buffer_in_use; i &lt; 4; i++)<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; drvdata-&gt;write_buffer[i] = 0;<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; status = drvdata-&gt;config-&gt;set_configuration(drvdata,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (u32 *) drvdata-&gt;write_buffer, 1);<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (status)<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; goto error;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; status = hwicap_command_desync(drvdata);<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (status)<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; goto error;<BR>
+<BR>
+ error:<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; drvdata-&gt;is_open = 0;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; up(&amp;drvdata-&gt;sem);<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return status;<BR>
+}<BR>
+<BR>
+static struct file_operations hwicap_fops = {<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .owner = THIS_MODULE,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .write = hwicap_write,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .read = hwicap_read,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .open = hwicap_open,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .release = hwicap_release,<BR>
+};<BR>
+<BR>
+static int __devinit hwicap_setup(struct device *dev, int id,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; const struct resource *regs_res,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; const struct hwicap_driver_config *config,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; const struct config_registers *config_regs)<BR>
+{<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dev_t devt;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct hwicap_drvdata *drvdata = NULL;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int retval = 0;<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dev_info(dev, &quot;Xilinx icap port driver\n&quot;);<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (id &lt; 0) {<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (id = 0; id &lt; HWICAP_DEVICES; id++)<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!probed_devices[id])<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (id &lt; 0 || id &gt;= HWICAP_DEVICES) {<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dev_err(dev, &quot;%s%i too large\n&quot;, DRIVER_NAME, id);<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return -EINVAL;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (probed_devices[id]) {<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dev_err(dev, &quot;cannot assign to %s%i; it is already in use\n&quot;,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DRIVER_NAME, id);<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return -EBUSY;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; probed_devices[id] = 1;<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; devt = MKDEV(xhwicap_major, xhwicap_minor + id);<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; drvdata = kmalloc(sizeof(struct hwicap_drvdata), GFP_KERNEL);<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!drvdata) {<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dev_err(dev, &quot;Couldn't allocate device private record\n&quot;);<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return -ENOMEM;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; memset((void *)drvdata, 0, sizeof(struct hwicap_drvdata));<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dev_set_drvdata(dev, (void *)drvdata);<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!regs_res) {<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dev_err(dev, &quot;Couldn't get registers resource\n&quot;);<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; retval = -EFAULT;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; goto failed1;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; drvdata-&gt;mem_start = regs_res-&gt;start;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; drvdata-&gt;mem_end = regs_res-&gt;end;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; drvdata-&gt;mem_size = regs_res-&gt;end - regs_res-&gt;start + 1;<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!request_mem_region(drvdata-&gt;mem_start,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; drvdata-&gt;mem_size, DRIVER_NAME)) {<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dev_err(dev, &quot;Couldn't lock memory region at %p\n&quot;,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (void *)regs_res-&gt;start);<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; retval = -EBUSY;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; goto failed1;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; drvdata-&gt;devt = devt;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; drvdata-&gt;dev = dev;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; drvdata-&gt;base_address = ioremap(drvdata-&gt;mem_start, drvdata-&gt;mem_size);<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!drvdata-&gt;base_address) {<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dev_err(dev, &quot;ioremap() failed\n&quot;);<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; goto failed2;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; drvdata-&gt;config = config;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; drvdata-&gt;config_regs = config_regs;<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; init_MUTEX(&amp;drvdata-&gt;sem);<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; drvdata-&gt;is_open = 0;<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dev_info(dev, &quot;ioremap %lx to %p with size %x\n&quot;,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (unsigned long int)drvdata-&gt;mem_start,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; drvdata-&gt;base_address, drvdata-&gt;mem_size);<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cdev_init(&amp;drvdata-&gt;cdev, &amp;hwicap_fops);<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; drvdata-&gt;cdev.owner = THIS_MODULE;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; retval = cdev_add(&amp;drvdata-&gt;cdev, devt, 1);<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (retval) {<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dev_err(dev, &quot;cdev_add() failed\n&quot;);<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; goto failed3;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /*&nbsp; devfs_mk_cdev(devt, S_IFCHR|S_IRUGO|S_IWUGO, DRIVER_NAME); */<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class_device_create(icap_class, NULL, devt, NULL, DRIVER_NAME);<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 0;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* success */<BR>
+<BR>
+ failed3:<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; iounmap(drvdata-&gt;base_address);<BR>
+<BR>
+ failed2:<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; release_mem_region(regs_res-&gt;start, drvdata-&gt;mem_size);<BR>
+<BR>
+ failed1:<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; kfree(drvdata);<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return retval;<BR>
+}<BR>
+<BR>
+static struct hwicap_driver_config buffer_icap_config = {<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .get_configuration = buffer_icap_get_configuration,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .set_configuration = buffer_icap_set_configuration,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .reset = buffer_icap_reset,<BR>
+};<BR>
+<BR>
+static struct hwicap_driver_config fifo_icap_config = {<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .get_configuration = fifo_icap_get_configuration,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .set_configuration = fifo_icap_set_configuration,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .reset = fifo_icap_reset,<BR>
+};<BR>
+<BR>
+static int __devexit hwicap_remove(struct device *dev)<BR>
+{<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct hwicap_drvdata *drvdata;<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; drvdata = (struct hwicap_drvdata *)dev_get_drvdata(dev);<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!drvdata)<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 0;<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class_device_destroy(icap_class, drvdata-&gt;devt);<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cdev_del(&amp;drvdata-&gt;cdev);<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; iounmap(drvdata-&gt;base_address);<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; release_mem_region(drvdata-&gt;mem_start, drvdata-&gt;mem_size);<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; kfree(drvdata);<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dev_set_drvdata(dev, NULL);<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; probed_devices[MINOR(dev-&gt;devt)-xhwicap_minor] = 0;<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 0;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* success */<BR>
+}<BR>
+<BR>
+static int __devinit hwicap_drv_probe(struct platform_device *pdev)<BR>
+{<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct resource *res;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; const struct config_registers *regs;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; const char *family;<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; res = platform_get_resource(pdev, IORESOURCE_MEM, 0);<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!res)<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return -ENODEV;<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* It's most likely that we're using V4, if the family is not<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; specified */<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; regs = &amp;v4_config_registers;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; family = pdev-&gt;dev.platform_data;<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (family) {<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!strcmp(family, &quot;virtex2p&quot;)) {<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; regs = &amp;v2_config_registers;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else if (!strcmp(family, &quot;virtex4&quot;)) {<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; regs = &amp;v4_config_registers;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else if (!strcmp(family, &quot;virtex5&quot;)) {<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; regs = &amp;v5_config_registers;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return hwicap_setup(&amp;pdev-&gt;dev, pdev-&gt;id, res,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &amp;buffer_icap_config, regs);<BR>
+}<BR>
+<BR>
+static int __devexit hwicap_drv_remove(struct platform_device *pdev)<BR>
+{<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return hwicap_remove(&amp;pdev-&gt;dev);<BR>
+}<BR>
+<BR>
+static struct platform_driver hwicap_platform_driver = {<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .probe = hwicap_drv_probe,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .remove = hwicap_drv_remove,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .driver = {<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .owner = THIS_MODULE,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .name = DRIVER_NAME,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; },<BR>
+};<BR>
+<BR>
+/* ---------------------------------------------------------------------<BR>
+ * OF bus binding<BR>
+ */<BR>
+<BR>
+#if defined(CONFIG_OF)<BR>
+static int __devinit<BR>
+hwicap_of_probe(struct of_device *op, const struct of_device_id *match)<BR>
+{<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct resource res;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; const unsigned int *id;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; const char *family;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int rc;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; const struct hwicap_driver_config *config = match-&gt;data;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; const struct config_registers *regs;<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dev_dbg(&amp;op-&gt;dev, &quot;hwicap_of_probe(%p, %p)\n&quot;, op, match);<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rc = of_address_to_resource(op-&gt;node, 0, &amp;res);<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (rc) {<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dev_err(&amp;op-&gt;dev, &quot;invalid address\n&quot;);<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return rc;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; id = of_get_property(op-&gt;node, &quot;port-number&quot;, NULL);<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* It's most likely that we're using V4, if the family is not<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; specified */<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; regs = &amp;v4_config_registers;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; family = of_get_property(op-&gt;node, &quot;xlnx,family&quot;, NULL);<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (family) {<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!strcmp(family, &quot;virtex2p&quot;)) {<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; regs = &amp;v2_config_registers;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else if (!strcmp(family, &quot;virtex4&quot;)) {<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; regs = &amp;v4_config_registers;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else if (!strcmp(family, &quot;virtex5&quot;)) {<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; regs = &amp;v5_config_registers;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return hwicap_setup(&amp;op-&gt;dev, id ? *id : -1, &amp;res, config,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; regs);<BR>
+}<BR>
+<BR>
+static int __devexit hwicap_of_remove(struct of_device *op)<BR>
+{<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return hwicap_remove(&amp;op-&gt;dev);<BR>
+}<BR>
+<BR>
+/* Match table for of_platform binding */<BR>
+static const struct of_device_id __devinit hwicap_of_match[] = {<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { .compatible = &quot;xlnx,opb-hwicap-1.00.b&quot;, .data = &amp;buffer_icap_config},<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { .compatible = &quot;xlnx,xps-hwicap-1.00.a&quot;, .data = &amp;fifo_icap_config},<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {},<BR>
+};<BR>
+MODULE_DEVICE_TABLE(of, hwicap_of_match);<BR>
+<BR>
+static struct of_platform_driver hwicap_of_driver = {<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .owner = THIS_MODULE,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .name = DRIVER_NAME,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .match_table = hwicap_of_match,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .probe = hwicap_of_probe,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .remove = __devexit_p(hwicap_of_remove),<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .driver = {<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .name = DRIVER_NAME,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; },<BR>
+};<BR>
+<BR>
+/* Registration helpers to keep the number of #ifdefs to a minimum */<BR>
+static inline int __devinit hwicap_of_register(void)<BR>
+{<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pr_debug(&quot;hwicap: calling of_register_platform_driver()\n&quot;);<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return of_register_platform_driver(&amp;hwicap_of_driver);<BR>
+}<BR>
+<BR>
+static inline void __devexit hwicap_of_unregister(void)<BR>
+{<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; of_unregister_platform_driver(&amp;hwicap_of_driver);<BR>
+}<BR>
+#else /* CONFIG_OF */<BR>
+/* CONFIG_OF not enabled; do nothing helpers */<BR>
+static inline int __devinit hwicap_of_register(void) { return 0; }<BR>
+static inline void __devexit hwicap_of_unregister(void) { }<BR>
+#endif /* CONFIG_OF */<BR>
+<BR>
+static int __devinit hwicap_module_init(void)<BR>
+{<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dev_t devt;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int retval;<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; icap_class = class_create(THIS_MODULE, &quot;xilinx_config&quot;);<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (xhwicap_major) {<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; devt = MKDEV(xhwicap_major, xhwicap_minor);<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; retval = register_chrdev_region(<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; devt,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HWICAP_DEVICES,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DRIVER_NAME);<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (retval &lt; 0)<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return retval;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else {<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; retval = alloc_chrdev_region(&amp;devt,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; xhwicap_minor,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HWICAP_DEVICES,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DRIVER_NAME);<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (retval &lt; 0)<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return retval;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; xhwicap_major = MAJOR(devt);<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; retval = platform_driver_register(&amp;hwicap_platform_driver);<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (retval)<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; goto failed1;<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; retval = hwicap_of_register();<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (retval)<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; goto failed2;<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return retval;<BR>
+<BR>
+ failed2:<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; platform_driver_unregister(&amp;hwicap_platform_driver);<BR>
+<BR>
+ failed1:<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unregister_chrdev_region(devt, HWICAP_DEVICES);<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return retval;<BR>
+}<BR>
+<BR>
+static void __devexit hwicap_module_cleanup(void)<BR>
+{<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dev_t devt = MKDEV(xhwicap_major, xhwicap_minor);<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class_destroy(icap_class);<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; platform_driver_unregister(&amp;hwicap_platform_driver);<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; hwicap_of_unregister();<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unregister_chrdev_region(devt, HWICAP_DEVICES);<BR>
+}<BR>
+<BR>
+module_init(hwicap_module_init);<BR>
+module_exit(hwicap_module_cleanup);<BR>
+<BR>
+MODULE_AUTHOR(&quot;Xilinx, Inc; Xilinx Research Labs Group&quot;);<BR>
+MODULE_DESCRIPTION(&quot;Xilinx ICAP Port Driver&quot;);<BR>
+MODULE_LICENSE(&quot;GPL&quot;);<BR>
diff --git a/drivers/char/xilinx_hwicap/xilinx_hwicap.h b/drivers/char/xilinx_hwicap/xilinx_hwicap.h<BR>
new file mode 100644<BR>
index 0000000..b6b47d0<BR>
--- /dev/null<BR>
+++ b/drivers/char/xilinx_hwicap/xilinx_hwicap.h<BR>
@@ -0,0 +1,193 @@<BR>
+/*****************************************************************************<BR>
+ *<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; Author: Xilinx, Inc.<BR>
+ *<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; This program is free software; you can redistribute it and/or modify it<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; under the terms of the GNU General Public License as published by the<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; Free Software Foundation; either version 2 of the License, or (at your<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; option) any later version.<BR>
+ *<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION &quot;AS IS&quot;<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; SOLUTIONS FOR XILINX DEVICES.&nbsp; BY PROVIDING THIS DESIGN, CODE,<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; FOR YOUR IMPLEMENTATION.&nbsp; XILINX EXPRESSLY DISCLAIMS ANY<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; FOR A PARTICULAR PURPOSE.<BR>
+ *<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; Xilinx products are not intended for use in life support appliances,<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; devices, or systems. Use in such applications is expressly prohibited.<BR>
+ *<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; (c) Copyright 2003-2007 Xilinx Inc.<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; All rights reserved.<BR>
+ *<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; You should have received a copy of the GNU General Public License along<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; with this program; if not, write to the Free Software Foundation, Inc.,<BR>
+ *&nbsp;&nbsp;&nbsp;&nbsp; 675 Mass Ave, Cambridge, MA 02139, USA.<BR>
+ *<BR>
+ *****************************************************************************/<BR>
+<BR>
+#ifndef XILINX_HWICAP_H_&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* prevent circular inclusions */<BR>
+#define XILINX_HWICAP_H_&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* by using protection macros */<BR>
+<BR>
+#include &lt;linux/types.h&gt;<BR>
+#include &lt;linux/cdev.h&gt;<BR>
+#include &lt;linux/version.h&gt;<BR>
+#include &lt;linux/platform_device.h&gt;<BR>
+<BR>
+#include &lt;asm/io.h&gt;<BR>
+<BR>
+struct hwicap_drvdata {<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u32 write_buffer_in_use;&nbsp; /* Always in [0,3] */<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u8 write_buffer[4];<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u32 read_buffer_in_use; &nbsp; /* Always in [0,3] */<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u8 read_buffer[4];<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u32 mem_start;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; /* phys. address of the control registers */<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u32 mem_end;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; /* phys. address of the control registers */<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u32 mem_size;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; void __iomem *base_address;/* virt. address of the control registers */<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct device *dev;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct cdev cdev;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Char device structure */<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dev_t devt;<BR>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; const struct hwicap_driver_config *config;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; const struct config_registers *config_regs;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; void *private_data;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bool is_open;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bool is_accessing;<BR>
+};<BR>
+<BR>
+struct hwicap_driver_config {<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int (*get_configuration)(struct hwicap_drvdata *drvdata, u32 *data,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u32 size);<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int (*set_configuration)(struct hwicap_drvdata *drvdata, u32 *data,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u32 size);<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; void (*reset)(struct hwicap_drvdata *drvdata);<BR>
+};<BR>
+<BR>
+/* Number of times to poll the done regsiter */<BR>
+#define XHI_MAX_RETRIES&nbsp;&nbsp;&nbsp;&nbsp; 10<BR>
+<BR>
+/************ Constant Definitions *************/<BR>
+<BR>
+#define XHI_PAD_FRAMES&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0x1<BR>
+<BR>
+/* Mask for calculating configuration packet headers */<BR>
+#define XHI_WORD_COUNT_MASK_TYPE_1&nbsp; 0x7FFUL<BR>
+#define XHI_WORD_COUNT_MASK_TYPE_2&nbsp; 0x1FFFFFUL<BR>
+#define XHI_TYPE_MASK&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0x7<BR>
+#define XHI_REGISTER_MASK&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0xF<BR>
+#define XHI_OP_MASK&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0x3<BR>
+<BR>
+#define XHI_TYPE_SHIFT&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 29<BR>
+#define XHI_REGISTER_SHIFT&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 13<BR>
+#define XHI_OP_SHIFT&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 27<BR>
+<BR>
+#define XHI_TYPE_1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1<BR>
+#define XHI_TYPE_2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2<BR>
+#define XHI_OP_WRITE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2<BR>
+#define XHI_OP_READ&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1<BR>
+<BR>
+/* Address Block Types */<BR>
+#define XHI_FAR_CLB_BLOCK&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0<BR>
+#define XHI_FAR_BRAM_BLOCK&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1<BR>
+#define XHI_FAR_BRAM_INT_BLOCK&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2<BR>
+<BR>
+struct config_registers {<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u32 CRC;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u32 FAR;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u32 FDRI;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u32 FDRO;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u32 CMD;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u32 CTL;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u32 MASK;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u32 STAT;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u32 LOUT;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u32 COR;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u32 MFWR;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u32 FLR;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u32 KEY;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u32 CBC;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u32 IDCODE;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u32 AXSS;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u32 C0R_1;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u32 CSOB;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u32 WBSTAR;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u32 TIMER;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u32 BOOTSTS;<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u32 CTL_1;<BR>
+};<BR>
+<BR>
+/* Configuration Commands */<BR>
+#define XHI_CMD_NULL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0<BR>
+#define XHI_CMD_WCFG&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1<BR>
+#define XHI_CMD_MFW&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2<BR>
+#define XHI_CMD_DGHIGH&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3<BR>
+#define XHI_CMD_RCFG&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4<BR>
+#define XHI_CMD_START&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5<BR>
+#define XHI_CMD_RCAP&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 6<BR>
+#define XHI_CMD_RCRC&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 7<BR>
+#define XHI_CMD_AGHIGH&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 8<BR>
+#define XHI_CMD_SWITCH&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 9<BR>
+#define XHI_CMD_GRESTORE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10<BR>
+#define XHI_CMD_SHUTDOWN&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 11<BR>
+#define XHI_CMD_GCAPTURE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 12<BR>
+#define XHI_CMD_DESYNCH&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 13<BR>
+#define XHI_CMD_IPROG&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 15 /* Only in Virtex5 */<BR>
+#define XHI_CMD_CRCC&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 16 /* Only in Virtex5 */<BR>
+#define XHI_CMD_LTIMER&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 17 /* Only in Virtex5 */<BR>
+<BR>
+/* Packet constants */<BR>
+#define XHI_SYNC_PACKET&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0xAA995566UL<BR>
+#define XHI_DUMMY_PACKET&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0xFFFFFFFFUL<BR>
+#define XHI_NOOP_PACKET&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (XHI_TYPE_1 &lt;&lt; XHI_TYPE_SHIFT)<BR>
+#define XHI_TYPE_2_READ ((XHI_TYPE_2 &lt;&lt; XHI_TYPE_SHIFT) | \<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (XHI_OP_READ &lt;&lt; XHI_OP_SHIFT))<BR>
+<BR>
+#define XHI_TYPE_2_WRITE ((XHI_TYPE_2 &lt;&lt; XHI_TYPE_SHIFT) | \<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (XHI_OP_WRITE &lt;&lt; XHI_OP_SHIFT))<BR>
+<BR>
+#define XHI_TYPE2_CNT_MASK&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0x07FFFFFF<BR>
+<BR>
+#define XHI_TYPE_1_PACKET_MAX_WORDS 2047UL<BR>
+#define XHI_TYPE_1_HEADER_BYTES&nbsp;&nbsp;&nbsp;&nbsp; 4<BR>
+#define XHI_TYPE_2_HEADER_BYTES&nbsp;&nbsp;&nbsp;&nbsp; 8<BR>
+<BR>
+/* Constant to use for CRC check when CRC has been disabled */<BR>
+#define XHI_DISABLED_AUTO_CRC&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0x0000DEFCUL<BR>
+<BR>
+/**<BR>
+ * hwicap_type_1_read: Generates a Type 1 read packet header.<BR>
+ * @parameter: Register is the address of the register to be read back.<BR>
+ *<BR>
+ * Generates a Type 1 read packet header, which is used to indirectly<BR>
+ * read registers in the configuration logic.&nbsp; This packet must then<BR>
+ * be sent through the icap device, and a return packet received with<BR>
+ * the information.<BR>
+ **/<BR>
+static inline u32 hwicap_type_1_read(u32 Register)<BR>
+{<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return (XHI_TYPE_1 &lt;&lt; XHI_TYPE_SHIFT) |<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (Register &lt;&lt; XHI_REGISTER_SHIFT) |<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (XHI_OP_READ &lt;&lt; XHI_OP_SHIFT);<BR>
+}<BR>
+<BR>
+/**<BR>
+ * hwicap_type_1_write: Generates a Type 1 write packet header<BR>
+ * @parameter: Register is the address of the register to be read back.<BR>
+ **/<BR>
+static inline u32 hwicap_type_1_write(u32 Register)<BR>
+{<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return (XHI_TYPE_1 &lt;&lt; XHI_TYPE_SHIFT) |<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (Register &lt;&lt; XHI_REGISTER_SHIFT) |<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (XHI_OP_WRITE &lt;&lt; XHI_OP_SHIFT);<BR>
+}<BR>
+<BR>
+#endif<BR>
--<BR>
1.5.3.4-dirty<BR>
<BR>
<BR>
<BR>
</FONT>
</P>

</BODY>
</HTML>