// SPDX-License-Identifier: GPL-2.0 /* * Intel INT0002 "Virtual GPIO" driver * * Copyright (C) 2017 Hans de Goede <hdegoede@redhat.com> * * Loosely based on android x86 kernel code which is: * * Copyright (c) 2014, Intel Corporation. * * Author: Dyut Kumar Sil <dyut.k.sil@intel.com> * * Some peripherals on Bay Trail and Cherry Trail platforms signal a Power * Management Event (PME) to the Power Management Controller (PMC) to wakeup * the system. When this happens software needs to clear the PME bus 0 status * bit in the GPE0a_STS register to avoid an IRQ storm on IRQ 9. * * This is modelled in ACPI through the INT0002 ACPI device, which is * called a "Virtual GPIO controller" in ACPI because it defines the event * handler to call when the PME triggers through _AEI and _L02 / _E02 * methods as would be done for a real GPIO interrupt in ACPI. Note this * is a hack to define an AML event handler for the PME while using existing * ACPI mechanisms, this is not a real GPIO at all. * * This driver will bind to the INT0002 device, and register as a GPIO * controller, letting gpiolib-acpi call the _L02 handler as it would * for a real GPIO controller.
*/
/* * Applying of the wakeup flag to our parent IRQ is delayed till system * suspend, because we only want to do this when using s2idle.
*/ if (on)
int0002->wake_enable_count++; else
int0002->wake_enable_count--;
/* * We directly request the irq here instead of passing a flow-handler * to gpiochip_set_chained_irqchip, because the irq is shared. * FIXME: augment this if we managed to pull handling of shared * IRQs into gpiolib.
*/
ret = devm_request_irq(dev, irq, int0002_irq,
IRQF_ONESHOT | IRQF_SHARED, "INT0002", chip); if (ret) {
dev_err(dev, "Error requesting IRQ %d: %d\n", irq, ret); return ret;
}
girq = &chip->irq;
gpio_irq_chip_set_chip(girq, &int0002_irqchip); /* This let us handle the parent IRQ in the driver */
girq->parent_handler = NULL;
girq->num_parents = 0;
girq->parents = NULL;
girq->default_type = IRQ_TYPE_NONE;
girq->handler = handle_edge_irq;
ret = devm_gpiochip_add_data(dev, chip, NULL); if (ret) {
dev_err(dev, "Error adding gpio chip: %d\n", ret); return ret;
}
/* * The INT0002 parent IRQ is often shared with the ACPI GPE IRQ, don't * muck with it when firmware based suspend is used, otherwise we may * cause spurious wakeups from firmware managed suspend.
*/ if (!pm_suspend_via_firmware() && int0002->wake_enable_count)
enable_irq_wake(int0002->parent_irq);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.