Skip to content

Commit

Permalink
mtd: nand: sunxi: add reset line support
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Icenowy Zheng authored and Boris Brezillon committed Jul 11, 2016
1 parent 7f65727 commit ab9d6a7
Showing 1 changed file with 23 additions and 2 deletions.
25 changes: 23 additions & 2 deletions drivers/mtd/nand/sunxi_nand.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
#include <linux/gpio.h>
#include <linux/interrupt.h>
#include <linux/iopoll.h>
#include <linux/reset.h>

#define NFC_REG_CTL 0x0000
#define NFC_REG_ST 0x0004
Expand Down Expand Up @@ -270,6 +271,7 @@ struct sunxi_nfc {
void __iomem *regs;
struct clk *ahb_clk;
struct clk *mod_clk;
struct reset_control *reset;
unsigned long assigned_cs;
unsigned long clk_rate;
struct list_head chips;
Expand Down Expand Up @@ -2209,15 +2211,27 @@ static int sunxi_nfc_probe(struct platform_device *pdev)
if (ret)
goto out_ahb_clk_unprepare;

nfc->reset = devm_reset_control_get_optional(dev, "ahb");
if (!IS_ERR(nfc->reset)) {
ret = reset_control_deassert(nfc->reset);
if (ret) {
dev_err(dev, "reset err %d\n", ret);
goto out_mod_clk_unprepare;
}
} else if (PTR_ERR(nfc->reset) != -ENOENT) {
ret = PTR_ERR(nfc->reset);
goto out_mod_clk_unprepare;
}

ret = sunxi_nfc_rst(nfc);
if (ret)
goto out_mod_clk_unprepare;
goto out_ahb_reset_reassert;

writel(0, nfc->regs + NFC_REG_INT);
ret = devm_request_irq(dev, irq, sunxi_nfc_interrupt,
0, "sunxi-nand", nfc);
if (ret)
goto out_mod_clk_unprepare;
goto out_ahb_reset_reassert;

nfc->dmac = dma_request_slave_channel(dev, "rxtx");
if (nfc->dmac) {
Expand Down Expand Up @@ -2247,6 +2261,9 @@ static int sunxi_nfc_probe(struct platform_device *pdev)
out_release_dmac:
if (nfc->dmac)
dma_release_channel(nfc->dmac);
out_ahb_reset_reassert:
if (!IS_ERR(nfc->reset))
reset_control_assert(nfc->reset);
out_mod_clk_unprepare:
clk_disable_unprepare(nfc->mod_clk);
out_ahb_clk_unprepare:
Expand All @@ -2260,6 +2277,10 @@ static int sunxi_nfc_remove(struct platform_device *pdev)
struct sunxi_nfc *nfc = platform_get_drvdata(pdev);

sunxi_nand_chips_cleanup(nfc);

if (!IS_ERR(nfc->reset))
reset_control_assert(nfc->reset);

if (nfc->dmac)
dma_release_channel(nfc->dmac);
clk_disable_unprepare(nfc->mod_clk);
Expand Down

0 comments on commit ab9d6a7

Please sign in to comment.