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 --- a/drivers/mtd/nand/xway_nand.c
14 +++ b/drivers/mtd/nand/xway_nand.c
16 #define NAND_CON_CSMUX (1 << 1)
17 #define NAND_CON_NANDM 1
19 +static u32 xway_latchcmd;
21 static void xway_reset_chip(struct nand_chip *chip)
23 unsigned long nandaddr = (unsigned long) chip->IO_ADDR_W;
25 + unsigned long timeout;
27 nandaddr &= ~NAND_WRITE_ADDR;
28 nandaddr |= NAND_WRITE_CMD;
30 /* finish with a reset */
31 + timeout = jiffies + msecs_to_jiffies(200);
33 spin_lock_irqsave(&ebu_lock, flags);
35 writeb(NAND_WRITE_CMD_RESET, (void __iomem *) nandaddr);
36 - while ((ltq_ebu_r32(EBU_NAND_WAIT) & NAND_WAIT_WR_C) == 0)
39 + if ((ltq_ebu_r32(EBU_NAND_WAIT) & NAND_WAIT_WR_C) == 0)
42 + } while (!time_after_eq(jiffies, timeout));
44 spin_unlock_irqrestore(&ebu_lock, flags);
47 @@ -94,17 +104,15 @@ static void xway_cmd_ctrl(struct mtd_inf
50 if (ctrl & NAND_CTRL_CHANGE) {
51 - nandaddr &= ~(NAND_WRITE_CMD | NAND_WRITE_ADDR);
53 - nandaddr |= NAND_WRITE_CMD;
55 - nandaddr |= NAND_WRITE_ADDR;
56 - this->IO_ADDR_W = (void __iomem *) nandaddr;
57 + xway_latchcmd = NAND_WRITE_CMD;
58 + else if (ctrl & NAND_ALE)
59 + xway_latchcmd = NAND_WRITE_ADDR;
62 if (cmd != NAND_CMD_NONE) {
63 spin_lock_irqsave(&ebu_lock, flags);
64 - writeb(cmd, this->IO_ADDR_W);
65 + writeb(cmd, (void __iomem *) (nandaddr | xway_latchcmd));
66 while ((ltq_ebu_r32(EBU_NAND_WAIT) & NAND_WAIT_WR_C) == 0)
68 spin_unlock_irqrestore(&ebu_lock, flags);
69 @@ -124,12 +132,38 @@ static unsigned char xway_read_byte(stru
72 spin_lock_irqsave(&ebu_lock, flags);
73 - ret = ltq_r8((void __iomem *)(nandaddr + NAND_READ_DATA));
74 + ret = ltq_r8((void __iomem *)(nandaddr | NAND_READ_DATA));
75 spin_unlock_irqrestore(&ebu_lock, flags);
80 +static void xway_read_buf(struct mtd_info *mtd, u_char *buf, int len)
82 + struct nand_chip *this = mtd->priv;
83 + unsigned long nandaddr = (unsigned long) this->IO_ADDR_R;
84 + unsigned long flags;
87 + spin_lock_irqsave(&ebu_lock, flags);
88 + for (i = 0; i < len; i++)
89 + buf[i] = ltq_r8((void __iomem *)(nandaddr | NAND_READ_DATA));
90 + spin_unlock_irqrestore(&ebu_lock, flags);
93 +static void xway_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
95 + struct nand_chip *this = mtd->priv;
96 + unsigned long nandaddr = (unsigned long) this->IO_ADDR_W;
97 + unsigned long flags;
100 + spin_lock_irqsave(&ebu_lock, flags);
101 + for (i = 0; i < len; i++)
102 + ltq_w8(buf[i], (void __iomem *)nandaddr);
103 + spin_unlock_irqrestore(&ebu_lock, flags);
106 static int xway_nand_probe(struct platform_device *pdev)
108 struct nand_chip *this = platform_get_drvdata(pdev);
109 @@ -175,6 +209,8 @@ static struct platform_nand_data xway_na
110 .dev_ready = xway_dev_ready,
111 .select_chip = xway_select_chip,
112 .read_byte = xway_read_byte,
113 + .read_buf = xway_read_buf,
114 + .write_buf = xway_write_buf,