Linux kernel and device drivers for NXP i.MX platforms
 help / color / mirror / Atom feed
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, &reg_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 [李琼斯]

  reply	other threads:[~2025-06-24 16:02 UTC|newest]

Thread overview: 17+ 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 via B4 Relay
2025-06-12 14:55 ` [PATCH v7 1/6] dt-bindings: mfd: add pf1550 Samuel Kayode via B4 Relay
2025-06-12 14:55 ` [PATCH v7 2/6] mfd: pf1550: add core mfd driver 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 via B4 Relay
2025-06-12 14:55 ` [PATCH v7 4/6] input: pf1550: add onkey support 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 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 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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox