Skip to content

Commit cd26465

Browse files
committed
platform/x86: x86-android-tablets: Add support for PMIC interrupts
The Crystal Cove PMIC has a pin which can be used to connect the IRQ of an external charger IC. On some boards this is used so we need a way to look this up. Note that the Intel PMICs have 2 levels of interrupts and thus 2 levels of IRQ domains all tied to a single fwnode. Level 1 is the irqchip which demultiplexes the actual PMIC interrupt into interrupts for the various MFD cells. Level 2 are the irqchips used in the cell drivers which themselves export IRQs, such as the crystal_cove_gpio driver, which de-multiplexes the level 2 interrupts for the GPIOs into individual per GPIO IRQs. The crystal_cove_charger driver registers an irqchip with a single IRQ for the charger driver to consume. Note the MFD cell IRQ cannot be consumed directly because the level 2 interrupts must be explicitly acked. To allow finding the right IRQ domain when looking up the IRQ for the charger, the crystal_cove_charger driver sets a DOMAIN_BUS_WIRED token on its IRQ domain. Add support for looking up the IRQ from the crystal_cove_charger driver. Signed-off-by: Hans de Goede <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent fc64a2b commit cd26465

File tree

1 file changed

+30
-1
lines changed

1 file changed

+30
-1
lines changed

drivers/platform/x86/x86-android-tablets.c

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include <linux/gpio/machine.h>
1818
#include <linux/i2c.h>
1919
#include <linux/irq.h>
20+
#include <linux/irqdomain.h>
2021
#include <linux/module.h>
2122
#include <linux/mod_devicetable.h>
2223
#include <linux/string.h>
@@ -31,11 +32,13 @@ enum x86_acpi_irq_type {
3132
X86_ACPI_IRQ_TYPE_NONE,
3233
X86_ACPI_IRQ_TYPE_APIC,
3334
X86_ACPI_IRQ_TYPE_GPIOINT,
35+
X86_ACPI_IRQ_TYPE_PMIC,
3436
};
3537

3638
struct x86_acpi_irq_data {
37-
char *chip; /* GPIO chip label (GPIOINT) */
39+
char *chip; /* GPIO chip label (GPIOINT) or PMIC ACPI path (PMIC) */
3840
enum x86_acpi_irq_type type;
41+
enum irq_domain_bus_token domain;
3942
int index;
4043
int trigger; /* ACPI_EDGE_SENSITIVE / ACPI_LEVEL_SENSITIVE */
4144
int polarity; /* ACPI_ACTIVE_HIGH / ACPI_ACTIVE_LOW / ACPI_ACTIVE_BOTH */
@@ -48,9 +51,14 @@ static int x86_acpi_irq_helper_gpiochip_find(struct gpio_chip *gc, void *data)
4851

4952
static int x86_acpi_irq_helper_get(const struct x86_acpi_irq_data *data)
5053
{
54+
struct irq_fwspec fwspec = { };
55+
struct irq_domain *domain;
56+
struct acpi_device *adev;
5157
struct gpio_desc *gpiod;
5258
struct gpio_chip *chip;
5359
unsigned int irq_type;
60+
acpi_handle handle;
61+
acpi_status status;
5462
int irq, ret;
5563

5664
switch (data->type) {
@@ -86,6 +94,27 @@ static int x86_acpi_irq_helper_get(const struct x86_acpi_irq_data *data)
8694
irq_set_irq_type(irq, irq_type);
8795

8896
return irq;
97+
case X86_ACPI_IRQ_TYPE_PMIC:
98+
status = acpi_get_handle(NULL, data->chip, &handle);
99+
if (ACPI_FAILURE(status)) {
100+
pr_err("error could not get %s handle\n", data->chip);
101+
return -ENODEV;
102+
}
103+
104+
acpi_bus_get_device(handle, &adev);
105+
if (!adev) {
106+
pr_err("error could not get %s adev\n", data->chip);
107+
return -ENODEV;
108+
}
109+
110+
fwspec.fwnode = acpi_fwnode_handle(adev);
111+
domain = irq_find_matching_fwspec(&fwspec, data->domain);
112+
if (!domain) {
113+
pr_err("error could not find IRQ domain for %s\n", data->chip);
114+
return -ENODEV;
115+
}
116+
117+
return irq_create_mapping(domain, data->index);
89118
default:
90119
return 0;
91120
}

0 commit comments

Comments
 (0)