[PATCH v5 04/11] clocksource/drivers: Add HPE GXP timer

Arnd Bergmann arnd at arndb.de
Tue Apr 26 16:00:20 AEST 2022


On Mon, Apr 25, 2022 at 10:38 PM Linus Walleij <linus.walleij at linaro.org> wrote:
> On Fri, Apr 22, 2022 at 3:16 PM Arnd Bergmann <arnd at arndb.de> wrote:
> > On Thu, Apr 21, 2022 at 9:21 PM <nick.hawkins at hpe.com> wrote:
> >
> > > +
> > > +static struct platform_device gxp_watchdog_device = {
> > > +       .name = "gxp-wdt",
> > > +       .id = -1,
> > > +};
> > > +/*
> > > + * This probe gets called after the timer is already up and running. This will create
> > > + * the watchdog device as a child since the registers are shared.
> > > + */
> > > +
> > > +static int gxp_timer_probe(struct platform_device *pdev)
> > > +{
> > > +       struct device *dev = &pdev->dev;
> > > +
> > > +       /* Pass the base address (counter) as platform data and nothing else */
> > > +       gxp_watchdog_device.dev.platform_data = local_gxp_timer->counter;
> > > +       gxp_watchdog_device.dev.parent = dev;
> > > +       return platform_device_register(&gxp_watchdog_device);
> > > +}
> >
> > I don't understand what this is about: the device should be created from
> > DT, not defined statically in the code. There are multiple ways of creating
> > a platform_device from a DT node, or you can allocate one here, but static
> > definitions are generally a mistake.
> >
> > I see that you copied this from the ixp4xx driver, so I think we should fix this
> > there as well.
>
> The ixp4xx driver looks like that because the register range used for
> the timer and the watchdog is combined, i.e. it is a single IP block:
>
>                 timer at c8005000 {
>                         compatible = "intel,ixp4xx-timer";
>                         reg = <0xc8005000 0x100>;
>                         interrupts = <5 IRQ_TYPE_LEVEL_HIGH>;
>                 };
>
> Device tree probing does not allow two devices to probe from the same
> DT node, so this was solved by letting the (less important) watchdog
> be spawn as a platform device from the timer.
>
> I don't know if double-probing for the same register range can be fixed,
> but I was assuming that the one-compatible-to-one-driver assumption
> was pretty hard-coded into the abstractions. Maybe it isn't?

Having a child device is fine, my objection was about the way
the device is created from a 'static platform_device ...' definition
rather than having the device structure allocated at probe time.

> Another way is of course to introduce an MFD. That becomes
> problematic in another way: MFD abstractions are supposed to
> be inbetween the resource and the devices it spawns, and with
> timers/clocksources this creates a horrible special-casing since the
> MFD bus (the parent may be providing e.g. an MMIO regmap)
> then need to be early-populated and searched by the timer core
> from TIMER_OF_DECLARE() early in boot.
>
> So this solution was the lesser evil that I could think about.

There are multiple ways of doing this that we already discussed
in the thread. The easiest is probably to have a child node without
custom registers in the DT and then use the DT helpers to
populate the linux devices with the correct data.

       Arnd


More information about the openbmc mailing list