[PATCH v2] irqchip: Add IRQCHIP_PLATFORM_DRIVER_BEGIN/END and IRQCHIP_MATCH helper macros
Marc Zyngier
maz at kernel.org
Fri Jul 17 14:04:15 EDT 2020
On 2020-07-17 18:50, Saravana Kannan wrote:
> On Fri, Jul 17, 2020 at 3:49 AM Marc Zyngier <maz at kernel.org> wrote:
>>
>> Hi Saravana,
>>
>> Thanks for re-spinning this one.
>>
>> On Fri, 17 Jul 2020 03:44:47 +0100,
>> Saravana Kannan <saravanak at google.com> wrote:
>> >
>> > Compiling an irqchip driver as a platform driver needs to bunch of
>> > things to be done right:
>> > - Making sure the parent domain is initialized first
>> > - Making sure the device can't be unbound from sysfs
>> > - Disallowing module unload if it's built as a module
>> > - Finding the parent node
>> > - Etc.
>> >
>> > Instead of trying to make sure all future irqchip platform drivers get
>> > this right, provide boilerplate macros that take care of all of this.
>> >
>> > An example use would look something like this. Where acme_foo_init and
>> > acme_bar_init are similar to what would be passed to IRQCHIP_DECLARE.
>> >
>> > IRQCHIP_PLATFORM_DRIVER_BEGIN
>>
>> I think there is some value in having the BEGIN statement containing
>> the driver name, see below.
>>
>> > IRQCHIP_MATCH(foo, "acme,foo", acme_foo_init)
>> > IRQCHIP_MATCH(bar, "acme,bar", acme_bar_init)
>> > IRQCHIP_PLATFORM_DRIVER_END(acme_irq)
>> >
>> > Signed-off-by: Saravana Kannan <saravanak at google.com>
>> > ---
>> > drivers/irqchip/irqchip.c | 22 ++++++++++++++++++++++
>> > include/linux/irqchip.h | 23 +++++++++++++++++++++++
>> > 2 files changed, 45 insertions(+)
>> >
>> > diff --git a/drivers/irqchip/irqchip.c b/drivers/irqchip/irqchip.c
>> > index 2b35e68bea82..236ea793f01c 100644
>> > --- a/drivers/irqchip/irqchip.c
>> > +++ b/drivers/irqchip/irqchip.c
>> > @@ -10,8 +10,10 @@
>> >
>> > #include <linux/acpi.h>
>> > #include <linux/init.h>
>> > +#include <linux/of_device.h>
>> > #include <linux/of_irq.h>
>> > #include <linux/irqchip.h>
>> > +#include <linux/platform_device.h>
>> >
>> > /*
>> > * This special of_device_id is the sentinel at the end of the
>> > @@ -29,3 +31,23 @@ void __init irqchip_init(void)
>> > of_irq_init(__irqchip_of_table);
>> > acpi_probe_device_table(irqchip);
>> > }
>> > +
>> > +int platform_irqchip_probe(struct platform_device *pdev)
>> > +{
>> > + struct device_node *np = pdev->dev.of_node;
>> > + struct device_node *par_np = of_irq_find_parent(np);
>> > + of_irq_init_cb_t irq_init_cb = of_device_get_match_data(&pdev->dev);
>> > +
>> > + if (!irq_init_cb)
>> > + return -EINVAL;
>> > +
>> > + if (par_np == np)
>> > + par_np = NULL;
>> > +
>> > + /* If there's a parent irqchip, make sure it has been initialized. */
>> > + if (par_np && !irq_find_matching_host(np, DOMAIN_BUS_ANY))
>>
>> There is no guarantee that the calling driver wants BUS_ANY as a token
>> for its parent. It may work for now, if you only have dependencies to
>> drivers that only expose a single domain, but that's not a general
>> purpose check..
>>
>> At least, please add a comment saying that the new driver may want to
>> check that the irqdomain it depends on may not be available.
>
> This is just checking if the parent interrupt controller has been
> initialized. It's just saying that if NONE of the parent irq domains
> have been registered, it's not time for this interrupt controller to
> initialize. And yes, as you said, the actual init code can do more
> checks and defer probe too. Maybe I'll just put the 2nd sentence as
> the comment.
Sure, go ahead.
>
>>
>> > + return -EPROBE_DEFER;
>> > +
>> > + return irq_init_cb(np, par_np);
>> > +}
>> > +EXPORT_SYMBOL_GPL(platform_irqchip_probe);
>> > diff --git a/include/linux/irqchip.h b/include/linux/irqchip.h
>> > index 950e4b2458f0..6d5eba7cbbb7 100644
>> > --- a/include/linux/irqchip.h
>> > +++ b/include/linux/irqchip.h
>> > @@ -13,6 +13,7 @@
>> >
>> > #include <linux/acpi.h>
>> > #include <linux/of.h>
>> > +#include <linux/platform_device.h>
>> >
>> > /*
>> > * This macro must be used by the different irqchip drivers to declare
>> > @@ -26,6 +27,28 @@
>> > */
>> > #define IRQCHIP_DECLARE(name, compat, fn) OF_DECLARE_2(irqchip, name, compat, fn)
>> >
>> > +extern int platform_irqchip_probe(struct platform_device *pdev);
>> > +
>> > +#define IRQCHIP_PLATFORM_DRIVER_BEGIN \
>> > +static const struct of_device_id __irqchip_match_table[] = {
>>
>> How about:
>>
>> #define IRQCHIP_PLATFORM_DRIVER_BEGIN(drv_name) \
>> static const struct of_device_id __irqchip_match_table_##drv_name = {
>>
>> which makes it easier to debug when you want to identify specific
>> structures in an object (otherwise, they all have the same
>> name...). it is also much more pleasing aesthetically ;-).
>
> I totally agree. I wanted BEGIN to have the name and END to not have
> to specify the name. But I couldn't figure out a way to do it. I
> assumed you wouldn't want the names repeated in both BEGIN and END. If
> you are okay with that, I prefer your suggestion too.
I'm perfectly fine having the name in both the BEGIN and END tags.
It has a nice LaTeX twist to it ;-).
>
>> > +
>> > +#define IRQCHIP_MATCH(compat, fn) { .compatible = compat, .data = fn },
>> > +
>> > +#define IRQCHIP_PLATFORM_DRIVER_END(drv_name) \
>> > + {}, \
>> > +}; \
>> > +MODULE_DEVICE_TABLE(of, __irqchip_match_table); \
>> > +static struct platform_driver drv_name##_driver = { \
>>
>> const?
>
> Sure.
>
>> > + .probe = platform_irqchip_probe, \
>> > + .driver = { \
>> > + .name = #drv_name, \
>> > + .owner = THIS_MODULE, \
>> > + .of_match_table = __irqchip_match_table,\
>> > + .suppress_bind_attrs = true, \
>> > + }, \
>> > +}; \
>> > +builtin_platform_driver(drv_name##_driver)
>> > +
>> > /*
>> > * This macro must be used by the different irqchip drivers to declare
>> > * the association between their version and their initialization function.
>> > --
>> > 2.28.0.rc0.105.gf9edc3c819-goog
>> >
>> >
>>
>> Otherwise looks good. When you respin it, it would be good to also
>> submit one user of this API by converting an existing driver, as I'd
>> hate to merge something that has no user.
>
> The only one I know will work is the qcom pdc one from John. So I was
> hoping John would respin his patch if you accept this one or I was
> going to redo it after it shows up on linux-next. Maybe MTK can use
> this too for their other series?
I have queued John's PDC work in irq/irqchip-5.9, which I will get
into -next over the weekend. Feel free to post a patch reworking
his last patch, which will give a very nice overview of what we gain.
Thanks,
M.
--
Jazz is not dead. It just smells funny...
More information about the Linux-mediatek
mailing list