diff --git a/target/linux/ar71xx/files/arch/mips/ath79/dev-nfc.c b/target/linux/ar71xx/files/arch/mips/ath79/dev-nfc.c index f330395fe..6155f70fb 100644 --- a/target/linux/ar71xx/files/arch/mips/ath79/dev-nfc.c +++ b/target/linux/ar71xx/files/arch/mips/ath79/dev-nfc.c @@ -80,6 +80,11 @@ void __init ath79_nfc_set_scan_fixup(int (*f)(struct mtd_info *mtd)) ath79_nfc_data.scan_fixup = f; } +void __init ath79_nfc_set_swap_dma(bool enable) +{ + ath79_nfc_data.swap_dma = enable; +} + void __init ath79_nfc_set_parts(struct mtd_partition *parts, int nr_parts) { ath79_nfc_data.parts = parts; diff --git a/target/linux/ar71xx/files/arch/mips/ath79/dev-nfc.h b/target/linux/ar71xx/files/arch/mips/ath79/dev-nfc.h index 1fc4b807b..46a090d9b 100644 --- a/target/linux/ar71xx/files/arch/mips/ath79/dev-nfc.h +++ b/target/linux/ar71xx/files/arch/mips/ath79/dev-nfc.h @@ -11,16 +11,20 @@ #ifndef _ATH79_DEV_NFC_H #define _ATH79_DEV_NFC_H +struct mtd_partition; + #ifdef CONFIG_ATH79_DEV_NFC void ath79_nfc_set_parts(struct mtd_partition *parts, int nr_parts); void ath79_nfc_set_select_chip(void (*f)(int chip_no)); void ath79_nfc_set_scan_fixup(int (*f)(struct mtd_info *mtd)); +void ath79_nfc_set_swap_dma(bool enable); void ath79_register_nfc(void); #else static inline void ath79_nfc_set_parts(struct mtd_partition *parts, int nr_parts) {} static inline void ath79_nfc_set_select_chip(void (*f)(int chip_no)) {} static inline void ath79_nfc_set_scan_fixup(int (*f)(struct mtd_info *mtd)) {} +static inline void ath79_nfc_set_swap_dma(bool enable) {} static inline void ath79_register_nfc(void) {} #endif diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-rb2011.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-rb2011.c index 933a45130..c7b985863 100644 --- a/target/linux/ar71xx/files/arch/mips/ath79/mach-rb2011.c +++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-rb2011.c @@ -200,6 +200,7 @@ static void __init rb2011_nand_init(void) ath79_nfc_set_parts(rb2011_nand_partitions, ARRAY_SIZE(rb2011_nand_partitions)); ath79_nfc_set_select_chip(rb2011_nand_select_chip); + ath79_nfc_set_swap_dma(true); ath79_register_nfc(); } diff --git a/target/linux/ar71xx/files/drivers/mtd/nand/ar934x_nfc.c b/target/linux/ar71xx/files/drivers/mtd/nand/ar934x_nfc.c index 7fd04ca62..7939f9218 100644 --- a/target/linux/ar71xx/files/drivers/mtd/nand/ar934x_nfc.c +++ b/target/linux/ar71xx/files/drivers/mtd/nand/ar934x_nfc.c @@ -174,6 +174,7 @@ struct ar934x_nfc { struct device *parent; void __iomem *base; void (*select_chip)(int chip_no); + bool swap_dma; int irq; wait_queue_head_t irq_waitq; @@ -190,6 +191,8 @@ struct ar934x_nfc { unsigned int buf_size; int buf_index; + bool read_id; + int erase1_page_addr; int rndout_page_addr; @@ -591,7 +594,10 @@ ar934x_nfc_read_status(struct ar934x_nfc *nfc) nfc_dbg(nfc, "read status, cmd:%08x status:%02x\n", cmd_reg, (status & 0xff)); - nfc->buf[0 ^ 3] = status; + if (nfc->swap_dma) + nfc->buf[0 ^ 3] = status; + else + nfc->buf[0] = status; } static void @@ -600,6 +606,7 @@ ar934x_nfc_cmdfunc(struct mtd_info *mtd, unsigned int command, int column, { struct ar934x_nfc *nfc = mtd_to_ar934x_nfc(mtd); + nfc->read_id = false; if (command != NAND_CMD_PAGEPROG) nfc->buf_index = 0; @@ -609,6 +616,7 @@ ar934x_nfc_cmdfunc(struct mtd_info *mtd, unsigned int command, int column, break; case NAND_CMD_READID: + nfc->read_id = true; ar934x_nfc_send_readid(nfc, command); break; @@ -717,13 +725,15 @@ static u8 ar934x_nfc_read_byte(struct mtd_info *mtd) { struct ar934x_nfc *nfc = mtd_to_ar934x_nfc(mtd); - unsigned int buf_index; u8 data; WARN_ON(nfc->buf_index >= nfc->buf_size); - buf_index = nfc->buf_index ^ 3; - data = nfc->buf[buf_index]; + if (nfc->swap_dma || nfc->read_id) + data = nfc->buf[nfc->buf_index ^ 3]; + else + data = nfc->buf[nfc->buf_index]; + nfc->buf_index++; return data; @@ -737,9 +747,16 @@ ar934x_nfc_write_buf(struct mtd_info *mtd, const u8 *buf, int len) WARN_ON(nfc->buf_index + len > nfc->buf_size); - for (i = 0; i < len; i++) { - nfc->buf[nfc->buf_index ^ 3] = buf[i]; - nfc->buf_index++; + if (nfc->swap_dma) { + for (i = 0; i < len; i++) { + nfc->buf[nfc->buf_index ^ 3] = buf[i]; + nfc->buf_index++; + } + } else { + for (i = 0; i < len; i++) { + nfc->buf[nfc->buf_index] = buf[i]; + nfc->buf_index++; + } } } @@ -754,9 +771,16 @@ ar934x_nfc_read_buf(struct mtd_info *mtd, u8 *buf, int len) buf_index = nfc->buf_index; - for (i = 0; i < len; i++) { - buf[i] = nfc->buf[buf_index ^ 3]; - buf_index++; + if (nfc->swap_dma || nfc->read_id) { + for (i = 0; i < len; i++) { + buf[i] = nfc->buf[buf_index ^ 3]; + buf_index++; + } + } else { + for (i = 0; i < len; i++) { + buf[i] = nfc->buf[buf_index]; + buf_index++; + } } nfc->buf_index = buf_index; @@ -1028,6 +1052,7 @@ ar934x_nfc_probe(struct platform_device *pdev) nfc->parent = &pdev->dev; nfc->select_chip = pdata->select_chip; + nfc->swap_dma = pdata->swap_dma; nand = &nfc->nand_chip; mtd = &nfc->mtd; diff --git a/target/linux/ar71xx/files/include/linux/platform/ar934x_nfc.h b/target/linux/ar71xx/files/include/linux/platform/ar934x_nfc.h index 3e4c6d988..2c3db156b 100644 --- a/target/linux/ar71xx/files/include/linux/platform/ar934x_nfc.h +++ b/target/linux/ar71xx/files/include/linux/platform/ar934x_nfc.h @@ -22,6 +22,7 @@ struct ar934x_nfc_platform_data { struct mtd_partition *parts; int nr_parts; + bool swap_dma; void (*hw_reset)(bool active); void (*select_chip)(int chip_no); int (*scan_fixup)(struct mtd_info *mtd); diff --git a/target/linux/ar71xx/patches-3.6/a05-ar934x_nfc-add-buffer-verification.patch b/target/linux/ar71xx/patches-3.6/a05-ar934x_nfc-add-buffer-verification.patch index 55c9da119..e83c66634 100644 --- a/target/linux/ar71xx/patches-3.6/a05-ar934x_nfc-add-buffer-verification.patch +++ b/target/linux/ar71xx/patches-3.6/a05-ar934x_nfc-add-buffer-verification.patch @@ -1,6 +1,6 @@ --- a/drivers/mtd/nand/ar934x_nfc.c +++ b/drivers/mtd/nand/ar934x_nfc.c -@@ -762,6 +762,18 @@ ar934x_nfc_read_buf(struct mtd_info *mtd +@@ -786,6 +786,18 @@ ar934x_nfc_read_buf(struct mtd_info *mtd nfc->buf_index = buf_index; } @@ -19,7 +19,7 @@ static void ar934x_nfc_hw_init(struct ar934x_nfc *nfc) { -@@ -1047,6 +1059,7 @@ ar934x_nfc_probe(struct platform_device +@@ -1072,6 +1084,7 @@ ar934x_nfc_probe(struct platform_device nand->read_byte = ar934x_nfc_read_byte; nand->write_buf = ar934x_nfc_write_buf; nand->read_buf = ar934x_nfc_read_buf;