Re: [PATCH v6 2/3] mfd: syscon: Add managed registration for external regmaps
James Hilliard <[email protected]>
| Newsgroups | dev.linux.lists.mfd,org.kernel.vger.linux-devicetree,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <CADvTj4rLO9SDY1CKef-VpbUVgNxJdtro45z7vY+cc8rB22i-7g@mail.gmail.com> |
On Tue, Aug 11, 2026 at 5:03 AM Arnd Bergmann <[email protected]> wrote: > > On Tue, Aug 11, 2026, at 11:17, James Hilliard wrote: > > On Tue, Aug 11, 2026 at 2:47 AM Arnd Bergmann <[email protected]> wrote: > > >> I don't think this is the right way to do it. As far as I can tell, > >> the device you have here is a generic mfd that uses a regmap, which > >> is not the same thing we usually call a syscon. > >> > >> The of_syscon_register_regmap() code path was added specifically > >> for chips that have a traditional syscon but depending on the > >> firmware may have to access this by some other means. This is > >> already stretching the definition of syscon. I don't think we > >> should take this further and allow normal device drivers like > >> yours to register through the syscon framework. > > > > This was suggested to me by Andrew: > > https://lore.kernel.org/all/[email protected]/ > > Maybe Andrew can clarify, but his reply can also be interpreted > as saying that you should copy syscon_regmap_lookup_by_phandle() > into your own driver, rather than changing the actual > syscon code. A literal copy would still depend on the syscon registry: syscon_regmap_lookup_by_phandle() parses the phandle and then obtains the regmap through syscon_node_to_regmap(). It does not find a normal device associated with the referenced node. A private AC200 implementation would instead have to find the I2C device, establish lifetime ordering, verify that its driver is bound and call dev_get_regmap(). That is effectively the v4 implementation rather than a copy of the syscon helper. Is that direct device lookup what you had in mind, or were you suggesting another way for the private helper to reach the I2C-created regmap? > One problem I see with your current approach is that the lifetime of > the regmap is not the lifetime of the user by the framework. > Unloading the mfd driver while the phy driver is in use will > destroy the regmap. This is a direct result of syscon being > a very special case that must work during early boot instead > of being a general-purpose abstraction for managing regmaps. The PHY creates a managed device link to the AC200 I2C device before obtaining its regmap. The driver core therefore unbinds the PHY consumer before allowing the AC200 supplier to release its devres-managed regmap. The PHY also checks under the supplier device lock that the AC200 probe has completed before using the regmap. This prevents it from observing the regmap while the supplier is only partially initialized. See: https://lore.kernel.org/all/[email protected]/ > >> Since you already have a top-level mfd device here, just use > >> that to pass the regmap to the child devices like we do for > >> other mfd drivers. You can e.g. do this when populating the child > >> devices through platform_data, or get the pointer from the > >> parent drvdata. > > > > The EPHY is not an MFD-created platform child. Phylib enumerates it as a > > struct phy_device on the SoC MDIO bus, so its device parent is the > > struct mii_bus rather than the AC200 I2C device. It therefore cannot > > directly obtain the AC200 regmap through parent drvdata or MFD child > > platform data. > > I see, so the fundamental problem here is that you have a single > device that is connected to two buses and both the OF devicetree > and the Linux driver model are rather bad at handling this. The link PHY is enumerated by phylib on the MDIO bus, while its package-control registers are accessed through the separately enumerated AC200 I2C device. > I would probably do this in one of two ways: > > a) have a driver module that registers both a phy driver and > a platform_driver and figures out the interaction between > them internally. That would require creating a second platform device for the AC200 control side even though the actual PHY is enumerated on MDIO. The two driver instances would still need explicit instance matching, probe ordering and removal coordination, presumably using the same firmware reference or an internal registry. > b) have the MFD driver export a private interface that lets > the phy_driver interact with the i2c registers and > make sure the i2c_driver sets suppress_bind_attrs=true > to prevent it from being unbound while the phy_driver > is loaded. The symbol dependency itself is enough to > prevent the mfd driver from being unloaded here. If the private interface only returns the regmap, it would largely duplicate dev_get_regmap(). It would also introduce a link-time dependency from the combined AC200/AC300 PHY module on the AC200 MFD module, including on AC300-only systems. Avoiding that would require splitting the PHY module or adding configuration-dependent stubs. suppress_bind_attrs would prevent manual sysfs unbind, but a managed device link already provides per-device teardown ordering without disabling unbind globally. > In either case, you still have the choice between a proper > abstraction that can deal with multiple instances of the > ac200 device, or slightly cheaty but common assumption that > only one of them can ever be present. There is also the approach used in v4: resolve the exact AC200 I2C device from the package phandle, establish the managed device link, verify that the supplier is bound, and retrieve its attached regmap with dev_get_regmap(). That uses the existing device and regmap interfaces, retains safe unbind ordering through the device link, and supports multiple AC200 instances because lookup is keyed by the phandle. It does not require an additional platform device, a private exported interface, or disabling manual unbind. Would that direct device-link and dev_get_regmap() approach be acceptable? v4: https://lore.kernel.org/all/[email protected]/ > > Arnd