All of lore.kernel.org
 help / color / mirror / Atom feed
From: Lee Jones <lee.jones@linaro.org>
To: Paul Cercueil <paul@crapouillou.net>
Cc: Rob Herring <robh+dt@kernel.org>,
	Mark Rutland <mark.rutland@arm.com>,
	Ralf Baechle <ralf@linux-mips.org>,
	Paul Burton <paul.burton@mips.com>,
	James Hogan <jhogan@kernel.org>, Jonathan Corbet <corbet@lwn.net>,
	Daniel Lezcano <daniel.lezcano@linaro.org>,
	Thomas Gleixner <tglx@linutronix.de>,
	Michael Turquette <mturquette@baylibre.com>,
	Stephen Boyd <sboyd@kernel.org>,
	Jason Cooper <jason@lakedaemon.net>,
	Marc Zyngier <marc.zyngier@arm.com>,
	Mathieu Malaterre <malat@debian.org>,
	linux-kernel@vger.kernel.org, devicetree@vger.kernel.org,
	linux-mips@vger.kernel.org, linux-doc@vger.kernel.org,
	linux-clk@vger.kernel.org, od@zcrc.me
Subject: Re: [PATCH v12 04/13] mfd: Add Ingenic TCU driver
Date: Thu, 27 Jun 2019 10:01:02 +0100	[thread overview]
Message-ID: <20190627090102.GA2000@dell> (raw)
In-Reply-To: <1561625387.1745.0@crapouillou.net>

On Thu, 27 Jun 2019, Paul Cercueil wrote:
> Le jeu. 27 juin 2019 à 8:58, Lee Jones <lee.jones@linaro.org> a écrit :
> > On Wed, 26 Jun 2019, Paul Cercueil wrote:
> > >  Le mer. 26 juin 2019 à 15:18, Lee Jones <lee.jones@linaro.org> a
> > > écrit :
> > >  > On Tue, 21 May 2019, Paul Cercueil wrote:
> > >  >
> > >  > >  This driver will provide a regmap that can be retrieved very
> > > early
> > >  > > in
> > >  > >  the boot process through the API function
> > > ingenic_tcu_get_regmap().
> > >  > >
> > >  > >  Additionally, it will call devm_of_platform_populate() so that
> > > all
> > >  > > the
> > >  > >  children devices will be probed.
> > >  > >
> > >  > >  Signed-off-by: Paul Cercueil <paul@crapouillou.net>
> > >  > >  ---
> > >  > >
> > >  > >  Notes:
> > >  > >      v12: New patch
> > >  > >
> > >  > >   drivers/mfd/Kconfig             |   8 +++
> > >  > >   drivers/mfd/Makefile            |   1 +
> > >  > >   drivers/mfd/ingenic-tcu.c       | 113
> > >  > > ++++++++++++++++++++++++++++++++
> > >  > >   include/linux/mfd/ingenic-tcu.h |   8 +++
> > >  > >   4 files changed, 130 insertions(+)
> > >  > >   create mode 100644 drivers/mfd/ingenic-tcu.c
> > 
> > [...]
> > 
> > >  > >  +static struct regmap * __init ingenic_tcu_create_regmap(struct
> > >  > > device_node *np)
> > >  > >  +{
> > >  > >  +	struct resource res;
> > >  > >  +	void __iomem *base;
> > >  > >  +	struct regmap *map;
> > >  > >  +
> > >  > >  +	if (!of_match_node(ingenic_tcu_of_match, np))
> > >  > >  +		return ERR_PTR(-EINVAL);
> > 
> > Drop this check.
> > 
> > >  > >  +	base = of_io_request_and_map(np, 0, "TCU");
> > >  > >  +	if (IS_ERR(base))
> > >  > >  +		return ERR_PTR(PTR_ERR(base));
> > >  > >  +
> > >  > >  +	map = regmap_init_mmio(NULL, base,
> > > &ingenic_tcu_regmap_config);
> > >  > >  +	if (IS_ERR(map))
> > >  > >  +		goto err_iounmap;
> > 
> > Place this inside probe().
> > 
> > >  > >  +	return map;
> > >  > >  +
> > >  > >  +err_iounmap:
> > >  > >  +	iounmap(base);
> > >  > >  +	of_address_to_resource(np, 0, &res);
> > >  > >  +	release_mem_region(res.start, resource_size(&res));
> > >  > >  +
> > >  > >  +	return map;
> > >  > >  +}
> > >  >
> > >  > Why does this need to be set-up earlier than probe()?
> > > 
> > >  See the explanation below.
> > 
> > I think the answer is, it doesn't.
> > 
> > >  > >  +static int __init ingenic_tcu_probe(struct platform_device
> > > *pdev)
> > >  > >  +{
> > >  > >  +	struct regmap *map =
> > > ingenic_tcu_get_regmap(pdev->dev.of_node);
> > >  > >  +
> > >  > >  +	platform_set_drvdata(pdev, map);
> > >  > >  +
> > >  > >  +	regmap_attach_dev(&pdev->dev, map,
> > > &ingenic_tcu_regmap_config);
> > >  > >  +
> > >  > >  +	return devm_of_platform_populate(&pdev->dev);
> > >  > >  +}
> > >  > >  +
> > >  > >  +static struct platform_driver ingenic_tcu_driver = {
> > >  > >  +	.driver = {
> > >  > >  +		.name = "ingenic-tcu",
> > >  > >  +		.of_match_table = ingenic_tcu_of_match,
> > >  > >  +	},
> > >  > >  +};
> > >  > >  +
> > >  > >  +static int __init ingenic_tcu_platform_init(void)
> > >  > >  +{
> > >  > >  +	return platform_driver_probe(&ingenic_tcu_driver,
> > >  > >  +				     ingenic_tcu_probe);
> > >  >
> > >  > What?  Why?
> > > 
> > >  The device driver probed here will populate the children devices,
> > >  which will be able to retrieve the pointer to the regmap through
> > >  device_get_regmap(dev->parent).
> > 
> > I've never heard of this call.  Where is it?
> 
> dev_get_regmap, in <linux/regmap.h>.
> 
> > >  The children devices are normal platform drivers that can be probed
> > >  the normal way. These are the PWM driver, the watchdog driver, and
> > > the
> > >  OST (OS Timer) clocksource driver, all part of the same hardware
> > > block
> > >  (the Timer/Counter Unit or TCU).
> > 
> > If they are normal devices, then there is no need to roll your own
> > regmap-getter implementation like this.
> > 
> > >  > >  +}
> > >  > >  +subsys_initcall(ingenic_tcu_platform_init);
> > >  > >  +
> > >  > >  +struct regmap * __init ingenic_tcu_get_regmap(struct
> > > device_node
> > >  > > *np)
> > >  > >  +{
> > >  > >  +	if (!tcu_regmap)
> > >  > >  +		tcu_regmap = ingenic_tcu_create_regmap(np);
> > >  > >  +
> > >  > >  +	return tcu_regmap;
> > >  > >  +}
> > >  >
> > >  > This makes me pretty uncomfortable.
> > >  >
> > >  > What calls it?
> > > 
> > >  The TCU IRQ driver (patch [06/13]), clocks driver (patch [05/13]),
> > > and the
> > >  non-OST clocksource driver (patch [07/13]) all probe very early in
> > > the boot
> > >  process, and share the same devicetree node. They call this
> > > function to get
> > >  a pointer to the regmap.
> > 
> > Horrible!
> > 
> > Instead, you should send it through platform_set_drvdata() and collect
> > it in the child drivers with platform_get_drvdata(dev->parent).
> 
> The IRQ, clocks and clocksource driver do NOT have a "struct device" to
> begin with. They are not platform drivers, and cannot be platform drivers,
> as they must register so early in the boot process, before "struct device"
> is even a thing.
> 
> All they get is a pointer to the same devicetree node. Since all of these
> have to use the same registers, they need to use a shared regmap, which
> they obtain by calling ingenic_tcu_get_regmap() below.
> 
> Then, when this driver's probe gets called, the regmap is retrieved and
> attached to the struct device, and then the children devices will be
> probed: the watchdog device, the PWM device, the OST device. These three
> will retrieve the regmap by calling dev_get_regmap(dev->parent, NULL).

That makes sense.

This explanation certainly belongs in the commit log.

Can you send your v14, as you intended.  I will re-review it with new
eyes when you do.

> > >  > >  +bool ingenic_tcu_pwm_can_use_chn(struct device *dev, unsigned
> > > int
> > >  > > channel)
> > >  > >  +{
> > >  > >  +	const struct ingenic_soc_info *soc =
> > >  > > device_get_match_data(dev->parent);
> > >  > >  +
> > >  > >  +	/* Enable all TCU channels for PWM use by default except
> > > channels
> > >  > > 0/1 */
> > >  > >  +	u32 pwm_channels_mask = GENMASK(soc->num_channels - 1, 2);
> > >  > >  +
> > >  > >  +	device_property_read_u32(dev->parent,
> > > "ingenic,pwm-channels-mask",
> > >  > >  +				 &pwm_channels_mask);
> > 
> > Doesn't this call overwrite the previous assignment above?
> 
> Yes, that's intended. You have a default value, that can be overriden
> by a device property.

You should provide a comment here to make your intentions clear.

> > >  > >  +	return !!(pwm_channels_mask & BIT(channel));
> > >  > >  +}
> > >  > >  +EXPORT_SYMBOL_GPL(ingenic_tcu_pwm_can_use_chn);
> > 
> > Where is this called from?
> 
> This is called from the PWM driver.

Why can't it live in the PWM driver?

-- 
Lee Jones [李琼斯]
Linaro Services Technical Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

  reply	other threads:[~2019-06-27  9:01 UTC|newest]

Thread overview: 33+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-05-21 14:51 Ingenic Timer/Counter Unit (TCU) patchset v12 Paul Cercueil
2019-05-21 14:51 ` [PATCH v12 01/13] dt-bindings: ingenic: Add DT bindings for TCU clocks Paul Cercueil
2019-05-21 14:51 ` [PATCH v12 02/13] doc: Add doc for the Ingenic TCU hardware Paul Cercueil
2019-05-21 14:51 ` [PATCH v12 03/13] dt-bindings: Add doc for the Ingenic TCU drivers Paul Cercueil
2019-05-24 20:21   ` Rob Herring
2019-05-25 19:13     ` Paul Cercueil
2019-06-11 14:57       ` Rob Herring
2019-05-21 14:51 ` [PATCH v12 04/13] mfd: Add Ingenic TCU driver Paul Cercueil
2019-06-22 12:21   ` Paul Cercueil
2019-06-26 13:18   ` Lee Jones
2019-06-26 13:55     ` Paul Cercueil
2019-06-27  6:58       ` Lee Jones
2019-06-27  8:49         ` Paul Cercueil
2019-06-27  9:01           ` Lee Jones [this message]
2019-06-27  9:19             ` Paul Cercueil
2019-05-21 14:51 ` [PATCH v12 05/13] clk: ingenic: Add driver for the TCU clocks Paul Cercueil
2019-06-07 21:28   ` Stephen Boyd
2019-06-07 21:28     ` Stephen Boyd
2019-06-07 21:59     ` Paul Cercueil
2019-06-07 22:50       ` Stephen Boyd
2019-05-21 14:51 ` [PATCH v12 06/13] irqchip: Add irq-ingenic-tcu driver Paul Cercueil
2019-06-22 12:22   ` Paul Cercueil
2019-05-21 14:51 ` [PATCH v12 07/13] clocksource: Add a new timer-ingenic driver Paul Cercueil
2019-06-22 12:23   ` Paul Cercueil
2019-05-21 14:51 ` [PATCH v12 08/13] clk: jz4740: Add TCU clock Paul Cercueil
2019-05-21 14:51 ` [PATCH v12 09/13] MIPS: jz4740: Add DTS nodes for the TCU drivers Paul Cercueil
2019-05-22  9:21   ` Mathieu Malaterre
2019-05-22 11:15     ` Paul Cercueil
2019-05-21 14:51 ` [PATCH v12 10/13] MIPS: qi_lb60: Reduce system timer and clocksource to 750 kHz Paul Cercueil
2019-05-21 14:51 ` [PATCH v12 11/13] MIPS: CI20: Reduce system timer and clocksource to 3 MHz Paul Cercueil
2019-05-21 14:51 ` [PATCH v12 12/13] MIPS: GCW0: Reduce system timer and clocksource to 750 kHz Paul Cercueil
2019-05-21 14:51 ` [PATCH v12 13/13] MIPS: jz4740: Drop obsolete code Paul Cercueil
2019-05-27 11:39 ` Ingenic Timer/Counter Unit (TCU) patchset v12 Mathieu Malaterre

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=20190627090102.GA2000@dell \
    --to=lee.jones@linaro.org \
    --cc=corbet@lwn.net \
    --cc=daniel.lezcano@linaro.org \
    --cc=devicetree@vger.kernel.org \
    --cc=jason@lakedaemon.net \
    --cc=jhogan@kernel.org \
    --cc=linux-clk@vger.kernel.org \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mips@vger.kernel.org \
    --cc=malat@debian.org \
    --cc=marc.zyngier@arm.com \
    --cc=mark.rutland@arm.com \
    --cc=mturquette@baylibre.com \
    --cc=od@zcrc.me \
    --cc=paul.burton@mips.com \
    --cc=paul@crapouillou.net \
    --cc=ralf@linux-mips.org \
    --cc=robh+dt@kernel.org \
    --cc=sboyd@kernel.org \
    --cc=tglx@linutronix.de \
    /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.