kernel: update linux 3.9 to 3.9.8
[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 --- a/drivers/mtd/nand/xway_nand.c
14 +++ b/drivers/mtd/nand/xway_nand.c
15 @@ -54,19 +54,29 @@
16 #define NAND_CON_CSMUX (1 << 1)
17 #define NAND_CON_NANDM 1
18
19 +static u32 xway_latchcmd;
20 +
21 static void xway_reset_chip(struct nand_chip *chip)
22 {
23 unsigned long nandaddr = (unsigned long) chip->IO_ADDR_W;
24 unsigned long flags;
25 + unsigned long timeout;
26
27 nandaddr &= ~NAND_WRITE_ADDR;
28 nandaddr |= NAND_WRITE_CMD;
29
30 /* finish with a reset */
31 + timeout = jiffies + msecs_to_jiffies(200);
32 +
33 spin_lock_irqsave(&ebu_lock, flags);
34 +
35 writeb(NAND_WRITE_CMD_RESET, (void __iomem *) nandaddr);
36 - while ((ltq_ebu_r32(EBU_NAND_WAIT) & NAND_WAIT_WR_C) == 0)
37 - ;
38 + do {
39 + if ((ltq_ebu_r32(EBU_NAND_WAIT) & NAND_WAIT_WR_C) == 0)
40 + break;
41 + cond_resched();
42 + } while (!time_after_eq(jiffies, timeout));
43 +
44 spin_unlock_irqrestore(&ebu_lock, flags);
45 }
46
47 @@ -94,17 +104,15 @@ static void xway_cmd_ctrl(struct mtd_inf
48 unsigned long flags;
49
50 if (ctrl & NAND_CTRL_CHANGE) {
51 - nandaddr &= ~(NAND_WRITE_CMD | NAND_WRITE_ADDR);
52 if (ctrl & NAND_CLE)
53 - nandaddr |= NAND_WRITE_CMD;
54 - else
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;
60 }
61
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)
67 ;
68 spin_unlock_irqrestore(&ebu_lock, flags);
69 @@ -124,12 +132,38 @@ static unsigned char xway_read_byte(stru
70 int ret;
71
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);
76
77 return ret;
78 }
79
80 +static void xway_read_buf(struct mtd_info *mtd, u_char *buf, int len)
81 +{
82 + struct nand_chip *this = mtd->priv;
83 + unsigned long nandaddr = (unsigned long) this->IO_ADDR_R;
84 + unsigned long flags;
85 + int i;
86 +
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);
91 +}
92 +
93 +static void xway_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
94 +{
95 + struct nand_chip *this = mtd->priv;
96 + unsigned long nandaddr = (unsigned long) this->IO_ADDR_W;
97 + unsigned long flags;
98 + int i;
99 +
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);
104 +}
105 +
106 static int xway_nand_probe(struct platform_device *pdev)
107 {
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,
115 }
116 };
117