Re: [PATCH 4/7] gpio: dwapb: Convert driver to using the GPIO-lib-based IRQ-chip
From: Serge Semin <hidden>
Date: 2020-07-29 16:07:08
Also in:
linux-gpio, lkml
On Wed, Jul 29, 2020 at 06:10:24PM +0300, Andy Shevchenko wrote:
On Wed, Jul 29, 2020 at 3:58 PM Serge Semin [off-list ref] wrote:quoted
On Mon, Jul 27, 2020 at 12:22:28AM +0200, Linus Walleij wrote:...quoted
Sorry for a delay with a response to this issue. I had to give it a more thorough thought since the problem is a bit more complex than it seemed originally. As I see it now It might be wrong to implement the cases 2) and 3), but 1) is more appropriate. First of all we need to note that GPIOlib framework provides the next parameters to describe the IRQ-chip: gc->irq.num_parents - number of parental IRQ numbers. gc->irq.parents[] - array of parental IRQ numbers. *gc->irq.valid_mask - a mask of IRQ/GPIO lines describing a valid IRQ. *gc->irq.map - mapping of hw IRQ/GPIO ID -> parental IRQ numbers. Using that set we can handle any case of linear and sparse parental IRQs. Here is how it can be implemented in the framework of DW APB GPIO controller. DW APB GPIO can be synthesized with two configs: 1) Combined IRQ line (GPIO_INTR_IO == True), 2) Multiple interrupt signals for each GPIO (GPIO_INTR_IO == False). Obviously the former case is trivial: IRQ_combined ______^________ /_ _ _ _ _ ___ _\ |_|_|_|_|_|...|_| - GPIOs In that case gc->irq.num_parents = 1; gc->irq.parents[0] = IRQ_combined; *gc->irq.valid_mask = GENMASK(ngpio - 1, 0); // This is done by the GPIOlib core itself. The later one (when multiple interrupt signals are involved) can be a bit more complicated. It can be also split up into two cases: 2a) One-on-one GPIO-IRQ mapping. 2b) Sparse GPIO-IRQ mapping. It's straightforward to implement 2a): i1i2i3i4i5 ... iN _ _ _ _ _ ___ _ |_|_|_|_|_|...|_| - GPIOs
quoted
In that case gc->irq.num_parents = ngpio; gc->irq.parents[] = {i1, i2, i3, i4, i5, ... iN}; gc->irq.map = {i1, i2, i3, i4, i5, ... iN}; *gc->irq.valid_mask = GENMASK(ngpio - 1, 0);This case puzzles me. Why is it not NULL and 0 and actually you handle everything as a nested case?
The code provided above is a sketch. Don't consider it literally. In reality of course valid_mask will be not NULL, memory for which will be allocated by the GPIOlib itself. The mask will be initialized by means of the gc->irq.init_valid_mask() callback.
quoted
The complication starts when we get to implementing 2b): i1 xi3i4 x ... iN _ _ _ _ _ ___ _ |_|_|_|_|_|...|_| - GPIOsSo does this. Valid mask will define exactly GPIOs that are IRQs. So, we will handle only nested IRQs which are valid.
Right.
quoted
In order to cover this case we need to answer on two question. Firstly how to get such platform config? I am not sure about ACPI, but aside from straightforward platform_data-based setup such configuration can be reached by setting up the "interrupts-extended" DT-property with zeroed phandle. Ok, since it's possible to meet such platform config, we need to think how to handle it and here is the second question. How to describe such case in the framework of GPIOlib-IRQchip? So from my side it was wrong to set the sparse IRQs array to gc->irq.parents. Instead I should have scanned the sparse IRQs array, calculated the number of non-empty parental IRQs, created an array of linear (non-sparse) IRQs, initialized *gc->irq.valid_mask in accordance with the sparse parental IRQs array. In other words it was wrong to assume, that each gc->irq.parents entry corresponds to the IRQ/GPIO line. The gc->irq.parents array just describes the parental IRQs and nothing else. Shortly speaking here is how the GPIOlib IRQchip parameters should be initialized in this case: gc->irq.num_parents - number of valid parental IRQs. gc->irq.parents - non-sparse, linear array of valid IRQs. *gc->irq.valid_mask - mask initialized by means of the gc->irq.init_valid_mask() callback, which indicates valid IRQ/GPIO IDs. *gc->irq.map - sparse array of parental IRQ numbers (which I mistakenly tried to pass through the gc->irq.parents pointer). After that GPIOlib IRQchip should work just fine without need to be patched in order to check whether the passed parental IRQs are valid or not. Please correct me if I am wrong in some aspects of the solution described above. I'll send a fix of the problem shortly.
Maybe I'm missing something, but looks like you are solving the issue which is not so complex / doesn't exist.
As I see it now the problem was to provide a suitable config for GPIO-lib IRQ-chip so one would correctly perceive our DW APB GPIO-IRQ setup with single/sparse/linear IRQs. My point in the message before was to explain how that problem could be solved without patching GPIO-lib or IRQ-chip implementations. I shared my thoughts to make sure the suggested solution is correct, to make sure I didn't miss something in my considerations. -Sergey
-- With Best Regards, Andy Shevchenko