--- a/devices/ccat/update.c Thu Jun 05 16:40:01 2014 +0200
+++ b/devices/ccat/update.c Thu Jun 05 17:08:54 2014 +0200
@@ -57,13 +57,6 @@
size_t size;
};
-static void ccat_wait_status_cleared(void __iomem * const ioaddr);
-static int ccat_read_flash(void __iomem * const ioaddr, char __user * buf,
- u32 len, loff_t * off);
-static void ccat_write_flash(const struct update_buffer *const buf);
-static void ccat_update_cmd(void __iomem * const ioaddr, u8 cmd, u16 clocks);
-static void ccat_update_destroy(struct kref *ref);
-
/**
* wait_until_busy_reset() - wait until the busy flag was reset
* @ioaddr: address of the CCAT Update function in PCI config space
@@ -76,6 +69,215 @@
}
}
+/**
+ * __ccat_update_cmd() - Helper to issue a FPGA flash command
+ * @ioaddr: address of the CCAT Update function in PCI config space
+ * @cmd: the command identifier
+ * @clocks: the number of clocks associated with the specified command
+ *
+ * no write memory barrier is called and the busy flag is not evaluated
+ */
+static inline void __ccat_update_cmd(void __iomem * const ioaddr, u8 cmd,
+ u16 clocks)
+{
+ iowrite8((0xff00 & clocks) >> 8, ioaddr);
+ iowrite8(0x00ff & clocks, ioaddr + 0x8);
+ iowrite8(cmd, ioaddr + 0x10);
+}
+
+/**
+ * ccat_update_cmd() - Helper to issue a FPGA flash command
+ * @ioaddr: address of the CCAT Update function in PCI config space
+ * @cmd: the command identifier
+ * @clocks: the number of clocks associated with the specified command
+ *
+ * Triggers a full flash command cycle with write memory barrier and
+ * command activate. This call blocks until the busy flag is reset.
+ */
+static inline void ccat_update_cmd(void __iomem * const ioaddr, u8 cmd,
+ u16 clocks)
+{
+ __ccat_update_cmd(ioaddr, cmd, clocks);
+ wmb();
+ iowrite8(0xff, ioaddr + 0x7f8);
+ wait_until_busy_reset(ioaddr);
+}
+
+/**
+ * ccat_update_cmd_addr() - Helper to issue a FPGA flash command with address parameter
+ * @ioaddr: address of the CCAT Update function in PCI config space
+ * @cmd: the command identifier
+ * @clocks: the number of clocks associated with the specified command
+ * @addr: 24 bit address associated with the specified command
+ *
+ * Triggers a full flash command cycle with write memory barrier and
+ * command activate. This call blocks until the busy flag is reset.
+ */
+static inline void ccat_update_cmd_addr(void __iomem * const ioaddr,
+ u8 cmd, u16 clocks, u32 addr)
+{
+ const u8 addr_0 = SWAP_BITS(addr & 0xff);
+ const u8 addr_1 = SWAP_BITS((addr & 0xff00) >> 8);
+ const u8 addr_2 = SWAP_BITS((addr & 0xff0000) >> 16);
+
+ __ccat_update_cmd(ioaddr, cmd, clocks);
+ iowrite8(addr_2, ioaddr + 0x18);
+ iowrite8(addr_1, ioaddr + 0x20);
+ iowrite8(addr_0, ioaddr + 0x28);
+ wmb();
+ iowrite8(0xff, ioaddr + 0x7f8);
+ wait_until_busy_reset(ioaddr);
+}
+
+/**
+ * ccat_get_status() - Read CCAT Update status
+ * @ioaddr: address of the CCAT Update function in PCI config space
+ *
+ * Return: the current status of the CCAT Update function
+ */
+static u8 ccat_get_status(void __iomem * const ioaddr)
+{
+ ccat_update_cmd(ioaddr, CCAT_READ_STATUS);
+ return ioread8(ioaddr + 0x20);
+}
+
+/**
+ * ccat_read_flash_block() - Read a block of CCAT configuration data from flash
+ * @ioaddr: address of the CCAT Update function in PCI config space
+ * @addr: 24 bit address of the block to read
+ * @len: number of bytes to read from this block, len <= CCAT_DATA_BLOCK_SIZE
+ * @buf: output buffer in user space
+ *
+ * Copies one block of configuration data from the CCAT FPGA's flash to
+ * the user space buffer.
+ * Note that the size of the FPGA's firmware is not known exactly so it
+ * is very possible that the overall buffer ends with a lot of 0xff.
+ *
+ * Return: the number of bytes copied
+ */
+static int ccat_read_flash_block(void __iomem * const ioaddr,
+ const u32 addr, const u16 len,
+ char __user * const buf)
+{
+ u16 i;
+ const u16 clocks = 8 * len;
+
+ ccat_update_cmd_addr(ioaddr, CCAT_READ_FLASH + clocks, addr);
+ for (i = 0; i < len; i++) {
+ put_user(ioread8(ioaddr + CCAT_DATA_IN_4 + 8 * i), buf + i);
+ }
+ return len;
+}
+
+/**
+ * ccat_read_flash() - Read a chunk of CCAT configuration data from flash
+ * @ioaddr: address of the CCAT Update function in PCI config space
+ * @buf: output buffer in user space
+ * @len: number of bytes to read
+ * @off: offset in the configuration data
+ *
+ * Copies multiple blocks of configuration data from the CCAT FPGA's
+ * flash to the user space buffer.
+ *
+ * Return: the number of bytes copied
+ */
+static int ccat_read_flash(void __iomem * const ioaddr, char __user * buf,
+ u32 len, loff_t * off)
+{
+ const loff_t start = *off;
+
+ while (len > CCAT_DATA_BLOCK_SIZE) {
+ *off +=
+ ccat_read_flash_block(ioaddr, *off, CCAT_DATA_BLOCK_SIZE,
+ buf);
+ buf += CCAT_DATA_BLOCK_SIZE;
+ len -= CCAT_DATA_BLOCK_SIZE;
+ }
+ *off += ccat_read_flash_block(ioaddr, *off, len, buf);
+ return *off - start;
+}
+
+/**
+ * ccat_wait_status_cleared() - wait until CCAT status is cleared
+ * @ioaddr: address of the CCAT Update function in PCI config space
+ *
+ * Blocks until bit 7 of the CCAT Update status is reset
+ */
+static void ccat_wait_status_cleared(void __iomem * const ioaddr)
+{
+ u8 status;
+
+ do {
+ status = ccat_get_status(ioaddr);
+ } while (status & (1 << 7));
+}
+
+/**
+ * ccat_write_flash_block() - Write a block of CCAT configuration data to flash
+ * @ioaddr: address of the CCAT Update function in PCI config space
+ * @addr: 24 bit start address in the CCAT FPGA's flash
+ * @len: number of bytes to write in this block, len <= CCAT_WRITE_BLOCK_SIZE
+ * @buf: input buffer
+ *
+ * Copies one block of configuration data to the CCAT FPGA's flash
+ *
+ * Return: the number of bytes copied
+ */
+static int ccat_write_flash_block(void __iomem * const ioaddr,
+ const u32 addr, const u16 len,
+ const char *const buf)
+{
+ const u16 clocks = 8 * len;
+ u16 i;
+
+ ccat_update_cmd(ioaddr, CCAT_WRITE_ENABLE);
+ for (i = 0; i < len; i++) {
+ iowrite8(buf[i], ioaddr + CCAT_DATA_OUT_4 + 8 * i);
+ }
+ ccat_update_cmd_addr(ioaddr, CCAT_WRITE_FLASH + clocks, addr);
+ ccat_wait_status_cleared(ioaddr);
+ return len;
+}
+
+/**
+ * ccat_write_flash() - Write a new CCAT configuration to FPGA's flash
+ * @update: a CCAT Update buffer containing the new FPGA configuration
+ */
+static void ccat_write_flash(const struct update_buffer *const update)
+{
+ const char *buf = update->data;
+ u32 off = 0;
+ size_t len = update->size;
+
+ while (len > CCAT_WRITE_BLOCK_SIZE) {
+ ccat_write_flash_block(update->update->ioaddr, off,
+ (u16) CCAT_WRITE_BLOCK_SIZE, buf);
+ off += CCAT_WRITE_BLOCK_SIZE;
+ buf += CCAT_WRITE_BLOCK_SIZE;
+ len -= CCAT_WRITE_BLOCK_SIZE;
+ }
+ ccat_write_flash_block(update->update->ioaddr, off, (u16) len, buf);
+}
+
+/**
+ * ccat_update_destroy() - Cleanup the CCAT Update function
+ * @ref: pointer to a struct kref embedded into a struct ccat_update, which we intend to destroy
+ *
+ * Retrieves the parent struct ccat_update and destroys it.
+ */
+static void ccat_update_destroy(struct kref *ref)
+{
+ struct ccat_update *update =
+ container_of(ref, struct ccat_update, refcount);
+
+ cdev_del(&update->cdev);
+ device_destroy(update->class, update->dev);
+ class_destroy(update->class);
+ unregister_chrdev_region(update->dev, 1);
+ kfree(update);
+ pr_debug("%s(): done\n", __FUNCTION__);
+}
+
static int ccat_update_open(struct inode *const i, struct file *const f)
{
struct ccat_update *update =
@@ -184,66 +386,6 @@
};
/**
- * __ccat_update_cmd() - Helper to issue a FPGA flash command
- * @ioaddr: address of the CCAT Update function in PCI config space
- * @cmd: the command identifier
- * @clocks: the number of clocks associated with the specified command
- *
- * no write memory barrier is called and the busy flag is not evaluated
- */
-static inline void __ccat_update_cmd(void __iomem * const ioaddr, u8 cmd,
- u16 clocks)
-{
- iowrite8((0xff00 & clocks) >> 8, ioaddr);
- iowrite8(0x00ff & clocks, ioaddr + 0x8);
- iowrite8(cmd, ioaddr + 0x10);
-}
-
-/**
- * ccat_update_cmd() - Helper to issue a FPGA flash command
- * @ioaddr: address of the CCAT Update function in PCI config space
- * @cmd: the command identifier
- * @clocks: the number of clocks associated with the specified command
- *
- * Triggers a full flash command cycle with write memory barrier and
- * command activate. This call blocks until the busy flag is reset.
- */
-static inline void ccat_update_cmd(void __iomem * const ioaddr, u8 cmd,
- u16 clocks)
-{
- __ccat_update_cmd(ioaddr, cmd, clocks);
- wmb();
- iowrite8(0xff, ioaddr + 0x7f8);
- wait_until_busy_reset(ioaddr);
-}
-
-/**
- * ccat_update_cmd_addr() - Helper to issue a FPGA flash command with address parameter
- * @ioaddr: address of the CCAT Update function in PCI config space
- * @cmd: the command identifier
- * @clocks: the number of clocks associated with the specified command
- * @addr: 24 bit address associated with the specified command
- *
- * Triggers a full flash command cycle with write memory barrier and
- * command activate. This call blocks until the busy flag is reset.
- */
-static inline void ccat_update_cmd_addr(void __iomem * const ioaddr,
- u8 cmd, u16 clocks, u32 addr)
-{
- const u8 addr_0 = SWAP_BITS(addr & 0xff);
- const u8 addr_1 = SWAP_BITS((addr & 0xff00) >> 8);
- const u8 addr_2 = SWAP_BITS((addr & 0xff0000) >> 16);
-
- __ccat_update_cmd(ioaddr, cmd, clocks);
- iowrite8(addr_2, ioaddr + 0x18);
- iowrite8(addr_1, ioaddr + 0x20);
- iowrite8(addr_0, ioaddr + 0x28);
- wmb();
- iowrite8(0xff, ioaddr + 0x7f8);
- wait_until_busy_reset(ioaddr);
-}
-
-/**
* ccat_get_prom_id() - Read CCAT PROM ID
* @ioaddr: address of the CCAT Update function in PCI config space
*
@@ -256,136 +398,6 @@
}
/**
- * ccat_get_status() - Read CCAT Update status
- * @ioaddr: address of the CCAT Update function in PCI config space
- *
- * Return: the current status of the CCAT Update function
- */
-static u8 ccat_get_status(void __iomem * const ioaddr)
-{
- ccat_update_cmd(ioaddr, CCAT_READ_STATUS);
- return ioread8(ioaddr + 0x20);
-}
-
-/**
- * ccat_wait_status_cleared() - wait until CCAT status is cleared
- * @ioaddr: address of the CCAT Update function in PCI config space
- *
- * Blocks until bit 7 of the CCAT Update status is reset
- */
-static void ccat_wait_status_cleared(void __iomem * const ioaddr)
-{
- u8 status;
-
- do {
- status = ccat_get_status(ioaddr);
- } while (status & (1 << 7));
-}
-
-/**
- * ccat_read_flash_block() - Read a block of CCAT configuration data from flash
- * @ioaddr: address of the CCAT Update function in PCI config space
- * @addr: 24 bit address of the block to read
- * @len: number of bytes to read from this block, len <= CCAT_DATA_BLOCK_SIZE
- * @buf: output buffer in user space
- *
- * Copies one block of configuration data from the CCAT FPGA's flash to
- * the user space buffer.
- * Note that the size of the FPGA's firmware is not known exactly so it
- * is very possible that the overall buffer ends with a lot of 0xff.
- *
- * Return: the number of bytes copied
- */
-static int ccat_read_flash_block(void __iomem * const ioaddr,
- const u32 addr, const u16 len,
- char __user * const buf)
-{
- u16 i;
- const u16 clocks = 8 * len;
-
- ccat_update_cmd_addr(ioaddr, CCAT_READ_FLASH + clocks, addr);
- for (i = 0; i < len; i++) {
- put_user(ioread8(ioaddr + CCAT_DATA_IN_4 + 8 * i), buf + i);
- }
- return len;
-}
-
-/**
- * ccat_read_flash() - Read a chunk of CCAT configuration data from flash
- * @ioaddr: address of the CCAT Update function in PCI config space
- * @buf: output buffer in user space
- * @len: number of bytes to read
- * @off: offset in the configuration data
- *
- * Copies multiple blocks of configuration data from the CCAT FPGA's
- * flash to the user space buffer.
- *
- * Return: the number of bytes copied
- */
-static int ccat_read_flash(void __iomem * const ioaddr, char __user * buf,
- u32 len, loff_t * off)
-{
- const loff_t start = *off;
-
- while (len > CCAT_DATA_BLOCK_SIZE) {
- *off +=
- ccat_read_flash_block(ioaddr, *off, CCAT_DATA_BLOCK_SIZE,
- buf);
- buf += CCAT_DATA_BLOCK_SIZE;
- len -= CCAT_DATA_BLOCK_SIZE;
- }
- *off += ccat_read_flash_block(ioaddr, *off, len, buf);
- return *off - start;
-}
-
-/**
- * ccat_write_flash_block() - Write a block of CCAT configuration data to flash
- * @ioaddr: address of the CCAT Update function in PCI config space
- * @addr: 24 bit start address in the CCAT FPGA's flash
- * @len: number of bytes to write in this block, len <= CCAT_WRITE_BLOCK_SIZE
- * @buf: input buffer
- *
- * Copies one block of configuration data to the CCAT FPGA's flash
- *
- * Return: the number of bytes copied
- */
-static int ccat_write_flash_block(void __iomem * const ioaddr,
- const u32 addr, const u16 len,
- const char *const buf)
-{
- const u16 clocks = 8 * len;
- u16 i;
-
- ccat_update_cmd(ioaddr, CCAT_WRITE_ENABLE);
- for (i = 0; i < len; i++) {
- iowrite8(buf[i], ioaddr + CCAT_DATA_OUT_4 + 8 * i);
- }
- ccat_update_cmd_addr(ioaddr, CCAT_WRITE_FLASH + clocks, addr);
- ccat_wait_status_cleared(ioaddr);
- return len;
-}
-
-/**
- * ccat_write_flash() - Write a new CCAT configuration to FPGA's flash
- * @update: a CCAT Update buffer containing the new FPGA configuration
- */
-static void ccat_write_flash(const struct update_buffer *const update)
-{
- const char *buf = update->data;
- u32 off = 0;
- size_t len = update->size;
-
- while (len > CCAT_WRITE_BLOCK_SIZE) {
- ccat_write_flash_block(update->update->ioaddr, off,
- (u16) CCAT_WRITE_BLOCK_SIZE, buf);
- off += CCAT_WRITE_BLOCK_SIZE;
- buf += CCAT_WRITE_BLOCK_SIZE;
- len -= CCAT_WRITE_BLOCK_SIZE;
- }
- ccat_write_flash_block(update->update->ioaddr, off, (u16) len, buf);
-}
-
-/**
* ccat_update_init() - Initialize the CCAT Update function
*/
struct ccat_update *ccat_update_init(const struct ccat_device *const ccatdev,
@@ -437,25 +449,6 @@
}
/**
- * ccat_update_destroy() - Cleanup the CCAT Update function
- * @ref: pointer to a struct kref embedded into a struct ccat_update, which we intend to destroy
- *
- * Retrieves the parent struct ccat_update and destroys it.
- */
-static void ccat_update_destroy(struct kref *ref)
-{
- struct ccat_update *update =
- container_of(ref, struct ccat_update, refcount);
-
- cdev_del(&update->cdev);
- device_destroy(update->class, update->dev);
- class_destroy(update->class);
- unregister_chrdev_region(update->dev, 1);
- kfree(update);
- pr_debug("%s(): done\n", __FUNCTION__);
-}
-
-/**
* ccat_update_remove() - Prepare the CCAT Update function for removal
*/
void ccat_update_remove(struct ccat_update *update)