diff mbox

[5/8] mfd: Provide the PRCMU with its own IRQ domain

Message ID 1344527635-6163-6-git-send-email-lee.jones@linaro.org (mailing list archive)
State New, archived
Headers show

Commit Message

Lee Jones Aug. 9, 2012, 3:53 p.m. UTC
The PRCMU has its own USB, Thermal, GPIO, Modem, HSI and RTC drivers,
amongst other things. This patch allows those subordinate devices to
use it as an interrupt controller as and when they are DT enabled.

CC: Samuel Ortiz <sameo@linux.intel.com>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
---
 drivers/mfd/db8500-prcmu.c       |   54 +++++++++++++++++++++++++++++---------
 include/linux/mfd/db8500-prcmu.h |    2 ++
 2 files changed, 43 insertions(+), 13 deletions(-)

Comments

Linus Walleij Aug. 14, 2012, 8:29 a.m. UTC | #1
On Thu, Aug 9, 2012 at 5:53 PM, Lee Jones <lee.jones@linaro.org> wrote:

> +static struct irq_domain *db8500_irq_domain;

So this is a good idea.

> +int db8500_irq_get_virq(int irq);

And I'm sceptic about this business. Why isn't this physical-to virtual
mapping business confined to the core MFD driver? But enlighten me.

Yours,
Linus Walleij
Arnd Bergmann Aug. 14, 2012, 9:42 a.m. UTC | #2
On Tuesday 14 August 2012, Linus Walleij wrote:
> 
> On Thu, Aug 9, 2012 at 5:53 PM, Lee Jones <lee.jones@linaro.org> wrote:
> 
> > +static struct irq_domain *db8500_irq_domain;
> 
> So this is a good idea.
> 
> > +int db8500_irq_get_virq(int irq);
> 
> And I'm sceptic about this business. Why isn't this physical-to virtual
> mapping business confined to the core MFD driver? But enlighten me.
> 

I believe MFD does not (yet) know about IRQ domains. The wm8994
and 88pm80x drivers do this slightly different by exporting
a foo_request_irq() function that performs the mapping.

Traditionally, an MFD would add an offset to the local IRQ number
to put the VIRQ into the IRQ resource, but this doesn't work when
you have domains other than legacy.

	Arnd
Linus Walleij Aug. 14, 2012, 10:44 a.m. UTC | #3
On Tue, Aug 14, 2012 at 11:42 AM, Arnd Bergmann <arnd@arndb.de> wrote:
> On Tuesday 14 August 2012, Linus Walleij wrote:
>> On Thu, Aug 9, 2012 at 5:53 PM, Lee Jones <lee.jones@linaro.org> wrote:
>>
>> > +int db8500_irq_get_virq(int irq);
>>
>> And I'm sceptic about this business. Why isn't this physical-to virtual
>> mapping business confined to the core MFD driver? But enlighten me.
>
> Traditionally, an MFD would add an offset to the local IRQ number
> to put the VIRQ into the IRQ resource, but this doesn't work when
> you have domains other than legacy.

Yes but I think I saw this other patch set from Lee, hitting
irqdomain, OF and MFD to actually fix this ... or did I get
it wrong?

Yours,
Linus Walleij
Lee Jones Aug. 20, 2012, 8:36 a.m. UTC | #4
On Tue, Aug 14, 2012 at 12:44:37PM +0200, Linus Walleij wrote:
> On Tue, Aug 14, 2012 at 11:42 AM, Arnd Bergmann <arnd@arndb.de> wrote:
> > On Tuesday 14 August 2012, Linus Walleij wrote:
> >> On Thu, Aug 9, 2012 at 5:53 PM, Lee Jones <lee.jones@linaro.org> wrote:
> >>
> >> > +int db8500_irq_get_virq(int irq);
> >>
> >> And I'm sceptic about this business. Why isn't this physical-to virtual
> >> mapping business confined to the core MFD driver? But enlighten me.
> >
> > Traditionally, an MFD would add an offset to the local IRQ number
> > to put the VIRQ into the IRQ resource, but this doesn't work when
> > you have domains other than legacy.
> 
> Yes but I think I saw this other patch set from Lee, hitting
> irqdomain, OF and MFD to actually fix this ... or did I get
> it wrong?

No, you're not wrong.

Historically (in my patches) xb8500_irq_get_virq() was used by drivers
to obtain a VIRQ when not using Device Tree. Now the MFD core handles
conversion there is little requirement for it. In fact there are no
more users for db8500_irq_get_virq() and only one user for 
ab8500_irq_get_virq() and that's itself. I guess we can rid them and
call irq_get_mapping() directly instead.
Lee Jones Aug. 20, 2012, 9:36 a.m. UTC | #5
On Tue, Aug 14, 2012 at 10:29:14AM +0200, Linus Walleij wrote:
> On Thu, Aug 9, 2012 at 5:53 PM, Lee Jones <lee.jones@linaro.org> wrote:
> 
> > +static struct irq_domain *db8500_irq_domain;
> 
> So this is a good idea.

Did you mean this, or did you mean that it's _not_ a good idea?

If the latter is true, where would you prefer to see it?

> > +int db8500_irq_get_virq(int irq);
> 
> And I'm sceptic about this business. Why isn't this physical-to virtual
> mapping business confined to the core MFD driver? But enlighten me.
> 
> Yours,
> Linus Walleij
Mark Brown Aug. 20, 2012, 12:10 p.m. UTC | #6
On Mon, Aug 20, 2012 at 09:36:43AM +0100, Lee Jones wrote:
> On Tue, Aug 14, 2012 at 12:44:37PM +0200, Linus Walleij wrote:

> > Yes but I think I saw this other patch set from Lee, hitting
> > irqdomain, OF and MFD to actually fix this ... or did I get
> > it wrong?

> No, you're not wrong.

> Historically (in my patches) xb8500_irq_get_virq() was used by drivers
> to obtain a VIRQ when not using Device Tree. Now the MFD core handles
> conversion there is little requirement for it. In fact there are no
> more users for db8500_irq_get_virq() and only one user for 
> ab8500_irq_get_virq() and that's itself. I guess we can rid them and
> call irq_get_mapping() directly instead.

Oh dear.  Unfortunately whoever added this support to the MFD core did
so in such a manner that it's only supported for device tree systems
and only for devices which express the MFD cells as device tree nodes
which means that most devices can't it - db8500 has got a reasonably
unusual combination there.
Lee Jones Aug. 20, 2012, 12:55 p.m. UTC | #7
On Mon, Aug 20, 2012 at 01:10:55PM +0100, Mark Brown wrote:
> On Mon, Aug 20, 2012 at 09:36:43AM +0100, Lee Jones wrote:
> > On Tue, Aug 14, 2012 at 12:44:37PM +0200, Linus Walleij wrote:
> 
> > > Yes but I think I saw this other patch set from Lee, hitting
> > > irqdomain, OF and MFD to actually fix this ... or did I get
> > > it wrong?
> 
> > No, you're not wrong.
> 
> > Historically (in my patches) xb8500_irq_get_virq() was used by drivers
> > to obtain a VIRQ when not using Device Tree. Now the MFD core handles
> > conversion there is little requirement for it. In fact there are no
> > more users for db8500_irq_get_virq() and only one user for 
> > ab8500_irq_get_virq() and that's itself. I guess we can rid them and
> > call irq_get_mapping() directly instead.
> 
> Oh dear.  Unfortunately whoever added this support to the MFD core did
> so in such a manner that it's only supported for device tree systems
> and only for devices which express the MFD cells as device tree nodes
> which means that most devices can't it - db8500 has got a reasonably
> unusual combination there.

Right, that was the initial intention. It would be a trivial semantic
change if drivers without DT support wished to use the functionality
though. However, the only examples I found of a non-DT enabled driver
that could make good use of it in order to strip out some cruft would
be the Arizona and one of the Samsung drivers, and they each have
their own hand-rolled methods of hwirq -> virq conversion now, so any
change to support them would result in multiple invocations of
irq_create_mapping which would likely cause breakage.
Mark Brown Aug. 20, 2012, 4:29 p.m. UTC | #8
On Mon, Aug 20, 2012 at 01:55:32PM +0100, Lee Jones wrote:

> Right, that was the initial intention. It would be a trivial semantic
> change if drivers without DT support wished to use the functionality
> though. However, the only examples I found of a non-DT enabled driver
> that could make good use of it in order to strip out some cruft would
> be the Arizona and one of the Samsung drivers, and they each have

All of the regmap devices could use this.

> their own hand-rolled methods of hwirq -> virq conversion now, so any
> change to support them would result in multiple invocations of
> irq_create_mapping which would likely cause breakage.

Multiple calls to irq_create_mapping() are totally fine.
Lee Jones Aug. 20, 2012, 4:49 p.m. UTC | #9
On Mon, Aug 20, 2012 at 05:29:23PM +0100, Mark Brown wrote:
> On Mon, Aug 20, 2012 at 01:55:32PM +0100, Lee Jones wrote:
> 
> > Right, that was the initial intention. It would be a trivial semantic
> > change if drivers without DT support wished to use the functionality
> > though. However, the only examples I found of a non-DT enabled driver
> > that could make good use of it in order to strip out some cruft would
> > be the Arizona and one of the Samsung drivers, and they each have
> 
> All of the regmap devices could use this.

Only if they have linear domains and don't support DT.

If they don't have linear domains there's no point, if they support DT
then they can use it as it is.

> > their own hand-rolled methods of hwirq -> virq conversion now, so any
> > change to support them would result in multiple invocations of
> > irq_create_mapping which would likely cause breakage.
> 
> Multiple calls to irq_create_mapping() are totally fine.

Sorry, perhaps I wasn't clear.

<mfd_parent_device>_probe()
|
+-> mfd_add_device()
    |
    +-> res->start = res->end = irq_create_mapping(res->start); // Now a VIRQ


<mfd_child_device>_probe()
|
+-> <mfd_parent_device>_irq_get_virq(res->start) // Ahhh, double VIRQ conversion

To stop being DT dependent we'd need to remove all hand-rolled stuff 
that these drivers are currently using, or else they will be attempting
to convert and already converted VIRQ value.
Mark Brown Aug. 20, 2012, 5:51 p.m. UTC | #10
On Mon, Aug 20, 2012 at 05:49:50PM +0100, Lee Jones wrote:
> On Mon, Aug 20, 2012 at 05:29:23PM +0100, Mark Brown wrote:

> > All of the regmap devices could use this.

> Only if they have linear domains and don't support DT.

Neither of those restrictions really apply...

> If they don't have linear domains there's no point, if they support DT
> then they can use it as it is.

All this stuff just works for any IRQ domain type, there's no
requirement for a particular one.  It's not urgently exciting for legacy
domains but it's not harmful either and pushes all the handling of this
stuff out of the MFD core and into the irqdomain code which is
definitely an abstraction win.

As far as DT goes supporting DT isn't enough, the current code will only
work on systems that actively use DT and do so using a particular style
of binding.  Since the majority of Linux architectures don't support DT
at all and it's not universally deployed on those that do this means
that generic drivers can't rely on it, and even drivers that use DT
might not be using the binding pattern which the framework code now
uses.

Indeed now that I think about the above isn't this going to be actively
harmful for generic drivers if they use this pattern for their bindings?
On DT systems the framework will unconditionally do the mapping but on
others no mapping will be done.  The function drivers don't know if the
mapping has been performed or not.

Unless I'm missing something here we need to fix this before the merge
window...

> To stop being DT dependent we'd need to remove all hand-rolled stuff 
> that these drivers are currently using, or else they will be attempting
> to convert and already converted VIRQ value. 

Well, yes - using framework code would be the goal here...
Lee Jones Aug. 21, 2012, 8:56 a.m. UTC | #11
> > If they don't have linear domains there's no point, if they support DT
> > then they can use it as it is.
> 
> All this stuff just works for any IRQ domain type, there's no
> requirement for a particular one.  It's not urgently exciting for legacy
> domains but it's not harmful either and pushes all the handling of this
> stuff out of the MFD core and into the irqdomain code which is
> definitely an abstraction win.

Wherever we do this from to be able to obtain the IRQ domain pointer, 
which is where I'm currently struggling. Our options are:

- Call into a helper function based in the IRQ controller from each 
child device. In turn the IRQ controller will be responsible for creating
the mapping necessary to obtain a virq. Using this method the child
device doesn't need to know if we're using an IRQ domain or not, or
whether we're using Device Tree or not. The drawback is that each child
device will be required to call the helper function prior to requesting
an IRQ. 

- If we're only talking MFD here, we can handle this stuff in the MFD
core, but we need more information. The IRQ domain subsystem only allows
domain look-up via a Device Tree node, so we need to get our hands on
the domain another way in the case of non-DT enabled devices. Either we
add another parameter to mfd_add_device(irq_domain, ...), or we
standardise the 'irq_domain' variable name and use:
        irq_domain = container_of(parent, struct irq_domain, irq_domain);

- I know that you have interest in pushing the functionality into the
IRQ domain subsystem, but I'm struggling to see how. It's calling into
the IRQ domain where we're seeing issues in the first place, specifically
irq_create_mapping(). How about if we passed 'irq_domain' as a parameter
when requesting the IRQ? That way we can pass the correct IRQ without
worry of conversion. If 'irq_domain' is !NULL the IRQ management subsystem
can do the necessary conversions. If 'irq_domain' is NULL it continues to
use the requested IRQ as a virq.
Mark Brown Aug. 21, 2012, 9:50 a.m. UTC | #12
On Tue, Aug 21, 2012 at 09:56:19AM +0100, Lee Jones wrote:

> Wherever we do this from to be able to obtain the IRQ domain pointer, 
> which is where I'm currently struggling. Our options are:

> - If we're only talking MFD here, we can handle this stuff in the MFD
> core, but we need more information. The IRQ domain subsystem only allows
> domain look-up via a Device Tree node, so we need to get our hands on

What makes you say this?  This is just a convenience for finding a
domain, irqdomains are *completely* indepentant of device tree.

> the domain another way in the case of non-DT enabled devices. Either we
> add another parameter to mfd_add_device(irq_domain, ...), or we
> standardise the 'irq_domain' variable name and use:
>         irq_domain = container_of(parent, struct irq_domain, irq_domain);

Passing the domain into mfd seems like the obvious solution here - it's
exactly what we currently do for legacy stuff (where we pass in the irq
base), ideally what we'd end up with over time is that we could just
remove the irq_base parameter entirely as everything would in time be
moved over to using irqdomains.

> - I know that you have interest in pushing the functionality into the
> IRQ domain subsystem, but I'm struggling to see how. It's calling into
> the IRQ domain where we're seeing issues in the first place, specifically
> irq_create_mapping(). How about if we passed 'irq_domain' as a parameter
> when requesting the IRQ? That way we can pass the correct IRQ without
> worry of conversion. If 'irq_domain' is !NULL the IRQ management subsystem
> can do the necessary conversions. If 'irq_domain' is NULL it continues to
> use the requested IRQ as a virq.

This is totally orthogonal to doing the mapping in the MFD subsystem
which is the issue here.
Lee Jones Aug. 21, 2012, 10:54 a.m. UTC | #13
On Tue, Aug 21, 2012 at 10:50:27AM +0100, Mark Brown wrote:
> On Tue, Aug 21, 2012 at 09:56:19AM +0100, Lee Jones wrote:
> 
> > Wherever we do this from to be able to obtain the IRQ domain pointer, 
> > which is where I'm currently struggling. Our options are:
> 
> > - If we're only talking MFD here, we can handle this stuff in the MFD
> > core, but we need more information. The IRQ domain subsystem only allows
> > domain look-up via a Device Tree node, so we need to get our hands on
> 
> What makes you say this?  This is just a convenience for finding a
> domain, irqdomains are *completely* indepentant of device tree.

How can you say that? I think you mean _can_ be independent of DT. If
that's what you mean then yes, that's true. All I'm saying is we need
another way to get hold of the domain, because the only way to obtain
it without having direct access is via a device node.
 
> > the domain another way in the case of non-DT enabled devices. Either we
> > add another parameter to mfd_add_device(irq_domain, ...), or we
> > standardise the 'irq_domain' variable name and use:
> >         irq_domain = container_of(parent, struct irq_domain, irq_domain);
> 
> Passing the domain into mfd seems like the obvious solution here - it's
> exactly what we currently do for legacy stuff (where we pass in the irq
> base), ideally what we'd end up with over time is that we could just
> remove the irq_base parameter entirely as everything would in time be
> moved over to using irqdomains.

Right. That's fine (and easy) then. You threw me when you said you wanted
it handled higher-up in the framework, as I didn't see how we could do 
this in the irqdomain itself.
 
> > - I know that you have interest in pushing the functionality into the
> > IRQ domain subsystem, but I'm struggling to see how. It's calling into
> > the IRQ domain where we're seeing issues in the first place, specifically
> > irq_create_mapping(). How about if we passed 'irq_domain' as a parameter
> > when requesting the IRQ? That way we can pass the correct IRQ without
> > worry of conversion. If 'irq_domain' is !NULL the IRQ management subsystem
> > can do the necessary conversions. If 'irq_domain' is NULL it continues to
> > use the requested IRQ as a virq.
> 
> This is totally orthogonal to doing the mapping in the MFD subsystem
> which is the issue here.

Again, I only mentioned this because you said you wanted it to be handled
by the irqdomain.

I'll code up the second suggestion now.
Mark Brown Aug. 21, 2012, 11:03 a.m. UTC | #14
On Tue, Aug 21, 2012 at 11:54:14AM +0100, Lee Jones wrote:
> On Tue, Aug 21, 2012 at 10:50:27AM +0100, Mark Brown wrote:

> > What makes you say this?  This is just a convenience for finding a
> > domain, irqdomains are *completely* indepentant of device tree.

> How can you say that? I think you mean _can_ be independent of DT. If
> that's what you mean then yes, that's true. All I'm saying is we need

No, I really mean what I'm saying.  Device tree builds on irqdomains,
not the other way around.

> another way to get hold of the domain, because the only way to obtain
> it without having direct access is via a device node.

This doesn't actually hold.

> > > - I know that you have interest in pushing the functionality into the
> > > IRQ domain subsystem, but I'm struggling to see how. It's calling into
> > > the IRQ domain where we're seeing issues in the first place, specifically
> > > irq_create_mapping(). How about if we passed 'irq_domain' as a parameter
> > > when requesting the IRQ? That way we can pass the correct IRQ without
> > > worry of conversion. If 'irq_domain' is !NULL the IRQ management subsystem
> > > can do the necessary conversions. If 'irq_domain' is NULL it continues to
> > > use the requested IRQ as a virq.

> > This is totally orthogonal to doing the mapping in the MFD subsystem
> > which is the issue here.

> Again, I only mentioned this because you said you wanted it to be handled
> by the irqdomain.

The *mapping* should be being handled in irqdomain.

> I'll code up the second suggestion now.

I've already done this.
Lee Jones Aug. 21, 2012, 12:02 p.m. UTC | #15
On Tue, Aug 21, 2012 at 12:03:29PM +0100, Mark Brown wrote:
> On Tue, Aug 21, 2012 at 11:54:14AM +0100, Lee Jones wrote:
> > On Tue, Aug 21, 2012 at 10:50:27AM +0100, Mark Brown wrote:
> 
> > > What makes you say this?  This is just a convenience for finding a
> > > domain, irqdomains are *completely* indepentant of device tree.
> 
> > How can you say that? I think you mean _can_ be independent of DT. If
> > that's what you mean then yes, that's true. All I'm saying is we need
> 
> No, I really mean what I'm saying.  Device tree builds on irqdomains,
> not the other way around.

This is just semantics.
 
> > another way to get hold of the domain, because the only way to obtain
> > it without having direct access is via a device node.
> 
> This doesn't actually hold.

Okay, besides irq_find_host(struct device_node *np), how else can you fetch
a domain from the irqdomain?

> > > > - I know that you have interest in pushing the functionality into the
> > > > IRQ domain subsystem, but I'm struggling to see how. It's calling into
> > > > the IRQ domain where we're seeing issues in the first place, specifically
> > > > irq_create_mapping(). How about if we passed 'irq_domain' as a parameter
> > > > when requesting the IRQ? That way we can pass the correct IRQ without
> > > > worry of conversion. If 'irq_domain' is !NULL the IRQ management subsystem
> > > > can do the necessary conversions. If 'irq_domain' is NULL it continues to
> > > > use the requested IRQ as a virq.
> 
> > > This is totally orthogonal to doing the mapping in the MFD subsystem
> > > which is the issue here.
> 
> > Again, I only mentioned this because you said you wanted it to be handled
> > by the irqdomain.
> 
> The *mapping* should be being handled in irqdomain.
> 
> > I'll code up the second suggestion now.
> 
> I've already done this.

What have you done already? 

Why make suggestions if you're just going to do the work yourself?
Mark Brown Aug. 21, 2012, 4:52 p.m. UTC | #16
On Tue, Aug 21, 2012 at 01:02:46PM +0100, Lee Jones wrote:
> On Tue, Aug 21, 2012 at 12:03:29PM +0100, Mark Brown wrote:

> > > another way to get hold of the domain, because the only way to obtain
> > > it without having direct access is via a device node.

> > This doesn't actually hold.

> Okay, besides irq_find_host(struct device_node *np), how else can you fetch
> a domain from the irqdomain?

I'm not sure I can parse the above, sorry - I'm not sure I can
distinguish "domain" and "irqdomain".

> What have you done already? 

Implemented a patch for this which I've now tested a bit and will
probably post in the next hour or so.

> Why make suggestions if you're just going to do the work yourself?

I made the suggestion then later on realised that this was actively
going to break things I care about so I actually need it fixing.
Lee Jones Aug. 22, 2012, 8:17 a.m. UTC | #17
On Tue, Aug 21, 2012 at 05:52:07PM +0100, Mark Brown wrote:
> On Tue, Aug 21, 2012 at 01:02:46PM +0100, Lee Jones wrote:
> > On Tue, Aug 21, 2012 at 12:03:29PM +0100, Mark Brown wrote:
> 
> > > > another way to get hold of the domain, because the only way to obtain
> > > > it without having direct access is via a device node.
> 
> > > This doesn't actually hold.
> 
> > Okay, besides irq_find_host(struct device_node *np), how else can you fetch
> > a domain from the irqdomain?
>
> I'm not sure I can parse the above, sorry - I'm not sure I can
> distinguish "domain" and "irqdomain".

Are you being intentionally awkward on this? Picking holes when you know
exactly what I'm trying to say? Not that it matters now, but just out of
principle, let me try to put it in a very clear way so there can be no
misinterpretation.

I was saying that in order for the MFD core to carry out the hwirq->virq
conversion, it needed to obtain the irqdomain pointer pertaining to the
provided hwirq. The only helper function the irqdomain subsystem provides
requires a device node pointer to be passed as an argument, hence the
mention of 'irq_find_host(struct device_node *np)'. Then the Device Tree
is traversed until a specified 'interrupt-controller' is stumbled upon
or is pointed to by the 'interrupt-parent' property. Hence, we have to 
find another way to find the irqdomain pointers for non-DT based MFDs. To
which we now have a solution.

> > What have you done already? 
> 
> Implemented a patch for this which I've now tested a bit and will
> probably post in the next hour or so.
> 
> > Why make suggestions if you're just going to do the work yourself?
> 
> I made the suggestion then later on realised that this was actively
> going to break things I care about so I actually need it fixing.

I'm a little taken aback and annoyed by this. In a previous email thread
you categorically requested that I discuss some of the important changes
with maintainers and people in-the-know prior to actually writing any
code. I was obviously actively working on, had put time into, and was in
the mist of discussing this with you. Then you just go ahead and code it
(the easy part) yourself, essentially wasting my time. Surely there's
some kind of etiquette surrounding such things?
Mark Brown Aug. 22, 2012, 11:19 a.m. UTC | #18
On Wed, Aug 22, 2012 at 09:17:50AM +0100, Lee Jones wrote:

> I was saying that in order for the MFD core to carry out the hwirq->virq
> conversion, it needed to obtain the irqdomain pointer pertaining to the
> provided hwirq. The only helper function the irqdomain subsystem provides
> requires a device node pointer to be passed as an argument, hence the
> mention of 'irq_find_host(struct device_node *np)'. Then the Device Tree
> is traversed until a specified 'interrupt-controller' is stumbled upon
> or is pointed to by the 'interrupt-parent' property. Hence, we have to 
> find another way to find the irqdomain pointers for non-DT based MFDs. To
> which we now have a solution.

Oh, right.  Yes, there's no way to get an irqdomain if you don't already
have it or something which has a direct mapping to one like an irqdomain.

> > I made the suggestion then later on realised that this was actively
> > going to break things I care about so I actually need it fixing.

> I'm a little taken aback and annoyed by this. In a previous email thread
> you categorically requested that I discuss some of the important changes
> with maintainers and people in-the-know prior to actually writing any
> code.

No, that's not something I've ever said to do.

I *have* asked you to communicate more clearly about what you're doing
but that doesn't mean to stop sending code, it means to have clearer
words around what you're sending.  The really bad pattern here is that
you're frequently working around issues in your drivers with changes in
the subsystem without mentioning that the driver issues even exist -
this makes it much harder understand what you are trying to achieve,
especially when there is a problem with your subsystem changes and/or
the urgency you're attaching to them.

>       I was obviously actively working on, had put time into, and was in
> the mist of discussing this with you. Then you just go ahead and code it
> (the easy part) yourself, essentially wasting my time. Surely there's
> some kind of etiquette surrounding such things?

To be honest in this case I had expected to send the patch out much
sooner than I did - several priority interrupts stopped me testing it.
Like I say I realised that I really needed a fix and it seemed like the
quickest way to accomplish that was to just send the code.
Lee Jones Aug. 22, 2012, 11:55 a.m. UTC | #19
> > > I made the suggestion then later on realised that this was actively
> > > going to break things I care about so I actually need it fixing.
> 
> > I'm a little taken aback and annoyed by this. In a previous email thread
> > you categorically requested that I discuss some of the important changes
> > with maintainers and people in-the-know prior to actually writing any
> > code.
> 
> No, that's not something I've ever said to do.
> 
> I *have* asked you to communicate more clearly about what you're doing
> but that doesn't mean to stop sending code, it means to have clearer
> words around what you're sending. 

That's not how I interpreted your words:

"What you can do here is to commmunicate about what you're doing more.
Don't just think about the code, think about the communication
surrounding the code - this is the core of the issue."

> The really bad pattern here is that
> you're frequently working around issues in your drivers with changes in
> the subsystem without mentioning that the driver issues even exist -
> this makes it much harder understand what you are trying to achieve,
> especially when there is a problem with your subsystem changes and/or
> the urgency you're attaching to them.

Frequently? I've done this once, and yes I did push hard because I
thought the subsystem was incorrect (I still think folding an entire
driver because of a minor failure is wrong, but we digress).

This is completely different to that. This was a subsystem change
designed to aid DT enabled MFDs which 'chose' to register themselves
in a specific way, by passing their compatible string through the 
mfd_cell only. It doesn't affect any other MFD unless they wrongly
assume the conversion would be automatically done for them. However,
the author would know because they would have tested it. All of this
was discussed at length with Arnd and this is what we came up with. 

I think it's great that you like the idea and want to extend that
functionality to other MFDs which perhaps don't support DT, or the
ones that do but don't want to provide compatible strings or device
nodes for all the MFD's child devices. But that is all we're doing
here. There was no breakage. It served a purpose and it worked well.
So well in fact that you've now provided the intended functionality
to other devices.

> >       I was obviously actively working on, had put time into, and was in
> > the mist of discussing this with you. Then you just go ahead and code it
> > (the easy part) yourself, essentially wasting my time. Surely there's
> > some kind of etiquette surrounding such things?
> 
> To be honest in this case I had expected to send the patch out much
> sooner than I did - several priority interrupts stopped me testing it.
> Like I say I realised that I really needed a fix and it seemed like the
> quickest way to accomplish that was to just send the code.

You only noticed it 2 days ago and I had a patch ready to go yesterday.
I'm confused because I don't understand why would you even complain about
it if you intended to work on it yourself? Surely, "Ah, I see an issue with
xyz, patch to follow." Would have been more appropriate, instead of 
complaining about it, then I go and waste my time trying to fix something
you intend on fixing yourself.

I guess what's done is done now.
Mark Brown Aug. 22, 2012, 3:48 p.m. UTC | #20
On Wed, Aug 22, 2012 at 12:55:25PM +0100, Lee Jones wrote:

> > I *have* asked you to communicate more clearly about what you're doing
> > but that doesn't mean to stop sending code, it means to have clearer
> > words around what you're sending. 

> That's not how I interpreted your words:

> "What you can do here is to commmunicate about what you're doing more.
> Don't just think about the code, think about the communication
> surrounding the code - this is the core of the issue."

Just to be clear I'd include things like commit messages, cover letters
and so on in the general area of communication.

> I think it's great that you like the idea and want to extend that
> functionality to other MFDs which perhaps don't support DT, or the
> ones that do but don't want to provide compatible strings or device
> nodes for all the MFD's child devices. But that is all we're doing
> here. There was no breakage. It served a purpose and it worked well.
> So well in fact that you've now provided the intended functionality
> to other devices.

I'm looking at this from the point of view of adding the compatible
strings and then finding that the core starts remapping things in the
case where you're probing from DT - and this behaviour will vary
depending on the device tree that the user is using so the driver can't
even make a decision based on if device tree is being used by the
system.

> You only noticed it 2 days ago and I had a patch ready to go yesterday.
> I'm confused because I don't understand why would you even complain about
> it if you intended to work on it yourself? Surely, "Ah, I see an issue with
> xyz, patch to follow." Would have been more appropriate, instead of 
> complaining about it, then I go and waste my time trying to fix something
> you intend on fixing yourself.

I didn't originally intend to do anything, if I had done I'd just have
sent a patch as you say.  Originally I'd just noticed it as being an
awkwardly designed interface at the wrong abstraction layer, it was only
later on that I realised how it could blow up.
diff mbox

Patch

diff --git a/drivers/mfd/db8500-prcmu.c b/drivers/mfd/db8500-prcmu.c
index 7040a00..9899b3f 100644
--- a/drivers/mfd/db8500-prcmu.c
+++ b/drivers/mfd/db8500-prcmu.c
@@ -270,6 +270,8 @@  static struct {
 	struct prcmu_fw_version version;
 } fw_info;
 
+static struct irq_domain *db8500_irq_domain;
+
 /*
  * This vector maps irq numbers to the bits in the bit field used in
  * communication with the PRCMU firmware.
@@ -2583,7 +2585,7 @@  static void prcmu_irq_mask(struct irq_data *d)
 
 	spin_lock_irqsave(&mb0_transfer.dbb_irqs_lock, flags);
 
-	mb0_transfer.req.dbb_irqs &= ~prcmu_irq_bit[d->irq - IRQ_PRCMU_BASE];
+	mb0_transfer.req.dbb_irqs &= ~prcmu_irq_bit[d->hwirq];
 
 	spin_unlock_irqrestore(&mb0_transfer.dbb_irqs_lock, flags);
 
@@ -2597,7 +2599,7 @@  static void prcmu_irq_unmask(struct irq_data *d)
 
 	spin_lock_irqsave(&mb0_transfer.dbb_irqs_lock, flags);
 
-	mb0_transfer.req.dbb_irqs |= prcmu_irq_bit[d->irq - IRQ_PRCMU_BASE];
+	mb0_transfer.req.dbb_irqs |= prcmu_irq_bit[d->hwirq];
 
 	spin_unlock_irqrestore(&mb0_transfer.dbb_irqs_lock, flags);
 
@@ -2637,9 +2639,43 @@  static char *fw_project_name(u8 project)
 	}
 }
 
+int db8500_irq_get_virq(int irq)
+{
+	return irq_create_mapping(db8500_irq_domain, irq);
+}
+EXPORT_SYMBOL_GPL(db8500_irq_get_virq);
+
+static int db8500_irq_map(struct irq_domain *d, unsigned int virq,
+				irq_hw_number_t hwirq)
+{
+	irq_set_chip_and_handler(virq, &prcmu_irq_chip,
+				handle_simple_irq);
+	set_irq_flags(virq, IRQF_VALID);
+
+	return 0;
+}
+
+static struct irq_domain_ops db8500_irq_ops = {
+        .map    = db8500_irq_map,
+        .xlate  = irq_domain_xlate_twocell,
+};
+
+static int db8500_irq_init(struct device_node *np)
+{
+	db8500_irq_domain = irq_domain_add_legacy(
+		np, NUM_PRCMU_WAKEUPS, IRQ_PRCMU_BASE,
+		0, &db8500_irq_ops, NULL);
+
+	if (!db8500_irq_domain) {
+		pr_err("Failed to create irqdomain\n");
+		return -ENOSYS;
+	}
+
+	return 0;
+}
+
 void __init db8500_prcmu_early_init(void)
 {
-	unsigned int i;
 	if (cpu_is_u8500v2()) {
 		void *tcpm_base = ioremap_nocache(U8500_PRCMU_TCPM_BASE, SZ_4K);
 
@@ -2683,16 +2719,6 @@  void __init db8500_prcmu_early_init(void)
 	init_completion(&mb5_transfer.work);
 
 	INIT_WORK(&mb0_transfer.mask_work, prcmu_mask_work);
-
-	/* Initalize irqs. */
-	for (i = 0; i < NUM_PRCMU_WAKEUPS; i++) {
-		unsigned int irq;
-
-		irq = IRQ_PRCMU_BASE + i;
-		irq_set_chip_and_handler(irq, &prcmu_irq_chip,
-					 handle_simple_irq);
-		set_irq_flags(irq, IRQF_VALID);
-	}
 }
 
 static void __init init_prcm_registers(void)
@@ -2999,6 +3025,8 @@  static int __devinit db8500_prcmu_probe(struct platform_device *pdev)
 		goto no_irq_return;
 	}
 
+	db8500_irq_init(np);
+
 	for (i = 0; i < ARRAY_SIZE(db8500_prcmu_devs); i++) {
 		if (!strcmp(db8500_prcmu_devs[i].name, "ab8500-core")) {
 			db8500_prcmu_devs[i].platform_data = ab8500_platdata;
diff --git a/include/linux/mfd/db8500-prcmu.h b/include/linux/mfd/db8500-prcmu.h
index b82f6ee..38494d9 100644
--- a/include/linux/mfd/db8500-prcmu.h
+++ b/include/linux/mfd/db8500-prcmu.h
@@ -571,6 +571,8 @@  u32 db8500_prcmu_read(unsigned int reg);
 void db8500_prcmu_write(unsigned int reg, u32 value);
 void db8500_prcmu_write_masked(unsigned int reg, u32 mask, u32 value);
 
+int db8500_irq_get_virq(int irq);
+
 #else /* !CONFIG_MFD_DB8500_PRCMU */
 
 static inline void db8500_prcmu_early_init(void) {}