Thread (23 messages) 23 messages, 4 authors, 2020-07-29

Re: [PATCH 4/7] gpio: dwapb: Convert driver to using the GPIO-lib-based IRQ-chip

From: Andy Shevchenko <hidden>
Date: 2020-07-25 12:13:10
Also in: linux-gpio, lkml

On Sat, Jul 25, 2020 at 2:03 AM Serge Semin
[off-list ref] wrote:
On Thu, Jul 23, 2020 at 01:03:17PM +0300, Andy Shevchenko wrote:
quoted
On Thu, Jul 23, 2020 at 04:38:55AM +0300, Serge Semin wrote:
...
quoted
quoted
5) Manually select a proper IRQ flow handler directly in the
irq_set_type() callback by calling irq_set_handler_locked() method, since
an ordinary (not Generic) irq_chip descriptor is now utilized.
quoted
Can you also emphasize that this make no regression to the 6a2f4b7dadd5 ("gpio:
dwapb: use a second irq chip")?
In fact I don't really see why that commit had been accepted in the first place.
Both level and edge triggered IRQ types are implemented by means of the same
callbacks and the same registers. The only handy thing in our case is the IRQ
flow handler setting in accordance with the requested IRQ type, but that
could be done by just calling irq_set_handler_locked() method without two-types
complication. The commit log says: "So we can have at runtime two users where
one is using edge and the other level." which isn't really correct since if an IRQ
line is shared it can only be requested with the same trigger flags (see the
inline comments in the __setup_irq() method definition). If an IRQ line isn't
shared, then there can't be more than one user.

Am I missing something?
I didn't investigate myself, but probably it's a history of changes
you are missing.
That said, in time when the above mentioned commit was made there was
no clear approach like we have nowadays.
But I might be mistaken.
In any case, just add a (small) remark that you were aware of that
change and do not see any problems while doing yours.
quoted
(And I hope you have means to test that scenario, because in my case I have
 only one IRQ and it's actually as input from other GPIO IRQ chip).
Alas I have DW APB GPIO with a single IRQ line attached too, so I can't test the
hierarchical case, but only the cascaded one.
Alas.

...
quoted
I like the idea, but is it possible to split this?
Yeah, 6) and 7) could be unpinned to dedicated patches. Thanks for noticing
this. I'll do that. But leaving the changes described before and not applying 8)
will produce buildable but not working driver. So I'd prefer to leave 8) here.
I see. Yes, we have to have compile time *and* run-time bisectability in place.

...
quoted
quoted
+           /*
+            * If more than one IRQ line is specified then try to
+            * initialize the hierarchical interrupts. Otherwise it's
+            * a simple cascaded case with a common IRQ signal.
+            */
+           girq->num_parents = pp->irq[1] ? pp->ngpio : 1;
quoted
Can it be sparse in the array? (It's actually the main point why I went with
memchr_inv() instead of doing something like above)
According to the DW APB GPIO databook it can be configured to provide either a
combined IRQ line or multiple interrupt signals for each GPIO. It's up to
the platform which of those signals are connected to an embedded IRQ
controller. So I guess theoretically the array values can be sparse.

Anyway now I see it's rather problematic. I didn't forget about the sparse IRQs
array case. I just thought it would work out-of-box. Before getting your comment
and digging deeper into the IRQ subsystem I had thought that it wasn't a problem
passing invalid IRQ numbers to the irq_set_chained_handler_and_data() especially
seeing zero IRQ number was supposed to be considered as invalid. That method shall
just ignore the invalid IRQs since the method irq_to_desc() calling radix_tree_lookup()
will fail to find a descriptor with invalid IRQ value and return NULL. So after
getting a NULL irq_desc the method irq_set_chained_handler_and_data() would
have stopped setting the handler. But turns out it may work only for
CONFIG_SPARSE_IRQ. If that config isn't enabled, then a very first IRQ
descriptor will be returned for zero IRQ number. That descriptor will be
initialized with the passed parent_handler callback, which isn't what we want.

So in order to fix the problem we could follow either of the next paths:
1) Just make sure the passed IRQs array is not sparse for instance by remapping
   it to be linear.
2) Move "if (gc->irq.parents[i]) irq_set_chained_handler_and_data()" statement to the
   gpiochip_add_irqchip() method.

What to you think? Linus?
I am okay with either that Linus will like.

...
quoted
quoted
+           /* This will let us handle the parent IRQ in the driver */
+           girq->parents = NULL;
+           girq->num_parents = 0;
+           girq->parent_handler = NULL;
quoted
Shan't we do this before request_irq() call (at least for consistency with the
rest of the drivers)?
Technically we shan't. Please elaborate which drivers you are referring to?
All of them? Recent patches for IRQ chip template do something like

girq = &...;
girq->foo = bar;
...
ret = request_irq(...);

...and here no more girq->baz = gaz; lines.
Even the recent Linus' series "Use irqchip template" mostly does it in the
same order.
Funny, that's what I;m referring to.

-- 
With Best Regards,
Andy Shevchenko
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help