mbox series

[v3,0/4] synquacer: implement ACPI gpio/interrupt support

Message ID 20190527112720.2266-1-ard.biesheuvel@linaro.org
Headers show
Series synquacer: implement ACPI gpio/interrupt support | expand

Message

Ard Biesheuvel May 27, 2019, 11:27 a.m. UTC
Wire up the existing GPIO and interrupt controller drivers to the ACPI
subsystem so they can be used on ACPI systems for ACPI event (power
button, hardware error notification etc)

Changes since v2:
- use helper to create hierarchical IRQ domains under ACPI instead of exposing
  the GSI domain's irqdomain pointer directly (#1)
- use has_acpi_companion() instead of ACPI_COMPANION() where possible (#4)
- add Mika's ack to #4

Changes since v1:
- Describe the EXIU controller as a separate device, which is a more accurate
  depiction of reality, and untangles the code a bit as well. Note that this
  requires the GPIO AML device to describe the EXIU interrupts explicitly.
- Add a patch to obtain the ACPI GSI irqdomain. The EXIU driver needs this
  to obtain the default parent domain, since the GIC is not modeled as an
  ACPI object in the namespace, and so the parent<->child link cannot be
  expressed in AML.
- Drop the Kconfig symbol for the GPIO controller. Just include the ACPI part
  when CONFIG_ACPI is defined.

Cc: Masahisa Kojima <masahisa.kojima@linaro.org>
Cc: Linus Walleij <linus.walleij@linaro.org>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Graeme Gregory <graeme.gregory@linaro.org>
Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: Mika Westerberg <mika.westerberg@linux.intel.com>
Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>
Cc: Len Brown <lenb@kernel.org>

Ard Biesheuvel (4):
  acpi/irq: implement helper to create hierachical domains
  irqchip/exiu: preparatory refactor for ACPI support
  irqchip/exiu: implement ACPI support
  gpio: mb86s7x: enable ACPI support

 drivers/acpi/irq.c             |  20 +++
 drivers/gpio/gpio-mb86s7x.c    |  51 ++++++-
 drivers/irqchip/irq-sni-exiu.c | 142 +++++++++++++++-----
 include/linux/acpi.h           |   7 +
 4 files changed, 182 insertions(+), 38 deletions(-)

-- 
2.20.1

Comments

Ard Biesheuvel May 28, 2019, 1:12 p.m. UTC | #1
On Tue, 28 May 2019 at 14:54, Marc Zyngier <marc.zyngier@arm.com> wrote:
>

> Hi Ard,

>

> On 27/05/2019 12:27, Ard Biesheuvel wrote:

> > ACPI permits arbitrary producer->consumer interrupt links to be

> > described in AML, which means a topology such as the following

> > is perfectly legal:

> >

> >   Device (EXIU) {

> >     Name (_HID, "SCX0008")

> >     Name (_UID, Zero)

> >     Name (_CRS, ResourceTemplate () {

> >       ...

> >     })

> >   }

> >

> >   Device (GPIO) {

> >     Name (_HID, "SCX0007")

> >     Name (_UID, Zero)

> >     Name (_CRS, ResourceTemplate () {

> >       Memory32Fixed (ReadWrite, SYNQUACER_GPIO_BASE, SYNQUACER_GPIO_SIZE)

> >       Interrupt (ResourceConsumer, Edge, ActiveHigh, ExclusiveAndWake, 0, "\\_SB.EXIU") {

> >         7,

> >       }

> >     })

> >     ...

> >   }

> >

> > The EXIU in this example is the external interrupt unit as can be found

> > on Socionext SynQuacer based platforms, which converts a block of 32 SPIs

> > from arbitrary polarity/trigger into level-high, with a separate set

> > of config/mask/unmask/clear controls.

> >

> > The existing DT based driver in drivers/irqchip/irq-sni-exiu.c models

> > this as a hierarchical domain stacked on top of the GIC's irqdomain.

> > Since the GIC is modeled as a DT node as well, obtaining a reference

> > to this irqdomain is easily done by going through the parent link.

> >

> > On ACPI systems, however, the GIC is not modeled as an object in the

> > namespace, and so device objects cannot refer to it directly. So in

> > order to obtain the irqdomain reference when driving the EXIU in ACPI

> > mode, we need a helper that implicitly grabs the default domain for

> > unqualified interrupts as the parent of the hierarchy.

> >

> > Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>

> > ---

> >  drivers/acpi/irq.c   | 20 ++++++++++++++++++++

> >  include/linux/acpi.h |  7 +++++++

> >  2 files changed, 27 insertions(+)

> >

> > diff --git a/drivers/acpi/irq.c b/drivers/acpi/irq.c

> > index c3b2222e2129..39824a6bbcd5 100644

> > --- a/drivers/acpi/irq.c

> > +++ b/drivers/acpi/irq.c

> > @@ -295,3 +295,23 @@ void __init acpi_set_irq_model(enum acpi_irq_model_id model,

> >       acpi_irq_model = model;

> >       acpi_gsi_domain_id = fwnode;

> >  }

> > +

> > +/**

> > + * acpi_irq_create_hierarchy - Create a hierarchical IRQ domain with the default

> > + *                             GSI domain as its parent.

> > + */

> > +struct irq_domain *acpi_irq_create_hierarchy(unsigned int flags,

> > +                                          unsigned int size,

> > +                                          struct fwnode_handle *fwnode,

> > +                                          const struct irq_domain_ops *ops,

> > +                                          void *host_data)

> > +{

> > +     struct irq_domain *d = irq_find_matching_fwnode(acpi_gsi_domain_id,

> > +                                                     DOMAIN_BUS_ANY);

> > +

> > +     if (!d)

> > +             return NULL;

> > +

> > +     return irq_domain_create_hierarchy(d, flags, size, fwnode, ops,

> > +                                        host_data);

> > +}

> > diff --git a/include/linux/acpi.h b/include/linux/acpi.h

> > index 98440df7fe42..70de4bc30cea 100644

> > --- a/include/linux/acpi.h

> > +++ b/include/linux/acpi.h

> > @@ -23,6 +23,7 @@

> >

> >  #include <linux/errno.h>

> >  #include <linux/ioport.h>    /* for struct resource */

> > +#include <linux/irqdomain.h>

> >  #include <linux/resource_ext.h>

> >  #include <linux/device.h>

> >  #include <linux/property.h>

> > @@ -327,6 +328,12 @@ int acpi_isa_irq_to_gsi (unsigned isa_irq, u32 *gsi);

> >  void acpi_set_irq_model(enum acpi_irq_model_id model,

> >                       struct fwnode_handle *fwnode);

> >

> > +struct irq_domain *acpi_irq_create_hierarchy(unsigned int flags,

> > +                                          unsigned int size,

> > +                                          struct fwnode_handle *fwnode,

> > +                                          const struct irq_domain_ops *ops,

> > +                                          void *host_data);

> > +

> >  #ifdef CONFIG_X86_IO_APIC

> >  extern int acpi_get_override_irq(u32 gsi, int *trigger, int *polarity);

> >  #else

> >

>

> Should we consider exporting this function to modules?

>


Good point, we probably should.


> Otherwise (and with Mika's comments addressed), looks good to me.

>

> Thanks,

>

>         M.

> --

> Jazz is not dead. It just smells funny...