lantiq: add v3.9 support
[openwrt/svn-archive/archive.git] / target / linux / lantiq / patches-3.9 / 0014-MTD-lantiq-xway-make-nand-actually-work.patch
1 From 48b06753494e3abbf97ffebe02b1765edab7c689 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 14/22] MTD: lantiq: xway: make nand actually work
5
6 http://lists.infradead.org/pipermail/linux-mtd/2012-September/044240.html
7
8 Signed-off-by: John Crispin <blogic@openwrt.org>
9 ---
10 drivers/mtd/nand/xway_nand.c | 54 +++++++++++++++++++++++++++++++++++-------
11 1 file changed, 45 insertions(+), 9 deletions(-)
12
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
17 @@ -54,19 +54,29 @@
18 #define NAND_CON_CSMUX (1 << 1)
19 #define NAND_CON_NANDM 1
20
21 +static u32 xway_latchcmd;
22 +
23 static void xway_reset_chip(struct nand_chip *chip)
24 {
25 unsigned long nandaddr = (unsigned long) chip->IO_ADDR_W;
26 unsigned long flags;
27 + unsigned long timeout;
28
29 nandaddr &= ~NAND_WRITE_ADDR;
30 nandaddr |= NAND_WRITE_CMD;
31
32 /* finish with a reset */
33 + timeout = jiffies + msecs_to_jiffies(200);
34 +
35 spin_lock_irqsave(&ebu_lock, flags);
36 +
37 writeb(NAND_WRITE_CMD_RESET, (void __iomem *) nandaddr);
38 - while ((ltq_ebu_r32(EBU_NAND_WAIT) & NAND_WAIT_WR_C) == 0)
39 - ;
40 + do {
41 + if ((ltq_ebu_r32(EBU_NAND_WAIT) & NAND_WAIT_WR_C) == 0)
42 + break;
43 + cond_resched();
44 + } while (!time_after_eq(jiffies, timeout));
45 +
46 spin_unlock_irqrestore(&ebu_lock, flags);
47 }
48
49 @@ -94,17 +104,15 @@ static void xway_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
50 unsigned long flags;
51
52 if (ctrl & NAND_CTRL_CHANGE) {
53 - nandaddr &= ~(NAND_WRITE_CMD | NAND_WRITE_ADDR);
54 if (ctrl & NAND_CLE)
55 - nandaddr |= NAND_WRITE_CMD;
56 - else
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;
62 }
63
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)
69 ;
70 spin_unlock_irqrestore(&ebu_lock, flags);
71 @@ -124,12 +132,38 @@ static unsigned char xway_read_byte(struct mtd_info *mtd)
72 int ret;
73
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);
78
79 return ret;
80 }
81
82 +static void xway_read_buf(struct mtd_info *mtd, u_char *buf, int len)
83 +{
84 + struct nand_chip *this = mtd->priv;
85 + unsigned long nandaddr = (unsigned long) this->IO_ADDR_R;
86 + unsigned long flags;
87 + int i;
88 +
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);
93 +}
94 +
95 +static void xway_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
96 +{
97 + struct nand_chip *this = mtd->priv;
98 + unsigned long nandaddr = (unsigned long) this->IO_ADDR_W;
99 + unsigned long flags;
100 + int i;
101 +
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);
106 +}
107 +
108 static int xway_nand_probe(struct platform_device *pdev)
109 {
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,
117 }
118 };
119
120 --
121 1.7.10.4
122