1 From cc77f36d2ea812027dc2a8a94c788c4c145f82dc Mon Sep 17 00:00:00 2001
2 From: John Crispin <blogic@openwrt.org>
3 Date: Mon, 22 Oct 2012 10:25:39 +0200
4 Subject: [PATCH 33/40] MTD: lantiq: xway: make nand actually work
6 http://lists.infradead.org/pipermail/linux-mtd/2012-September/044240.html
8 Signed-off-by: John Crispin <blogic@openwrt.org>
10 drivers/mtd/nand/xway_nand.c | 54 +++++++++++++++++++++++++++++++++++-------
11 1 file changed, 45 insertions(+), 9 deletions(-)
13 diff --git a/drivers/mtd/nand/xway_nand.c b/drivers/mtd/nand/xway_nand.c
14 index 3f81dc8..49b2e47 100644
15 --- a/drivers/mtd/nand/xway_nand.c
16 +++ b/drivers/mtd/nand/xway_nand.c
18 #define NAND_CON_CSMUX (1 << 1)
19 #define NAND_CON_NANDM 1
21 +static u32 xway_latchcmd;
23 static void xway_reset_chip(struct nand_chip *chip)
25 unsigned long nandaddr = (unsigned long) chip->IO_ADDR_W;
27 + unsigned long timeout;
29 nandaddr &= ~NAND_WRITE_ADDR;
30 nandaddr |= NAND_WRITE_CMD;
32 /* finish with a reset */
33 + timeout = jiffies + msecs_to_jiffies(200);
35 spin_lock_irqsave(&ebu_lock, flags);
37 writeb(NAND_WRITE_CMD_RESET, (void __iomem *) nandaddr);
38 - while ((ltq_ebu_r32(EBU_NAND_WAIT) & NAND_WAIT_WR_C) == 0)
41 + if ((ltq_ebu_r32(EBU_NAND_WAIT) & NAND_WAIT_WR_C) == 0)
44 + } while (!time_after_eq(jiffies, timeout));
46 spin_unlock_irqrestore(&ebu_lock, flags);
49 @@ -94,17 +104,15 @@ static void xway_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
52 if (ctrl & NAND_CTRL_CHANGE) {
53 - nandaddr &= ~(NAND_WRITE_CMD | NAND_WRITE_ADDR);
55 - nandaddr |= NAND_WRITE_CMD;
57 - nandaddr |= NAND_WRITE_ADDR;
58 - this->IO_ADDR_W = (void __iomem *) nandaddr;
59 + xway_latchcmd = NAND_WRITE_CMD;
60 + else if (ctrl & NAND_ALE)
61 + xway_latchcmd = NAND_WRITE_ADDR;
64 if (cmd != NAND_CMD_NONE) {
65 spin_lock_irqsave(&ebu_lock, flags);
66 - writeb(cmd, this->IO_ADDR_W);
67 + writeb(cmd, (void __iomem *) (nandaddr | xway_latchcmd));
68 while ((ltq_ebu_r32(EBU_NAND_WAIT) & NAND_WAIT_WR_C) == 0)
70 spin_unlock_irqrestore(&ebu_lock, flags);
71 @@ -124,12 +132,38 @@ static unsigned char xway_read_byte(struct mtd_info *mtd)
74 spin_lock_irqsave(&ebu_lock, flags);
75 - ret = ltq_r8((void __iomem *)(nandaddr + NAND_READ_DATA));
76 + ret = ltq_r8((void __iomem *)(nandaddr | NAND_READ_DATA));
77 spin_unlock_irqrestore(&ebu_lock, flags);
82 +static void xway_read_buf(struct mtd_info *mtd, u_char *buf, int len)
84 + struct nand_chip *this = mtd->priv;
85 + unsigned long nandaddr = (unsigned long) this->IO_ADDR_R;
86 + unsigned long flags;
89 + spin_lock_irqsave(&ebu_lock, flags);
90 + for (i = 0; i < len; i++)
91 + buf[i] = ltq_r8((void __iomem *)(nandaddr | NAND_READ_DATA));
92 + spin_unlock_irqrestore(&ebu_lock, flags);
95 +static void xway_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
97 + struct nand_chip *this = mtd->priv;
98 + unsigned long nandaddr = (unsigned long) this->IO_ADDR_W;
99 + unsigned long flags;
102 + spin_lock_irqsave(&ebu_lock, flags);
103 + for (i = 0; i < len; i++)
104 + ltq_w8(buf[i], (void __iomem *)nandaddr);
105 + spin_unlock_irqrestore(&ebu_lock, flags);
108 static int xway_nand_probe(struct platform_device *pdev)
110 struct nand_chip *this = platform_get_drvdata(pdev);
111 @@ -175,6 +209,8 @@ static struct platform_nand_data xway_nand_data = {
112 .dev_ready = xway_dev_ready,
113 .select_chip = xway_select_chip,
114 .read_byte = xway_read_byte,
115 + .read_buf = xway_read_buf,
116 + .write_buf = xway_write_buf,