diff options
author | Icenowy Zheng <icenowy@aosc.xyz> | 2016-06-20 00:48:38 -0400 |
---|---|---|
committer | Boris Brezillon <boris.brezillon@free-electrons.com> | 2016-07-11 02:40:18 -0400 |
commit | ab9d6a783544bbf8834277f8409048ddc35712ed (patch) | |
tree | 524a1bb4393e9b6ae3cbaea5e0a0e4d882fb2154 /drivers/mtd | |
parent | 7f657279a6de28573f13420840b2de3e04131d04 (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.c | 25 |
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) | |||
2247 | out_release_dmac: | 2261 | out_release_dmac: |
2248 | if (nfc->dmac) | 2262 | if (nfc->dmac) |
2249 | dma_release_channel(nfc->dmac); | 2263 | dma_release_channel(nfc->dmac); |
2264 | out_ahb_reset_reassert: | ||
2265 | if (!IS_ERR(nfc->reset)) | ||
2266 | reset_control_assert(nfc->reset); | ||
2250 | out_mod_clk_unprepare: | 2267 | out_mod_clk_unprepare: |
2251 | clk_disable_unprepare(nfc->mod_clk); | 2268 | clk_disable_unprepare(nfc->mod_clk); |
2252 | out_ahb_clk_unprepare: | 2269 | out_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); |