dslinux/linux-2.6.x/drivers/mtd/devices firmware.c
amadeus
dslinux_amadeus at user.in-berlin.de
Sun Aug 6 22:22:06 CEST 2006
Update of /cvsroot/dslinux/dslinux/linux-2.6.x/drivers/mtd/devices
In directory antilope:/tmp/cvs-serv22750/linux-2.6.x/drivers/mtd/devices
Modified Files:
firmware.c
Log Message:
Fix cache line alignment bug
Index: firmware.c
===================================================================
RCS file: /cvsroot/dslinux/dslinux/linux-2.6.x/drivers/mtd/devices/firmware.c,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -d -r1.8 -r1.9
--- firmware.c 5 Aug 2006 21:41:05 -0000 1.8
+++ firmware.c 6 Aug 2006 20:22:04 -0000 1.9
@@ -31,7 +31,8 @@
static struct mtd_info *mtdinfo;
static int firmware_data_read;
static wait_queue_head_t wait_queue;
-static struct nds_firmware_block firmware_block;
+/* This buffer is aligned to the ARM9 cache lines, because of cache line invalidation */
+static struct nds_firmware_block firmware_block __attribute__ ((aligned (32)));
int firmware_read(struct mtd_info *mtd, loff_t from, size_t len,
size_t *retlen, u_char *buf)
@@ -47,8 +48,9 @@
firmware_block.from = from;
firmware_block.len = len;
firmware_block.destination = buf;
- /* writeback cached data before ARM7 gets hand on */
- dmac_clean_range((unsigned long)&firmware_block,
+ /* writeback cached data before ARM7 gets hand on. Invalidate cache so
+ we can read the new values after ARM7 has written them. */
+ dmac_flush_range((unsigned long)&firmware_block,
((unsigned long)&firmware_block)+sizeof(firmware_block));
nds_fifo_send(FIFO_FIRMWARE_CMD(FIFO_FIRMWARE_CMD_READ, 0));
@@ -56,16 +58,12 @@
if(wait_event_interruptible(wait_queue, firmware_data_read)) {
return -ERESTART;
}
- /* invalidate cache before we read data written by ARM7 */
- dmac_inv_range((unsigned long)&firmware_block,
- ((unsigned long)&firmware_block)+sizeof(firmware_block));
- dmac_inv_range((unsigned long)&firmware_block.data,
- (((unsigned long)&firmware_block.data)+firmware_block.len));
/* copy data to caller. Here better than in interrupt callback. */
memcpy(firmware_block.destination,
&firmware_block.data,
firmware_block.len);
+
*retlen = len;
return 0;
}
More information about the dslinux-commit
mailing list