On Wed, Nov 20, 2019 at 08:20:14PM +0100, Jan Kiszka wrote: > From: Jan Kiszka <jan.kiszka@xxxxxxxxxxx> > > The ACPI description on the Quark platform does not provide the required > information to do establish generic handling. Therefore, we need to hook > from the driver directly into SCI handler of the ACPI subsystem in order > to catch and report GPIO-related events. > > Validated on the Quark-based IOT2000 platform. > > Signed-off-by: Jan Kiszka <jan.kiszka@xxxxxxxxxxx> Reviewed-by: Mika Westerberg <mika.westerberg@xxxxxxxxxxxxxxx> Below one minor stylistic comment. > --- > drivers/gpio/gpio-sch.c | 30 ++++++++++++++++++++++++++++++ > 1 file changed, 30 insertions(+) > > diff --git a/drivers/gpio/gpio-sch.c b/drivers/gpio/gpio-sch.c > index 6a9c5500800c..75c95da145d8 100644 > --- a/drivers/gpio/gpio-sch.c > +++ b/drivers/gpio/gpio-sch.c > @@ -155,6 +155,31 @@ static const struct gpio_chip sch_gpio_chip = { > .to_irq = sch_gpio_to_irq, > }; > > +static u32 sch_sci_handler(void *context) > +{ > + struct sch_gpio *sch = context; > + unsigned long core_status, resume_status; > + unsigned int resume_gpios, offset; > + > + core_status = inl(sch->iobase + GTS); > + resume_status = inl(sch->iobase + GTS + 0x20); > + > + if (core_status == 0 && resume_status == 0) You can also write this like if (!core_status &&& !resume_status) > + return ACPI_INTERRUPT_NOT_HANDLED; > + > + for_each_set_bit(offset, &core_status, sch->resume_base) > + generic_handle_irq(sch->irq_base + offset); > + > + resume_gpios = sch->chip.ngpio - sch->resume_base; > + for_each_set_bit(offset, &resume_status, resume_gpios) > + generic_handle_irq(sch->irq_base + sch->resume_base + offset); > + > + outl(core_status, sch->iobase + GTS); > + outl(resume_status, sch->iobase + GTS + 0x20); > + > + return ACPI_INTERRUPT_HANDLED; > +} > + > static int sch_irq_type(struct irq_data *d, unsigned int type) > { > struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); > @@ -215,6 +240,7 @@ static int sch_gpio_probe(struct platform_device *pdev) > struct irq_chip_type *ct; > struct sch_gpio *sch; > struct resource *res; > + acpi_status status; > int irq_base, ret; > > sch = devm_kzalloc(&pdev->dev, sizeof(*sch), GFP_KERNEL); > @@ -303,6 +329,10 @@ static int sch_gpio_probe(struct platform_device *pdev) > if (ret) > return ret; > > + status = acpi_install_sci_handler(sch_sci_handler, sch); > + if (ACPI_FAILURE(status)) > + return -EINVAL; > + > return 0; > } > > -- > 2.16.4