diff options
Diffstat (limited to 'drivers/platform/x86/intel_int0002_vgpio.c')
-rw-r--r-- | drivers/platform/x86/intel_int0002_vgpio.c | 52 |
1 files changed, 32 insertions, 20 deletions
diff --git a/drivers/platform/x86/intel_int0002_vgpio.c b/drivers/platform/x86/intel_int0002_vgpio.c index d9542c661ddc..f14e2c5f9da5 100644 --- a/drivers/platform/x86/intel_int0002_vgpio.c +++ b/drivers/platform/x86/intel_int0002_vgpio.c @@ -122,7 +122,7 @@ static irqreturn_t int0002_irq(int irq, void *data) generic_handle_irq(irq_find_mapping(chip->irq.domain, GPE0A_PME_B0_VIRT_GPIO_PIN)); - pm_system_wakeup(); + pm_wakeup_hard_event(chip->parent); return IRQ_HANDLED; } @@ -144,6 +144,7 @@ static struct irq_chip int0002_cht_irqchip = { * No set_wake, on CHT the IRQ is typically shared with the ACPI SCI * and we don't want to mess with the ACPI SCI irq settings. */ + .flags = IRQCHIP_SKIP_SET_WAKE, }; static const struct x86_cpu_id int0002_cpu_ids[] = { @@ -152,12 +153,19 @@ static const struct x86_cpu_id int0002_cpu_ids[] = { {} }; +static void int0002_init_irq_valid_mask(struct gpio_chip *chip, + unsigned long *valid_mask, + unsigned int ngpios) +{ + bitmap_clear(valid_mask, 0, GPE0A_PME_B0_VIRT_GPIO_PIN); +} + static int int0002_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; const struct x86_cpu_id *cpu_id; - struct irq_chip *irq_chip; struct gpio_chip *chip; + struct gpio_irq_chip *girq; int irq, ret; /* Menlow has a different INT0002 device? <sigh> */ @@ -166,10 +174,8 @@ static int int0002_probe(struct platform_device *pdev) return -ENODEV; irq = platform_get_irq(pdev, 0); - if (irq < 0) { - dev_err(dev, "Error getting IRQ: %d\n", irq); + if (irq < 0) return irq; - } chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL); if (!chip) @@ -184,19 +190,13 @@ static int int0002_probe(struct platform_device *pdev) chip->direction_output = int0002_gpio_direction_output; chip->base = -1; chip->ngpio = GPE0A_PME_B0_VIRT_GPIO_PIN + 1; - chip->irq.need_valid_mask = true; - - ret = devm_gpiochip_add_data(&pdev->dev, chip, NULL); - if (ret) { - dev_err(dev, "Error adding gpio chip: %d\n", ret); - return ret; - } - - bitmap_clear(chip->irq.valid_mask, 0, GPE0A_PME_B0_VIRT_GPIO_PIN); + chip->irq.init_valid_mask = int0002_init_irq_valid_mask; /* - * We manually request the irq here instead of passing a flow-handler + * 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_SHARED, "INT0002", chip); @@ -205,17 +205,28 @@ static int int0002_probe(struct platform_device *pdev) return ret; } - irq_chip = (struct irq_chip *)cpu_id->driver_data; + girq = &chip->irq; + girq->chip = (struct irq_chip *)cpu_id->driver_data; + /* 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 = gpiochip_irqchip_add(chip, irq_chip, 0, handle_edge_irq, - IRQ_TYPE_NONE); + ret = devm_gpiochip_add_data(dev, chip, NULL); if (ret) { - dev_err(dev, "Error adding irqchip: %d\n", ret); + dev_err(dev, "Error adding gpio chip: %d\n", ret); return ret; } - gpiochip_set_chained_irqchip(chip, irq_chip, irq, NULL); + device_init_wakeup(dev, true); + return 0; +} +static int int0002_remove(struct platform_device *pdev) +{ + device_init_wakeup(&pdev->dev, false); return 0; } @@ -231,6 +242,7 @@ static struct platform_driver int0002_driver = { .acpi_match_table = int0002_acpi_ids, }, .probe = int0002_probe, + .remove = int0002_remove, }; module_platform_driver(int0002_driver); |