[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <fea1e962-1af2-d666-2b0d-55a8e230430c@imgtec.com>
Date: Tue, 1 Nov 2016 11:05:43 +0000
From: Zubair Lutfullah Kakakhel <Zubair.Kakakhel@...tec.com>
To: Thomas Gleixner <tglx@...utronix.de>
CC: <monstr@...str.eu>, <jason@...edaemon.net>, <marc.zyngier@....com>,
<linux-kernel@...r.kernel.org>, <michal.simek@...inx.com>,
<linuxppc-dev@...ts.ozlabs.org>, <mpe@...erman.id.au>
Subject: Re: [Patch V6 2/6] irqchip: xilinx: Clean up irqdomain argument and
read/write
Hi,
Thanks for the review.
On 10/31/2016 07:51 PM, Thomas Gleixner wrote:
> On Mon, 31 Oct 2016, Zubair Lutfullah Kakakhel wrote:
>> The drivers read/write function handling is a bit quirky.
>
> Can you please explain in more detail what's quirky and why it should be
> done differently,
>
>> And the irqmask is passed directly to the handler.
>
> I can't make any sense out of that sentence. Which handler? If you talk
> about the write function, then I don't see a change. So what are you
> talking about?
Thanks. I'll add more detail in v7 if this patch survives.
>
>> Add a new irqchip struct to pass to the handler and
>> cleanup read/write handling.
>
> I still don't see what it cleans up. You move the write function pointer
> into a data structure, which is exposed by another pointer. So you create
> two levels of indirection in the hotpath. The function prototype is still
> the same. So all this does is making things slower unless I'm missing
> something.
I wrote this patch/cleanup based on a review of driver by Marc when I moved the
driver from arch/microblaze to drivers/irqchip
"Marc Zyngier
...
> arch/microblaze/kernel/intc.c | 196 ----------------------------------------
> drivers/irqchip/irq-axi-intc.c | 196 ++++++++++++++++++++++++++++++++++++++++
...
> + /* Yeah, okay, casting the intr_mask to a void* is butt-ugly, but I'm
> + * lazy and Michal can clean it up to something nicer when he tests
> + * and commits this patch. ~~gcl */
> + root_domain = irq_domain_add_linear(intc, nr_irq, &xintc_irq_domain_ops,
> + (void *)intr_mask);
Since you're now reworking this driver, how about addressing this
ugliness? You could store the intr_mask together with intc_baseaddr,
and the read/write functions in a global structure, and pass a
pointer to it? That would make the code a bit nicer...
"
https://patchwork.kernel.org/patch/9287933/
>
>> -static unsigned int (*read_fn)(void __iomem *);
>> -static void (*write_fn)(u32, void __iomem *);
>> +struct xintc_irq_chip {
>> + void __iomem *base;
>> + struct irq_domain *domain;
>> + struct irq_chip chip;
>
> The tabs between struct and the structure name are bogus.
>
>> + u32 intr_mask;
>> + unsigned int (*read)(void __iomem *iomem);
>> + void (*write)(u32 data, void __iomem *iomem);
>
> Please structure that like a table:
>
> void __iomem *base;
> struct irq_domain *domain;
> struct irq_chip chip;
> u32 intr_mask;
> unsigned int (*read)(void __iomem *iomem);
> void (*write)(u32 data, void __iomem *iomem);
>
> Can you see how that makes parsing the struct simpler, because the data
> types are clearly to identify?
That does make it look much better.
>
>> +static struct xintc_irq_chip *xintc_irqc;
>>
>> static void intc_write32(u32 val, void __iomem *addr)
>> {
>> @@ -54,6 +60,18 @@ static unsigned int intc_read32_be(void __iomem *addr)
>> return ioread32be(addr);
>> }
>>
>> +static inline unsigned int xintc_read(struct xintc_irq_chip *xintc_irqc,
>> + int reg)
>> +{
>> + return xintc_irqc->read(xintc_irqc->base + reg);
>> +}
>> +
>> +static inline void xintc_write(struct xintc_irq_chip *xintc_irqc,
>> + int reg, u32 data)
>> +{
>> + xintc_irqc->write(data, xintc_irqc->base + reg);
>> +}
>> +
>> static void intc_enable_or_unmask(struct irq_data *d)
>> {
>> unsigned long mask = 1 << d->hwirq;
>> @@ -65,21 +83,21 @@ static void intc_enable_or_unmask(struct irq_data *d)
>> * acks the irq before calling the interrupt handler
>> */
>> if (irqd_is_level_type(d))
>> - write_fn(mask, intc_baseaddr + IAR);
>> + xintc_write(xintc_irqc, IAR, mask);
>
> So this whole thing makes only sense, when you want to support multiple
> instances of that chip and then you need to store the xintc_irqc pointer as
> irqchip data and retrieve it from there. Unless you do that, this "cleanup"
> is just churn for nothing with the effect of making things less efficient.
>
Indeed the driver doesn't support multiple instances of the Xilinx Interrupt controller.
I don't have a use-case or the hardware for that.
So what would be the recommended course of action?
Regards,
ZubairLK
> Thanks,
>
> tglx
>
Powered by blists - more mailing lists