Hi Simon, On Sun, Dec 22, 2019 at 2:16 AM Simon Glass <s...@chromium.org> wrote: > > There can be different types of interrupt controllers in a system and some > drivers may need to distinguish between these. In general this can be > handled using the device tree by adding the interrupt information to > device nodes. > > However on x86 devices we have interrupt controllers which are not tied > to any particular device and not really used in U-Boot. These still need > to be inited, so a convenient method is to give each controller a type > and allow a particular controller type to be probed. > > Add support for this in sandbox along with a test. > > Signed-off-by: Simon Glass <s...@chromium.org> > --- > > Changes in v2: None > > arch/sandbox/include/asm/test.h | 4 ++++ > drivers/misc/irq-uclass.c | 24 +++++++++++++++++++++++- > drivers/misc/irq_sandbox.c | 2 +- > include/irq.h | 21 +++++++++++++++++++++ > test/dm/irq.c | 14 ++++++++++++++ > 5 files changed, 63 insertions(+), 2 deletions(-) > > diff --git a/arch/sandbox/include/asm/test.h b/arch/sandbox/include/asm/test.h > index fdb0ecfed1..0a11dfeefb 100644 > --- a/arch/sandbox/include/asm/test.h > +++ b/arch/sandbox/include/asm/test.h > @@ -45,6 +45,10 @@ > #define PCI_EA_BAR2_MAGIC 0x72727272 > #define PCI_EA_BAR4_MAGIC 0x74747474 > > +enum { > + SANDBOX_IRQN_PEND = 1, /* Interrupt number for 'pending' test */ > +}; > + > /* System controller driver data */ > enum { > SYSCON0 = 32, > diff --git a/drivers/misc/irq-uclass.c b/drivers/misc/irq-uclass.c > index d5182cf149..38498a66a4 100644 > --- a/drivers/misc/irq-uclass.c > +++ b/drivers/misc/irq-uclass.c > @@ -1,11 +1,13 @@ > // SPDX-License-Identifier: GPL-2.0+ > /* > - * Copyright (C) 2015, Bin Meng <bmeng...@gmail.com> > + * Copyright 2019 Google, LLC > + * Written by Simon Glass <s...@chromium.org> > */ > > #include <common.h> > #include <dm.h> > #include <irq.h> > +#include <dm/device-internal.h> > > int irq_route_pmc_gpio_gpe(struct udevice *dev, uint pmc_gpe_num) > { > @@ -47,6 +49,26 @@ int irq_restore_polarities(struct udevice *dev) > return ops->restore_polarities(dev); > } > > +int irq_first_device_type(enum irq_dev_t type, struct udevice **devp) > +{ > + struct udevice *dev; > + struct uclass *uc; > + int ret; > + > + ret = uclass_get(UCLASS_IRQ, &uc); > + if (ret) > + return ret; > + uclass_foreach_dev(dev, uc) { > + if (dev_get_driver_data(dev) == type) { > + *devp = dev; > + > + return device_probe(dev);
The logic is generic and should not be limited to IRQ uclass. Maybe we should put this API in DM core, and name it as something like uclass_first_device_drvdata()? > + } > + } > + > + return -ENODEV; > +} > + > UCLASS_DRIVER(irq) = { > .id = UCLASS_IRQ, > .name = "irq", > diff --git a/drivers/misc/irq_sandbox.c b/drivers/misc/irq_sandbox.c > index 6dda1a4c44..011022ac62 100644 > --- a/drivers/misc/irq_sandbox.c > +++ b/drivers/misc/irq_sandbox.c > @@ -43,7 +43,7 @@ static const struct irq_ops sandbox_irq_ops = { > }; > > static const struct udevice_id sandbox_irq_ids[] = { > - { .compatible = "sandbox,irq"}, > + { .compatible = "sandbox,irq", SANDBOX_IRQT_BASE }, > { } > }; > > diff --git a/include/irq.h b/include/irq.h > index 01ded64f16..1db97b5c3f 100644 > --- a/include/irq.h > +++ b/include/irq.h > @@ -8,6 +8,17 @@ > #ifndef __irq_H > #define __irq_H > > +/* > + * Interrupt controller types available. You can find a particular one with > + * irq_first_device_type() > + */ > +enum irq_dev_t { > + X86_IRQT_BASE, /* Base controller */ > + X86_IRQT_ITSS, /* ITSS controller, e.g. on APL */ > + X86_IRQT_ACPI_GPE, /* ACPI General-Purpose Events controller */ > + SANDBOX_IRQT_BASE, /* Sandbox testing */ > +}; > + > /** > * struct irq_ops - Operations for the IRQ > */ > @@ -85,4 +96,14 @@ int irq_snapshot_polarities(struct udevice *dev); > */ > int irq_restore_polarities(struct udevice *dev); > > +/** > + * irq_first_device_type() - Get a particular interrupt controller > + * > + * @type: Type to find > + * @devp: Returns the device, if found > + * @return 0 if OK, -ENODEV if not found, other -ve error if uclass failed to > + * probe > + */ > +int irq_first_device_type(enum irq_dev_t type, struct udevice **devp); > + > #endif > diff --git a/test/dm/irq.c b/test/dm/irq.c > index 726189c59f..0f23f108a7 100644 > --- a/test/dm/irq.c > +++ b/test/dm/irq.c > @@ -8,6 +8,7 @@ > #include <common.h> > #include <dm.h> > #include <irq.h> > +#include <asm/test.h> > #include <dm/test.h> > #include <test/ut.h> > > @@ -30,3 +31,16 @@ static int dm_test_irq_base(struct unit_test_state *uts) > return 0; > } > DM_TEST(dm_test_irq_base, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); > + > +/* Test of irq_first_device_type() */ > +static int dm_test_irq_type(struct unit_test_state *uts) > +{ > + struct udevice *dev; > + > + ut_assertok(irq_first_device_type(SANDBOX_IRQT_BASE, &dev)); > + ut_asserteq(-ENODEV, irq_first_device_type(X86_IRQT_BASE, &dev)); > + > + return 0; > +} > +DM_TEST(dm_test_irq_type, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); > + > -- Regards, Bin