From: Lee Jones <lee@kernel.org>
To: Samuel Kayode <samuel.kayode@savoirfairelinux.com>
Cc: Rob Herring <robh@kernel.org>,
Krzysztof Kozlowski <krzk+dt@kernel.org>,
Conor Dooley <conor+dt@kernel.org>,
Liam Girdwood <lgirdwood@gmail.com>,
Mark Brown <broonie@kernel.org>,
Dmitry Torokhov <dmitry.torokhov@gmail.com>,
Sebastian Reichel <sre@kernel.org>, Frank Li <Frank.li@nxp.com>,
imx@lists.linux.dev, devicetree@vger.kernel.org,
linux-kernel@vger.kernel.org, linux-input@vger.kernel.org,
linux-pm@vger.kernel.org, Abel Vesa <abelvesa@kernel.org>,
Abel Vesa <abelvesa@linux.com>, Robin Gong <b38343@freescale.com>,
Robin Gong <yibin.gong@nxp.com>,
Enric Balletbo i Serra <eballetbo@gmail.com>
Subject: Re: [PATCH v7 2/6] mfd: pf1550: add core mfd driver
Date: Tue, 24 Jun 2025 17:02:35 +0100 [thread overview]
Message-ID: <20250624160235.GM795775@google.com> (raw)
In-Reply-To: <aFWrxtArHjb5nc0M@fedora>
On Fri, 20 Jun 2025, Samuel Kayode wrote:
> Hi Lee,
>
> Thanks a lot for the review.
>
> On Thu, Jun 19, 2025 at 02:03:37PM +0100, Lee Jones wrote:
> > > +static int pf1550_read_otp(const struct pf1550_dev *pf1550, unsigned int index,
> >
> > What does OTP mean?
> >
> It's a One-Time Programmable memory with configuration for the pf1550. I will
> expand on this in the commit description of the next version.
Place it in a comment please.
> > Why do you have to write to 4 registers first?
> >
> The pf1550 was designed such that the registers of the accompanying OTP is
> accessed indirectly. Valid keys have to be written to specific pf1550
> registers. After writing the keys, the address of the OTP register to be read
> is then written to PF1550_TEST_REG_FMRADDR and its corresponding value read from
> PF1550_TEST_REG_FMRDATA.
In a comment please. If I wondered, so with others.
> > This should all be made clear in some way or another.
> >
> I'll be adding comments on this in the next version.
Great!
> > > + unsigned int *val)
> > > +{
> > > + int ret = 0;
> > > +
> > > + ret = regmap_write(pf1550->regmap, PF1550_PMIC_REG_KEY, 0x15);
> >
> > No magic numbers. These should all be defined.
> Will do.
> >
> > > + if (ret)
> > > + goto read_err;
> > > + ret = regmap_write(pf1550->regmap, PF1550_CHARG_REG_CHGR_KEY2, 0x50);
> > > + if (ret)
> > > + goto read_err;
> > > + ret = regmap_write(pf1550->regmap, PF1550_TEST_REG_KEY3, 0xab);
> > > + if (ret)
> > > + goto read_err;
> > > + ret = regmap_write(pf1550->regmap, PF1550_TEST_REG_FMRADDR, index);
> > > + if (ret)
> > > + goto read_err;
> > > + ret = regmap_read(pf1550->regmap, PF1550_TEST_REG_FMRDATA, val);
> > > + if (ret)
> > > + goto read_err;
> > > +
> > > + return 0;
> > > +
> > > +read_err:
> > > + dev_err_probe(pf1550->dev, ret, "read otp reg %x found!\n", index);
> ...
> > > +static int pf1550_add_child_device(struct pf1550_dev *pmic,
> > > + const struct mfd_cell *cell,
> > > + struct regmap_irq_chip_data *pdata,
> >
> > This is not pdata.
> >
> > > + int pirq,
> > > + const struct regmap_irq_chip *chip,
> > > + struct regmap_irq_chip_data **data)
> > > +{
> > > + struct device *dev = pmic->dev;
> > > + struct irq_domain *domain;
> > > + int irq, ret;
> > > +
> > > + irq = regmap_irq_get_virq(pdata, pirq);
> > > + if (irq < 0)
> > > + return dev_err_probe(dev, irq,
> > > + "Failed to get parent vIRQ(%d) for chip %s\n",
> > > + pirq, chip->name);
> > > +
> > > + ret = devm_regmap_add_irq_chip(dev, pmic->regmap, irq,
> > > + IRQF_ONESHOT | IRQF_SHARED |
> > > + IRQF_TRIGGER_FALLING, 0, chip, data);
> > > + if (ret)
> > > + return dev_err_probe(dev, ret,
> > > + "Failed to add %s IRQ chip\n",
> > > + chip->name);
> > > +
> > > + domain = regmap_irq_get_domain(*data);
> > > +
> > > + return devm_mfd_add_devices(dev, PLATFORM_DEVID_NONE, cell, 1,
> > > + NULL, 0, domain);
> >
> > Why can't all 3 devices be registered in one call?
> >
> The 3 devices use different regmap_irq_chip s. I have to register them
> separately cause they have different irq domains but perhaps there is a better
> way to handle this?
That's okay, just do 3 calls.
Must neater than what we have here.
> > > +}
> >
> > To be honest, the premise around this function is a bit of a mess.
> >
> > Please move all of this into .probe().
> Will do.
> >
> > > +static int pf1550_i2c_probe(struct i2c_client *i2c)
> > > +{
> > > + const struct mfd_cell *regulator = &pf1550_regulator_cell;
> > > + const struct mfd_cell *charger = &pf1550_charger_cell;
> > > + const struct mfd_cell *onkey = &pf1550_onkey_cell;
> > > + unsigned int reg_data = 0, otp_data = 0;
> > > + struct pf1550_dev *pf1550;
> > > + int ret = 0;
> > > +
> > > + pf1550 = devm_kzalloc(&i2c->dev, sizeof(*pf1550), GFP_KERNEL);
> > > + if (!pf1550)
> > > + return -ENOMEM;
> > > +
> > > + i2c_set_clientdata(i2c, pf1550);
> > > + pf1550->dev = &i2c->dev;
> > > + pf1550->i2c = i2c;
> >
> > What are you storing i2c for?
> >
> It doesn't need to be stored.
> > Either store dev and irq OR i2c. You don't need all three.
> >
> Will do.
> > > + ret = regmap_read(pf1550->regmap, PF1550_PMIC_REG_DEVICE_ID, ®_data);
> > > + if (ret < 0 || reg_data != PF1550_DEVICE_ID)
> > > + return dev_err_probe(pf1550->dev, ret ?: -EINVAL,
> > > + "device not found!\n");
> >
> > Are you sure? What if the wrong device was found?
> >
> I can change the error log here to "Invalid device ID: ..."?
Right. Invalid or unsupported, etc.
> >
> ...
> > > + /* add top level interrupts */
> > > + ret = devm_regmap_add_irq_chip(pf1550->dev, pf1550->regmap, pf1550->irq,
> > > + IRQF_ONESHOT | IRQF_SHARED |
> > > + IRQF_TRIGGER_FALLING,
> > > + 0, &pf1550_irq_chip,
> > > + &pf1550->irq_data);
> > > + if (ret)
> > > + return ret;
> > > +
> > > + ret = pf1550_add_child_device(pf1550, regulator, pf1550->irq_data,
> > > + PF1550_IRQ_REGULATOR,
> > > + &pf1550_regulator_irq_chip,
> > > + &pf1550->irq_data_regulator);
> > > + if (ret)
> > > + return ret;
> > > +
> > > + ret = pf1550_add_child_device(pf1550, onkey, pf1550->irq_data,
> > > + PF1550_IRQ_ONKEY,
> > > + &pf1550_onkey_irq_chip,
> > > + &pf1550->irq_data_onkey);
> > > + if (ret)
> > > + return ret;
> > > +
> > > + ret = pf1550_add_child_device(pf1550, charger, pf1550->irq_data,
> > > + PF1550_IRQ_CHG,
> > > + &pf1550_charger_irq_chip,
> > > + &pf1550->irq_data_charger);
> > > + return ret;
> > > +}
> > > +
> > > +static int pf1550_suspend(struct device *dev)
> > > +{
> > > + struct i2c_client *i2c = container_of(dev, struct i2c_client, dev);
> > > + struct pf1550_dev *pf1550 = i2c_get_clientdata(i2c);
> >
> > You can swap all of this for:
> >
> > struct pf1550_dev *pf1550 = dev_get_drvdata(dev).
> >
> Will do.
> > > +
> > > + if (device_may_wakeup(dev)) {
> > > + enable_irq_wake(pf1550->irq);
> > > + disable_irq(pf1550->irq);
> > > + }
> > > +
> > > + return 0;
> > > +}
> > > +
> > > +static int pf1550_resume(struct device *dev)
> > > +{
> > > + struct i2c_client *i2c = container_of(dev, struct i2c_client, dev);
> > > + struct pf1550_dev *pf1550 = i2c_get_clientdata(i2c);
> >
> > As above.
> >
> > > +
> > > + if (device_may_wakeup(dev)) {
> > > + disable_irq_wake(pf1550->irq);
> > > + enable_irq(pf1550->irq);
> >
> > I would normally expect these to be around the opposite way to the ones
> > in .suspend().
> Do you mean enable_irq_wake and disable_irq in .resume() and the opposite for
> .suspend()?
Yes. Or whatever fits best.
Maybe the h/w doesn't work that way, I just found it odd.
--
Lee Jones [李琼斯]
next prev parent reply other threads:[~2025-06-24 16:02 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-06-12 14:55 [PATCH v7 0/6] add support for pf1550 PMIC MFD-based drivers Samuel Kayode
2025-06-12 14:55 ` Samuel Kayode via B4 Relay
2025-06-12 14:55 ` [PATCH v7 1/6] dt-bindings: mfd: add pf1550 Samuel Kayode
2025-06-12 14:55 ` Samuel Kayode via B4 Relay
2025-06-12 14:55 ` [PATCH v7 2/6] mfd: pf1550: add core mfd driver Samuel Kayode
2025-06-12 14:55 ` Samuel Kayode via B4 Relay
2025-06-19 13:03 ` Lee Jones
2025-06-20 18:43 ` Samuel Kayode
2025-06-24 16:02 ` Lee Jones [this message]
2025-06-12 14:55 ` [PATCH v7 3/6] regulator: pf1550: add support for regulator Samuel Kayode
2025-06-12 14:55 ` Samuel Kayode via B4 Relay
2025-06-12 14:55 ` [PATCH v7 4/6] input: pf1550: add onkey support Samuel Kayode
2025-06-12 14:55 ` Samuel Kayode via B4 Relay
2025-06-17 22:23 ` Dmitry Torokhov
2025-06-12 14:55 ` [PATCH v7 5/6] power: supply: pf1550: add battery charger support Samuel Kayode
2025-06-12 14:55 ` Samuel Kayode via B4 Relay
2025-06-12 16:02 ` Frank Li
2025-06-22 0:43 ` Sebastian Reichel
2025-06-25 14:19 ` Samuel Kayode
2025-07-06 23:33 ` Sebastian Reichel
2025-07-07 15:10 ` Samuel Kayode
2025-06-12 14:55 ` [PATCH v7 6/6] MAINTAINERS: add an entry for pf1550 mfd driver Samuel Kayode
2025-06-12 14:55 ` Samuel Kayode via B4 Relay
2025-06-12 16:03 ` Frank Li
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=20250624160235.GM795775@google.com \
--to=lee@kernel.org \
--cc=Frank.li@nxp.com \
--cc=abelvesa@kernel.org \
--cc=abelvesa@linux.com \
--cc=b38343@freescale.com \
--cc=broonie@kernel.org \
--cc=conor+dt@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=dmitry.torokhov@gmail.com \
--cc=eballetbo@gmail.com \
--cc=imx@lists.linux.dev \
--cc=krzk+dt@kernel.org \
--cc=lgirdwood@gmail.com \
--cc=linux-input@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pm@vger.kernel.org \
--cc=robh@kernel.org \
--cc=samuel.kayode@savoirfairelinux.com \
--cc=sre@kernel.org \
--cc=yibin.gong@nxp.com \
/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.