aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd
diff options
context:
space:
mode:
authorIcenowy Zheng <icenowy@aosc.xyz>2016-06-20 00:48:38 -0400
committerBoris Brezillon <boris.brezillon@free-electrons.com>2016-07-11 02:40:18 -0400
commitab9d6a783544bbf8834277f8409048ddc35712ed (patch)
tree524a1bb4393e9b6ae3cbaea5e0a0e4d882fb2154 /drivers/mtd
parent7f657279a6de28573f13420840b2de3e04131d04 (diff)
mtd: nand: sunxi: add reset line support
The NAND controller on some sun8i chips needs its reset line to be deasserted before they can enter working state. Signed-off-by: Icenowy Zheng <icenowy@aosc.xyz> Acked-by: Maxime Ripard <maxime.ripard@free-electrons.com> Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
Diffstat (limited to 'drivers/mtd')
-rw-r--r--drivers/mtd/nand/sunxi_nand.c25
1 files changed, 23 insertions, 2 deletions
diff --git a/drivers/mtd/nand/sunxi_nand.c b/drivers/mtd/nand/sunxi_nand.c
index f582fe41d61d..d2b7457d447f 100644
--- a/drivers/mtd/nand/sunxi_nand.c
+++ b/drivers/mtd/nand/sunxi_nand.c
@@ -39,6 +39,7 @@
39#include <linux/gpio.h> 39#include <linux/gpio.h>
40#include <linux/interrupt.h> 40#include <linux/interrupt.h>
41#include <linux/iopoll.h> 41#include <linux/iopoll.h>
42#include <linux/reset.h>
42 43
43#define NFC_REG_CTL 0x0000 44#define NFC_REG_CTL 0x0000
44#define NFC_REG_ST 0x0004 45#define NFC_REG_ST 0x0004
@@ -270,6 +271,7 @@ struct sunxi_nfc {
270 void __iomem *regs; 271 void __iomem *regs;
271 struct clk *ahb_clk; 272 struct clk *ahb_clk;
272 struct clk *mod_clk; 273 struct clk *mod_clk;
274 struct reset_control *reset;
273 unsigned long assigned_cs; 275 unsigned long assigned_cs;
274 unsigned long clk_rate; 276 unsigned long clk_rate;
275 struct list_head chips; 277 struct list_head chips;
@@ -2209,15 +2211,27 @@ static int sunxi_nfc_probe(struct platform_device *pdev)
2209 if (ret) 2211 if (ret)
2210 goto out_ahb_clk_unprepare; 2212 goto out_ahb_clk_unprepare;
2211 2213
2214 nfc->reset = devm_reset_control_get_optional(dev, "ahb");
2215 if (!IS_ERR(nfc->reset)) {
2216 ret = reset_control_deassert(nfc->reset);
2217 if (ret) {
2218 dev_err(dev, "reset err %d\n", ret);
2219 goto out_mod_clk_unprepare;
2220 }
2221 } else if (PTR_ERR(nfc->reset) != -ENOENT) {
2222 ret = PTR_ERR(nfc->reset);
2223 goto out_mod_clk_unprepare;
2224 }
2225
2212 ret = sunxi_nfc_rst(nfc); 2226 ret = sunxi_nfc_rst(nfc);
2213 if (ret) 2227 if (ret)
2214 goto out_mod_clk_unprepare; 2228 goto out_ahb_reset_reassert;
2215 2229
2216 writel(0, nfc->regs + NFC_REG_INT); 2230 writel(0, nfc->regs + NFC_REG_INT);
2217 ret = devm_request_irq(dev, irq, sunxi_nfc_interrupt, 2231 ret = devm_request_irq(dev, irq, sunxi_nfc_interrupt,
2218 0, "sunxi-nand", nfc); 2232 0, "sunxi-nand", nfc);
2219 if (ret) 2233 if (ret)
2220 goto out_mod_clk_unprepare; 2234 goto out_ahb_reset_reassert;
2221 2235
2222 nfc->dmac = dma_request_slave_channel(dev, "rxtx"); 2236 nfc->dmac = dma_request_slave_channel(dev, "rxtx");
2223 if (nfc->dmac) { 2237 if (nfc->dmac) {
@@ -2247,6 +2261,9 @@ static int sunxi_nfc_probe(struct platform_device *pdev)
2247out_release_dmac: 2261out_release_dmac:
2248 if (nfc->dmac) 2262 if (nfc->dmac)
2249 dma_release_channel(nfc->dmac); 2263 dma_release_channel(nfc->dmac);
2264out_ahb_reset_reassert:
2265 if (!IS_ERR(nfc->reset))
2266 reset_control_assert(nfc->reset);
2250out_mod_clk_unprepare: 2267out_mod_clk_unprepare:
2251 clk_disable_unprepare(nfc->mod_clk); 2268 clk_disable_unprepare(nfc->mod_clk);
2252out_ahb_clk_unprepare: 2269out_ahb_clk_unprepare:
@@ -2260,6 +2277,10 @@ static int sunxi_nfc_remove(struct platform_device *pdev)
2260 struct sunxi_nfc *nfc = platform_get_drvdata(pdev); 2277 struct sunxi_nfc *nfc = platform_get_drvdata(pdev);
2261 2278
2262 sunxi_nand_chips_cleanup(nfc); 2279 sunxi_nand_chips_cleanup(nfc);
2280
2281 if (!IS_ERR(nfc->reset))
2282 reset_control_assert(nfc->reset);
2283
2263 if (nfc->dmac) 2284 if (nfc->dmac)
2264 dma_release_channel(nfc->dmac); 2285 dma_release_channel(nfc->dmac);
2265 clk_disable_unprepare(nfc->mod_clk); 2286 clk_disable_unprepare(nfc->mod_clk);