All of lore.kernel.org
 help / color / mirror / Atom feed
From: Doug Anderson <dianders@chromium.org>
To: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
Cc: Rob Herring <robh+dt@kernel.org>,
	Bjorn Andersson <bjorn.andersson@linaro.org>,
	Andy Gross <agross@kernel.org>,
	dhavalp@codeaurora.org, mturney@codeaurora.org,
	Rajendra Nayak <rnayak@codeaurora.org>,
	Ravi Kumar Bokka <rbokka@codeaurora.org>,
	linux-arm-msm <linux-arm-msm@vger.kernel.org>,
	Sai Prakash Ranjan <saiprakash.ranjan@codeaurora.org>,
	sparate@codeaurora.org, mkurumel@codeaurora.org,
	LKML <linux-kernel@vger.kernel.org>
Subject: Re: [PATCH v3 3/4] nvmem: qfprom: Add fuse blowing support
Date: Wed, 17 Jun 2020 10:13:53 -0700	[thread overview]
Message-ID: <CAD=FV=X9xZH9Sj6hE-T=hz64XeaEVOHjP40cj-koXpE5KCHDSQ@mail.gmail.com> (raw)
In-Reply-To: <ca00ca5c-eb8b-5662-d73a-e222735347eb@linaro.org>

Hi,

On Wed, Jun 17, 2020 at 8:18 AM Srinivas Kandagatla
<srinivas.kandagatla@linaro.org> wrote:
>
> Thanks Doug,
> Overall the patch is looking good, I have few minor comments below!
>
> On 17/06/2020 15:51, Douglas Anderson wrote:
> > From: Ravi Kumar Bokka <rbokka@codeaurora.org>
> >
> > This patch adds support for blowing fuses to the qfprom driver if the
> > required properties are defined in the device tree.
> >
> > Signed-off-by: Ravi Kumar Bokka <rbokka@codeaurora.org>
> > Signed-off-by: Douglas Anderson <dianders@chromium.org>
> > ---
> > Please double-check that I got the major/minor version logic right
> > here.  I don't have documentation for this, but Srinivas mentioned
> > that it was at address 0x6000 and I happened to find an "8" and a "7"
> > on sc7180 so I assumed that was the major and minor version.
> >
> > Changes in v3:
> > - Don't provide "reset" value for things; just save/restore.
> > - Use the major/minor version read from 0x6000.
> > - Reading should still read "corrected", not "raw".
> > - Added a sysfs knob to allow you to read "raw" instead of "corrected"
> > - Simplified the SoC data structure.
> > - No need for quite so many levels of abstraction for clocks/regulator.
> > - Don't set regulator voltage.  Rely on device tree to make sure it's right.
> > - Properly undo things in the case of failure.
> > - Don't just keep enabling the regulator over and over again.
> > - Enable / disable the clock each time
> > - Polling every 100 us but timing out in 10 us didn't make sense; swap.
> > - No reason for 100 us to be SoC specific.
> > - No need for reg-names.
> > - We shouldn't be creating two separate nvmem devices.
> >
> >   drivers/nvmem/qfprom.c | 314 +++++++++++++++++++++++++++++++++++++++--
> >   1 file changed, 303 insertions(+), 11 deletions(-)
> >
> > diff --git a/drivers/nvmem/qfprom.c b/drivers/nvmem/qfprom.c
> > index 8a91717600be..486202860f84 100644
> > --- a/drivers/nvmem/qfprom.c
> > +++ b/drivers/nvmem/qfprom.c
> > @@ -3,57 +3,349 @@
> >    * Copyright (C) 2015 Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
> >    */
> >
> > +#include <linux/clk.h>
> >   #include <linux/device.h>
> > +#include <linux/io.h>
> > +#include <linux/iopoll.h>
> > +#include <linux/kernel.h>
> >   #include <linux/module.h>
> >   #include <linux/mod_devicetable.h>
> > -#include <linux/io.h>
> >   #include <linux/nvmem-provider.h>
> >   #include <linux/platform_device.h>
> > +#include <linux/regulator/consumer.h>
> > +
> > +/* Blow timer clock frequency in Mhz */
> > +#define QFPROM_BLOW_TIMER_OFFSET 0x03c
> > +
> > +/* Amount of time required to hold charge to blow fuse in micro-seconds */
> > +#define QFPROM_FUSE_BLOW_POLL_US     10
> > +#define QFPROM_FUSE_BLOW_TIMEOUT_US  100
> > +
> > +#define QFPROM_BLOW_STATUS_OFFSET    0x048
> > +#define QFPROM_BLOW_STATUS_BUSY              0x1
> > +#define QFPROM_BLOW_STATUS_READY     0x0
> > +
> > +#define QFPROM_ACCEL_OFFSET          0x044
> > +
> > +#define QFPROM_VERSION_OFFSET                0x0
> > +#define QFPROM_MAJOR_VERSION_SHIFT   28
> > +#define QFPROM_MAJOR_VERSION_MASK    0xf
> > +#define QFPROM_MINOR_VERSION_SHIFT   16
> > +#define QFPROM_MINOR_VERSION_MASK    0xf
>
> Using GENMASK here makes it much readable!
>
> ...
>
> >
> >   static int qfprom_probe(struct platform_device *pdev)
> >   {
> > +     struct nvmem_config econfig = {
> > +             .name = "qfprom",
> > +             .stride = 1,
> > +             .word_size = 1,
> > +             .reg_read = qfprom_reg_read,
> > +     };
> >       struct device *dev = &pdev->dev;
> >       struct resource *res;
> >       struct nvmem_device *nvmem;
> >       struct qfprom_priv *priv;
> > +     int ret;
> >
> >       priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
> >       if (!priv)
> >               return -ENOMEM;
> >
> > +     /* The corrected section is always provided */
> >       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> > -     priv->base = devm_ioremap_resource(dev, res);
> > -     if (IS_ERR(priv->base))
> > -             return PTR_ERR(priv->base);
> > +     priv->qfpcorrected = devm_ioremap_resource(dev, res);
> > +     if (IS_ERR(priv->qfpcorrected))
> > +             return PTR_ERR(priv->qfpcorrected);
> >
> >       econfig.size = resource_size(res);
> >       econfig.dev = dev;
> >       econfig.priv = priv;
> >
> > +     priv->dev = dev;
> > +
> > +     /*
> > +      * If more than one region is provided then the OS has the ability
> > +      * to write.
> > +      */
> > +     res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
> > +     if (res) {
> > +             u32 version;
> > +             int major_version, minor_version;
> > +
> > +             priv->qfpraw = devm_ioremap_resource(dev, res);
> > +             if (IS_ERR(priv->qfpraw))
> > +                     return PTR_ERR(priv->qfpraw);
> > +             res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
> > +             priv->qfpconf = devm_ioremap_resource(dev, res);
> > +             if (IS_ERR(priv->qfpconf))
> > +                     return PTR_ERR(priv->qfpconf);
> > +             res = platform_get_resource(pdev, IORESOURCE_MEM, 3);
> > +             priv->qfpsecurity = devm_ioremap_resource(dev, res);
> > +             if (IS_ERR(priv->qfpsecurity))
> > +                     return PTR_ERR(priv->qfpsecurity);
> > +
> > +             version = readl(priv->qfpsecurity + QFPROM_VERSION_OFFSET);
> > +             major_version = (version >> QFPROM_MAJOR_VERSION_SHIFT) &
> > +                             QFPROM_MAJOR_VERSION_MASK;
> > +             minor_version = (version >> QFPROM_MINOR_VERSION_SHIFT) &
> > +                             QFPROM_MINOR_VERSION_MASK;
> > +
> > +             if (major_version == 7 && minor_version == 8)
> > +                     priv->soc_data = &qfprom_7_8_data;
> > +
> > +             /* Only enable writing if we have SoC data. */
> > +             if (priv->soc_data)
> > +                     econfig.reg_write = qfprom_reg_write;
> > +     }
> > +
>
> <----------snip
> > +     priv->vcc = devm_regulator_get(&pdev->dev, "vcc");
> > +     if (IS_ERR(priv->vcc))
> > +             return PTR_ERR(priv->vcc);
> > +
> > +     priv->secclk = devm_clk_get_optional(dev, "sec");
> > +     if (IS_ERR(priv->secclk)) {
> > +             ret = PTR_ERR(priv->secclk);
> > +             if (ret != -EPROBE_DEFER)
> > +                     dev_err(dev, "sec error getting : %d\n", ret);
> > +             return ret;
> > +     }
> > +
> ----------->
> should you move both clk and regulator into the previous if (res) {}
> block? As I don't see them marked as optional for write cases.

Sure, I'll move them on the next version.  I will note that the
current version actually works fine but I guess since there currently
isn't actually a user of the clock/regulator in the non-write case
then we don't need to make the calls...  Why does it work fine the way
it is too?

* regulator_get() will automatically create a "dummy" regulator if one
isn't specified in the device tree, so there's no harm in the call.
If you actually need to know if a regulator is there you need to call
regulator_get_optional()

* clk_get_optional() will return NULL if a clock isn't specified in
the device tree and clock framework is fine with you passing NULL for
enable/disable/prepare/unprepare.  If you actually need to know if a
clock is there you need to call clk_get().

Amazing but true that the "optional" variants of the regulator and
clock code are effectively opposites of each other.  :-P


-Doug

  reply	other threads:[~2020-06-17 17:14 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-06-17 14:51 [PATCH v3 0/4] nvmem: qfprom: Patches for fuse blowing on Qualcomm SoCs Douglas Anderson
2020-06-17 14:51 ` [PATCH v3 1/4] dt-bindings: nvmem: qfprom: Convert to yaml Douglas Anderson
2020-06-17 15:18   ` Srinivas Kandagatla
2020-06-17 16:26     ` Ravi Kumar Bokka (Temp)
2020-06-17 17:28       ` Doug Anderson
2020-06-18 18:43   ` Rob Herring
2020-06-17 14:51 ` [PATCH v3 2/4] dt-bindings: nvmem: Add properties needed for blowing fuses Douglas Anderson
2020-06-17 15:19   ` Srinivas Kandagatla
2020-06-17 17:22     ` Doug Anderson
2020-06-18 10:10       ` Srinivas Kandagatla
2020-06-18 13:48         ` Doug Anderson
2020-06-18 14:01           ` Srinivas Kandagatla
2020-06-18 15:32             ` Doug Anderson
     [not found]               ` <159249930746.62212.6196028697481604160@swboyd.mtv.corp.google.com>
2020-06-18 17:25                 ` Doug Anderson
2020-06-19  9:22                   ` Srinivas Kandagatla
2020-06-17 14:51 ` [PATCH v3 3/4] nvmem: qfprom: Add fuse blowing support Douglas Anderson
2020-06-17 15:03   ` Jeffrey Hugo
2020-06-17 15:18   ` Srinivas Kandagatla
2020-06-17 17:13     ` Doug Anderson [this message]
2020-06-23 13:35   ` Pavel Machek
2020-06-23 14:48     ` Doug Anderson
2020-06-17 14:51 ` [PATCH v3 4/4] arm64: dts: qcom: sc7180: Add properties to qfprom for fuse blowing Douglas Anderson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CAD=FV=X9xZH9Sj6hE-T=hz64XeaEVOHjP40cj-koXpE5KCHDSQ@mail.gmail.com' \
    --to=dianders@chromium.org \
    --cc=agross@kernel.org \
    --cc=bjorn.andersson@linaro.org \
    --cc=dhavalp@codeaurora.org \
    --cc=linux-arm-msm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mkurumel@codeaurora.org \
    --cc=mturney@codeaurora.org \
    --cc=rbokka@codeaurora.org \
    --cc=rnayak@codeaurora.org \
    --cc=robh+dt@kernel.org \
    --cc=saiprakash.ranjan@codeaurora.org \
    --cc=sparate@codeaurora.org \
    --cc=srinivas.kandagatla@linaro.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.