Re: [PATCH 2/2] mtd: nand: sunxi: add reset line support

From: Boris Brezillon
Date: Sun Jun 19 2016 - 09:19:45 EST


On Sun, 19 Jun 2016 21:11:00 +0800
icenowy@xxxxxxxx wrote:

> Then I will soon make the v2 patch set, with the error detection part fixed.
>
> But why does sunxi-mmc check only EPROBE_DEFER?

I guess someone had a probe-dependency problem and fixed this case but
ignored all the possible errors. But there may be other reasons for
devm_reset_control_get_optional() to fail. The only one that is really
reflecting that the reset line is not defined in the DT is -ENOENT.

>
> 19.06.2016, 20:53, "Boris Brezillon" <boris.brezillon@xxxxxxxxxxxxxxxxxx>:
> > On Sun, 19 Jun 2016 20:41:09 +0800
> > icenowy@xxxxxxxx wrote:
> >
> >> ÂTo be honest, I copied them from sunxi-mmc.c.
> >>
> >> ÂWhat function should be chosen better?
> >
> > You did the right thing (except for the error detection part). My
> > question was addressed to Philipp (the reset subsystem maintainer).
> >
> >> Â19.06.2016, 20:06, "Boris Brezillon" <boris.brezillon@xxxxxxxxxxxxxxxxxx>:
> >> Â> +Philipp
> >> Â>
> >> Â> On Sun, 19 Jun 2016 19:37:39 +0800
> >> Â> Icenowy Zheng <icenowy@xxxxxxxx> wrote:
> >> Â>
> >> Â>> ÂThe NAND controller on some sun8i chips needs its reset line to be deasserted
> >> Â>> Âbefore they can enter working state. This commit added the reset line process
> >> Â>> Âto the driver.
> >> Â>>
> >> Â>> ÂSigned-off-by: Icenowy Zheng <icenowy@xxxxxxxx>
> >> Â>> Â---
> >> Â>> ÂÂdrivers/mtd/nand/sunxi_nand.c | 14 ++++++++++++++
> >> Â>> ÂÂ1 file changed, 14 insertions(+)
> >> Â>>
> >> Â>> Âdiff --git a/drivers/mtd/nand/sunxi_nand.c b/drivers/mtd/nand/sunxi_nand.c
> >> Â>> Âindex a83a690..1502748 100644
> >> Â>> Â--- a/drivers/mtd/nand/sunxi_nand.c
> >> Â>> Â+++ b/drivers/mtd/nand/sunxi_nand.c
> >> Â>> Â@@ -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
> >> Â>> Â@@ -269,6 +270,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;
> >> Â>> Â@@ -1871,6 +1873,18 @@ 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 (PTR_ERR(nfc->reset) == -EPROBE_DEFER)
> >> Â>> Â+ return PTR_ERR(nfc->reset);
> >> Â>
> >> Â> Actually you should test for != -ENOENT, because all error codes except
> >> Â> this one should stop the ->probe().
> >> Â>
> >> Â> BTW, this devm_reset_control_get_optional() is really weird. While most
> >> Â> _optional() methods return NULL when the element is not defined in the
> >> Â> DT, this one returns -ENOTENT, which makes it impossible to
> >> Â> differentiate a real error from a undefined reset line (which is a
> >> Â> valid case for _optional()).
> >> Â>
> >> Â> Philipp, is there a good reason for doing that?
> >> Â>
> >> Â>> Â+
> >> Â>> Â+ 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;
> >> Â>> Â+ }
> >> Â>> Â+ }
> >> Â>> Â+