linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Lee Jones <lee.jones@linaro.org>
To: Charles Keepax <ckeepax@opensource.cirrus.com>
Cc: linux-kernel@vger.kernel.org, patches@opensource.cirrus.com
Subject: Re: [PATCH v2 1/2] mfd: mfd-core: Add mechanism for removal of a subset of children
Date: Tue, 16 Jun 2020 10:15:45 +0100	[thread overview]
Message-ID: <20200616091545.GP2608702@dell> (raw)
In-Reply-To: <20200616084748.GS71940@ediswmail.ad.cirrus.com>

On Tue, 16 Jun 2020, Charles Keepax wrote:

> On Tue, Jun 16, 2020 at 08:58:34AM +0100, Lee Jones wrote:
> > On Mon, 15 Jun 2020, Charles Keepax wrote:
> > > Happy to discuss other approaches as well, but this one was quite                                                                                                                                                                              │··················
> > > appealing as it was very simple but affords quite a lot of flexibility.                                                                                                                                                                        │··················
> > 
> > What about this?
> > 
> > diff --git a/drivers/mfd/mfd-core.c b/drivers/mfd/mfd-core.c
> > index f5a73af60dd40..a06e0332e1e31 100644
> > --- a/drivers/mfd/mfd-core.c
> > +++ b/drivers/mfd/mfd-core.c
> > @@ -283,7 +283,7 @@ int mfd_add_devices(struct device *parent, int id,
> >  }
> >  EXPORT_SYMBOL(mfd_add_devices);
> >  
> > -static int mfd_remove_devices_fn(struct device *dev, void *data)
> > +static int mfd_remove_devices_fn(struct device *dev, void *level)
> >  {
> >         struct platform_device *pdev;
> >         const struct mfd_cell *cell;
> > @@ -294,6 +294,9 @@ static int mfd_remove_devices_fn(struct device *dev, void *data)
> >         pdev = to_platform_device(dev);
> >         cell = mfd_get_cell(pdev);
> >  
> > +       if (cell->level && (!level || cell->level != *level))
> > +               return 0;
> > +
> >         regulator_bulk_unregister_supply_alias(dev, cell->parent_supplies,
> >                                                cell->num_parent_supplies);
> >  
> > @@ -303,7 +306,11 @@ static int mfd_remove_devices_fn(struct device *dev, void *data)
> >  
> >  void mfd_remove_devices(struct device *parent)
> >  {
> > +       int level = MFD_DEP_LEVEL_HIGH;
> > +
> >         device_for_each_child_reverse(parent, NULL, mfd_remove_devices_fn);
> > +       device_for_each_child_reverse(parent, &level, mfd_remove_devices_fn);
> >  }
> >  EXPORT_SYMBOL(mfd_remove_devices);
> > 
> > No need for special calls from the parent driver in this case.
> > 
> > Just a requirement to set the cell's dependency level.
> > 
> 
> Apologies if I am missing something here, but this looks like a
> pretty challenging interface from the drivers side.  Rather than
> just statically setting tag in the mfd_cells and separate calls
> to mfd_remove_devices_by_tag, such as:
> 
> 	mfd_remove_devices_by_tag(madera->dev, MADERA_OPTIONAL_DRIVER);
> 
> 	pm_runtime_disable(madera->dev);
> 	regulator_disable(madera->dcvdd);
> 	regulator_put(madera->dcvdd);
> 
> 	mfd_remove_devices(madera->dev);
> 
> You need to statically set the level but then also iterate through
> the children and update the cell level on each subsequent remove,
> in my case:
> 
> static int arizona_set_mfd_level(struct device *dev, void *data)
> {
> 	struct platform_device *pdev = to_platform_device(dev);
> 	if (pdev->mfd_cell)
> 		pdev->mfd_cell->level = MFD_DEP_LEVEL_HIGH;
> }
> ...
> 	mfd_remove_devices(madera->dev);
> 
> 	device_for_each_child(madera->dev, NULL, arizona_set_mfd_level);
> 
> 	pm_runtime_disable(madera->dev);
> 	regulator_disable(madera->dcvdd);
> 	regulator_put(madera->dcvdd);
> 
> 	mfd_remove_devices(madera->dev);
> 
> Does this match how you would expect this to be used?

No, not at all.

> I do have some concerns. The code can't use mfd_get_cell since it
> returns a const pointer, although the pointer in platform_device
> isn't const so we access that directly, could update mfd_get_cell? We
> also don't have access to mfd_dev_type outside of the mfd core so
> its hard to check we are actually setting the mfd_cell of actual
> MFD children, I guess just checking for mfd_cell being not NULL is
> good enough?

Hmmm... looks like I missed the fact that you needed additional
processing between the removal of each batch of devices.  My
implementation simply handles the order in which devices are removed
(a bit like initcall()s).

How about the inclusion of mfd_remove_devices_late(), whereby
mfd_remove_devices() will refuse to remove devices tagged with
MFD_DEP_LEVEL_HIGH.

Not sure why, but I really dislike the idea of device removal by
arbitrary value/tag, as I see it spawning all sorts of weird and
wonderful implications/hacks/abuse.

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

  reply	other threads:[~2020-06-16  9:15 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-06-15 15:07 [PATCH v2 1/2] mfd: mfd-core: Add mechanism for removal of a subset of children Charles Keepax
2020-06-15 15:07 ` [PATCH v2 2/2] mfd: madera: Improve handling of regulator unbinding Charles Keepax
2020-06-16  7:58 ` [PATCH v2 1/2] mfd: mfd-core: Add mechanism for removal of a subset of children Lee Jones
2020-06-16  8:47   ` Charles Keepax
2020-06-16  9:15     ` Lee Jones [this message]
2020-06-16 10:06       ` Charles Keepax
2020-06-16 13:22         ` Lee Jones
2020-06-16 13:30           ` Charles Keepax

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=20200616091545.GP2608702@dell \
    --to=lee.jones@linaro.org \
    --cc=ckeepax@opensource.cirrus.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=patches@opensource.cirrus.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;
as well as URLs for NNTP newsgroup(s).