89044d57709f48cb62523cf4c15b76869a6dde01
[15.05/openwrt.git] / target / linux / lantiq / patches-3.8 / 0033-MTD-lantiq-xway-make-nand-actually-work.patch
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
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