# HG changeset patch # User Patrick Bruenn # Date 1401980934 -7200 # Node ID a4fdad543554982007f99a30510f9cd623fad341 # Parent 144e11d93e995f3f3794b5b486fd75fac8533c0f reorder functions in update.c to omit forward declarations diff -r 144e11d93e99 -r a4fdad543554 devices/ccat/update.c --- 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)