All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC PATCH 0/3] synquacer: implement ACPI gpio/interrupt support
@ 2019-04-25 10:20 ` Ard Biesheuvel
  0 siblings, 0 replies; 34+ messages in thread
From: Ard Biesheuvel @ 2019-04-25 10:20 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Graeme Gregory, Ard Biesheuvel, Marc Zyngier, Linus Walleij,
	linux-gpio, Masahisa Kojima

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)

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>

Ard Biesheuvel (3):
  irqchip/exiu: preparatory refactor for ACPI support
  irqchip/exiu: implement ACPI gpiolib/irqchip support
  gpio: mb86s70: enable ACPI and irqchip support

 drivers/gpio/Kconfig           |   4 +
 drivers/gpio/gpio-mb86s7x.c    |  58 ++++++--
 drivers/irqchip/irq-sni-exiu.c | 157 +++++++++++++++-----
 3 files changed, 173 insertions(+), 46 deletions(-)

-- 
2.20.1

^ permalink raw reply	[flat|nested] 34+ messages in thread

* [RFC PATCH 0/3] synquacer: implement ACPI gpio/interrupt support
@ 2019-04-25 10:20 ` Ard Biesheuvel
  0 siblings, 0 replies; 34+ messages in thread
From: Ard Biesheuvel @ 2019-04-25 10:20 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Graeme Gregory, Ard Biesheuvel, Marc Zyngier, Linus Walleij,
	linux-gpio, Masahisa Kojima

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)

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>

Ard Biesheuvel (3):
  irqchip/exiu: preparatory refactor for ACPI support
  irqchip/exiu: implement ACPI gpiolib/irqchip support
  gpio: mb86s70: enable ACPI and irqchip support

 drivers/gpio/Kconfig           |   4 +
 drivers/gpio/gpio-mb86s7x.c    |  58 ++++++--
 drivers/irqchip/irq-sni-exiu.c | 157 +++++++++++++++-----
 3 files changed, 173 insertions(+), 46 deletions(-)

-- 
2.20.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 34+ messages in thread

* [RFC PATCH 1/3] irqchip/exiu: preparatory refactor for ACPI support
  2019-04-25 10:20 ` Ard Biesheuvel
@ 2019-04-25 10:20   ` Ard Biesheuvel
  -1 siblings, 0 replies; 34+ messages in thread
From: Ard Biesheuvel @ 2019-04-25 10:20 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Graeme Gregory, Ard Biesheuvel, Marc Zyngier, Linus Walleij,
	linux-gpio, Masahisa Kojima

In preparation of exposing the EXIU controller as the irqchip part of
the GPIO controller, split the DT init function in a DT specific and
a generic part, where the latter will be reused for ACPI support later.

Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 drivers/irqchip/irq-sni-exiu.c | 77 ++++++++++++--------
 1 file changed, 48 insertions(+), 29 deletions(-)

diff --git a/drivers/irqchip/irq-sni-exiu.c b/drivers/irqchip/irq-sni-exiu.c
index 1927b2f36ff6..52ce662334d4 100644
--- a/drivers/irqchip/irq-sni-exiu.c
+++ b/drivers/irqchip/irq-sni-exiu.c
@@ -1,7 +1,7 @@
 /*
  * Driver for Socionext External Interrupt Unit (EXIU)
  *
- * Copyright (c) 2017 Linaro, Ltd. <ard.biesheuvel@linaro.org>
+ * Copyright (c) 2017-2019 Linaro, Ltd. <ard.biesheuvel@linaro.org>
  *
  * Based on irq-tegra.c:
  *   Copyright (C) 2011 Google, Inc.
@@ -167,35 +167,25 @@ static const struct irq_domain_ops exiu_domain_ops = {
 	.free		= irq_domain_free_irqs_common,
 };
 
-static int __init exiu_init(struct device_node *node,
-			    struct device_node *parent)
+static struct irq_domain *exiu_init(struct irq_domain *parent_domain,
+				    struct fwnode_handle *fwnode,
+				    struct resource *res)
 {
-	struct irq_domain *parent_domain, *domain;
+	struct irq_domain *domain;
 	struct exiu_irq_data *data;
 	int err;
 
-	if (!parent) {
-		pr_err("%pOF: no parent, giving up\n", node);
-		return -ENODEV;
-	}
-
-	parent_domain = irq_find_host(parent);
-	if (!parent_domain) {
-		pr_err("%pOF: unable to obtain parent domain\n", node);
-		return -ENXIO;
-	}
-
 	data = kzalloc(sizeof(*data), GFP_KERNEL);
 	if (!data)
-		return -ENOMEM;
+		return ERR_PTR(-ENOMEM);
 
-	if (of_property_read_u32(node, "socionext,spi-base", &data->spi_base)) {
-		pr_err("%pOF: failed to parse 'spi-base' property\n", node);
+	if (fwnode_property_read_u32_array(fwnode, "socionext,spi-base",
+					   &data->spi_base, 1)) {
 		err = -ENODEV;
 		goto out_free;
 	}
 
-	data->base = of_iomap(node, 0);
+	data->base = ioremap(res->start, resource_size(res));
 	if (!data->base) {
 		err = -ENODEV;
 		goto out_free;
@@ -205,23 +195,52 @@ static int __init exiu_init(struct device_node *node,
 	writel_relaxed(0xFFFFFFFF, data->base + EIREQCLR);
 	writel_relaxed(0xFFFFFFFF, data->base + EIMASK);
 
-	domain = irq_domain_add_hierarchy(parent_domain, 0, NUM_IRQS, node,
-					  &exiu_domain_ops, data);
+	domain = irq_domain_create_hierarchy(parent_domain, 0, NUM_IRQS,
+					     fwnode, &exiu_domain_ops, data);
 	if (!domain) {
-		pr_err("%pOF: failed to allocate domain\n", node);
 		err = -ENOMEM;
 		goto out_unmap;
 	}
+	return domain;
+out_unmap:
+	iounmap(data->base);
+out_free:
+	kfree(data);
+	return ERR_PTR(err);
+}
+
+static int __init exiu_dt_init(struct device_node *node,
+			       struct device_node *parent)
+{
+	struct irq_domain *parent_domain, *domain;
+	struct resource res;
+
+	if (!parent) {
+		pr_err("%pOF: no parent, giving up\n", node);
+		return -ENODEV;
+	}
+
+	parent_domain = irq_find_host(parent);
+	if (!parent_domain) {
+		pr_err("%pOF: unable to obtain parent domain\n", node);
+		return -ENXIO;
+	}
+
+	if (of_address_to_resource(node, 0, &res)) {
+		pr_err("%pOF: failed to parse memory resource\n", node);
+		return -ENXIO;
+	}
+
+	domain = exiu_init(parent_domain, of_node_to_fwnode(node), &res);
+	if (IS_ERR(domain)) {
+		pr_err("%pOF: failed to create IRQ domain (%ld)\n", node,
+		       PTR_ERR(domain));
+		return PTR_ERR(domain);
+	}
 
 	pr_info("%pOF: %d interrupts forwarded to %pOF\n", node, NUM_IRQS,
 		parent);
 
 	return 0;
-
-out_unmap:
-	iounmap(data->base);
-out_free:
-	kfree(data);
-	return err;
 }
-IRQCHIP_DECLARE(exiu, "socionext,synquacer-exiu", exiu_init);
+IRQCHIP_DECLARE(exiu, "socionext,synquacer-exiu", exiu_dt_init);
-- 
2.20.1

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [RFC PATCH 1/3] irqchip/exiu: preparatory refactor for ACPI support
@ 2019-04-25 10:20   ` Ard Biesheuvel
  0 siblings, 0 replies; 34+ messages in thread
From: Ard Biesheuvel @ 2019-04-25 10:20 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Graeme Gregory, Ard Biesheuvel, Marc Zyngier, Linus Walleij,
	linux-gpio, Masahisa Kojima

In preparation of exposing the EXIU controller as the irqchip part of
the GPIO controller, split the DT init function in a DT specific and
a generic part, where the latter will be reused for ACPI support later.

Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 drivers/irqchip/irq-sni-exiu.c | 77 ++++++++++++--------
 1 file changed, 48 insertions(+), 29 deletions(-)

diff --git a/drivers/irqchip/irq-sni-exiu.c b/drivers/irqchip/irq-sni-exiu.c
index 1927b2f36ff6..52ce662334d4 100644
--- a/drivers/irqchip/irq-sni-exiu.c
+++ b/drivers/irqchip/irq-sni-exiu.c
@@ -1,7 +1,7 @@
 /*
  * Driver for Socionext External Interrupt Unit (EXIU)
  *
- * Copyright (c) 2017 Linaro, Ltd. <ard.biesheuvel@linaro.org>
+ * Copyright (c) 2017-2019 Linaro, Ltd. <ard.biesheuvel@linaro.org>
  *
  * Based on irq-tegra.c:
  *   Copyright (C) 2011 Google, Inc.
@@ -167,35 +167,25 @@ static const struct irq_domain_ops exiu_domain_ops = {
 	.free		= irq_domain_free_irqs_common,
 };
 
-static int __init exiu_init(struct device_node *node,
-			    struct device_node *parent)
+static struct irq_domain *exiu_init(struct irq_domain *parent_domain,
+				    struct fwnode_handle *fwnode,
+				    struct resource *res)
 {
-	struct irq_domain *parent_domain, *domain;
+	struct irq_domain *domain;
 	struct exiu_irq_data *data;
 	int err;
 
-	if (!parent) {
-		pr_err("%pOF: no parent, giving up\n", node);
-		return -ENODEV;
-	}
-
-	parent_domain = irq_find_host(parent);
-	if (!parent_domain) {
-		pr_err("%pOF: unable to obtain parent domain\n", node);
-		return -ENXIO;
-	}
-
 	data = kzalloc(sizeof(*data), GFP_KERNEL);
 	if (!data)
-		return -ENOMEM;
+		return ERR_PTR(-ENOMEM);
 
-	if (of_property_read_u32(node, "socionext,spi-base", &data->spi_base)) {
-		pr_err("%pOF: failed to parse 'spi-base' property\n", node);
+	if (fwnode_property_read_u32_array(fwnode, "socionext,spi-base",
+					   &data->spi_base, 1)) {
 		err = -ENODEV;
 		goto out_free;
 	}
 
-	data->base = of_iomap(node, 0);
+	data->base = ioremap(res->start, resource_size(res));
 	if (!data->base) {
 		err = -ENODEV;
 		goto out_free;
@@ -205,23 +195,52 @@ static int __init exiu_init(struct device_node *node,
 	writel_relaxed(0xFFFFFFFF, data->base + EIREQCLR);
 	writel_relaxed(0xFFFFFFFF, data->base + EIMASK);
 
-	domain = irq_domain_add_hierarchy(parent_domain, 0, NUM_IRQS, node,
-					  &exiu_domain_ops, data);
+	domain = irq_domain_create_hierarchy(parent_domain, 0, NUM_IRQS,
+					     fwnode, &exiu_domain_ops, data);
 	if (!domain) {
-		pr_err("%pOF: failed to allocate domain\n", node);
 		err = -ENOMEM;
 		goto out_unmap;
 	}
+	return domain;
+out_unmap:
+	iounmap(data->base);
+out_free:
+	kfree(data);
+	return ERR_PTR(err);
+}
+
+static int __init exiu_dt_init(struct device_node *node,
+			       struct device_node *parent)
+{
+	struct irq_domain *parent_domain, *domain;
+	struct resource res;
+
+	if (!parent) {
+		pr_err("%pOF: no parent, giving up\n", node);
+		return -ENODEV;
+	}
+
+	parent_domain = irq_find_host(parent);
+	if (!parent_domain) {
+		pr_err("%pOF: unable to obtain parent domain\n", node);
+		return -ENXIO;
+	}
+
+	if (of_address_to_resource(node, 0, &res)) {
+		pr_err("%pOF: failed to parse memory resource\n", node);
+		return -ENXIO;
+	}
+
+	domain = exiu_init(parent_domain, of_node_to_fwnode(node), &res);
+	if (IS_ERR(domain)) {
+		pr_err("%pOF: failed to create IRQ domain (%ld)\n", node,
+		       PTR_ERR(domain));
+		return PTR_ERR(domain);
+	}
 
 	pr_info("%pOF: %d interrupts forwarded to %pOF\n", node, NUM_IRQS,
 		parent);
 
 	return 0;
-
-out_unmap:
-	iounmap(data->base);
-out_free:
-	kfree(data);
-	return err;
 }
-IRQCHIP_DECLARE(exiu, "socionext,synquacer-exiu", exiu_init);
+IRQCHIP_DECLARE(exiu, "socionext,synquacer-exiu", exiu_dt_init);
-- 
2.20.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [RFC PATCH 2/3] irqchip/exiu: implement ACPI gpiolib/irqchip support
  2019-04-25 10:20 ` Ard Biesheuvel
@ 2019-04-25 10:20   ` Ard Biesheuvel
  -1 siblings, 0 replies; 34+ messages in thread
From: Ard Biesheuvel @ 2019-04-25 10:20 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Graeme Gregory, Ard Biesheuvel, Marc Zyngier, Linus Walleij,
	linux-gpio, Masahisa Kojima

Expose the existing EXIU hierarchical irqchip domain code to permit
the interrupt controller to be used as the irqchip component of a
GPIO controller on ACPI systems.

Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 drivers/irqchip/irq-sni-exiu.c | 82 +++++++++++++++++---
 1 file changed, 73 insertions(+), 9 deletions(-)

diff --git a/drivers/irqchip/irq-sni-exiu.c b/drivers/irqchip/irq-sni-exiu.c
index 52ce662334d4..99351cf997d9 100644
--- a/drivers/irqchip/irq-sni-exiu.c
+++ b/drivers/irqchip/irq-sni-exiu.c
@@ -12,6 +12,7 @@
  * published by the Free Software Foundation.
  */
 
+#include <linux/gpio/driver.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
 #include <linux/irq.h>
@@ -20,6 +21,7 @@
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/of_irq.h>
+#include <linux/platform_device.h>
 
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 
@@ -134,9 +136,13 @@ static int exiu_domain_translate(struct irq_domain *domain,
 
 		*hwirq = fwspec->param[1] - info->spi_base;
 		*type = fwspec->param[2] & IRQ_TYPE_SENSE_MASK;
-		return 0;
+	} else {
+		if (fwspec->param_count != 2)
+			return -EINVAL;
+		*hwirq = fwspec->param[0];
+		*type = fwspec->param[2] & IRQ_TYPE_SENSE_MASK;
 	}
-	return -EINVAL;
+	return 0;
 }
 
 static int exiu_domain_alloc(struct irq_domain *dom, unsigned int virq,
@@ -147,16 +153,23 @@ static int exiu_domain_alloc(struct irq_domain *dom, unsigned int virq,
 	struct exiu_irq_data *info = dom->host_data;
 	irq_hw_number_t hwirq;
 
-	if (fwspec->param_count != 3)
-		return -EINVAL;	/* Not GIC compliant */
-	if (fwspec->param[0] != GIC_SPI)
-		return -EINVAL;	/* No PPI should point to this domain */
-
+	parent_fwspec = *fwspec;
+	if (is_of_node(dom->parent->fwnode)) {
+		if (fwspec->param_count != 3)
+			return -EINVAL;	/* Not GIC compliant */
+		if (fwspec->param[0] != GIC_SPI)
+			return -EINVAL;	/* No PPI should point to this domain */
+
+		hwirq = fwspec->param[1] - info->spi_base;
+	} else if (is_fwnode_irqchip(dom->parent->fwnode)) {
+		hwirq = fwspec->param[0];
+		parent_fwspec.param[0] = hwirq + info->spi_base + 32;
+	} else {
+		return -EINVAL;
+	}
 	WARN_ON(nr_irqs != 1);
-	hwirq = fwspec->param[1] - info->spi_base;
 	irq_domain_set_hwirq_and_chip(dom, virq, hwirq, &exiu_irq_chip, info);
 
-	parent_fwspec = *fwspec;
 	parent_fwspec.fwnode = dom->parent->fwnode;
 	return irq_domain_alloc_irqs_parent(dom, virq, nr_irqs, &parent_fwspec);
 }
@@ -244,3 +257,54 @@ static int __init exiu_dt_init(struct device_node *node,
 	return 0;
 }
 IRQCHIP_DECLARE(exiu, "socionext,synquacer-exiu", exiu_dt_init);
+
+#ifdef CONFIG_ACPI
+static int exiu_acpi_gpio_to_irq(struct gpio_chip *gc, u32 gpio)
+{
+	struct irq_fwspec fwspec;
+
+	fwspec.fwnode		= gc->parent->fwnode;
+	fwspec.param_count	= 2;
+	fwspec.param[0]		= gpio;
+	fwspec.param[1]		= IRQ_TYPE_LEVEL_HIGH;
+
+	return irq_create_fwspec_mapping(&fwspec);
+}
+
+int exiu_acpi_init(struct platform_device *pdev, struct gpio_chip *gc)
+{
+	struct irq_domain *parent_domain = NULL, *domain;
+	struct resource *res;
+	int irq;
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq > 0)
+		parent_domain = irq_get_irq_data(irq)->domain;
+
+	if (!parent_domain) {
+		dev_err(&pdev->dev, "unable to obtain parent domain\n");
+		return -ENODEV;
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	if (!res) {
+		dev_err(&pdev->dev, "failed to parse memory resource\n");
+		return -ENXIO;
+	}
+
+	domain = exiu_init(parent_domain, dev_fwnode(&pdev->dev), res);
+	if (IS_ERR(domain)) {
+		dev_err(&pdev->dev, "failed to create IRQ domain (%ld)\n",
+			PTR_ERR(domain));
+		return PTR_ERR(domain);
+	}
+
+	gc->irq.domain = domain;
+	gc->to_irq = exiu_acpi_gpio_to_irq;
+
+	dev_info(&pdev->dev, "%d interrupts forwarded\n", NUM_IRQS);
+
+	return 0;
+}
+EXPORT_SYMBOL(exiu_acpi_init);
+#endif
-- 
2.20.1

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [RFC PATCH 2/3] irqchip/exiu: implement ACPI gpiolib/irqchip support
@ 2019-04-25 10:20   ` Ard Biesheuvel
  0 siblings, 0 replies; 34+ messages in thread
From: Ard Biesheuvel @ 2019-04-25 10:20 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Graeme Gregory, Ard Biesheuvel, Marc Zyngier, Linus Walleij,
	linux-gpio, Masahisa Kojima

Expose the existing EXIU hierarchical irqchip domain code to permit
the interrupt controller to be used as the irqchip component of a
GPIO controller on ACPI systems.

Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 drivers/irqchip/irq-sni-exiu.c | 82 +++++++++++++++++---
 1 file changed, 73 insertions(+), 9 deletions(-)

diff --git a/drivers/irqchip/irq-sni-exiu.c b/drivers/irqchip/irq-sni-exiu.c
index 52ce662334d4..99351cf997d9 100644
--- a/drivers/irqchip/irq-sni-exiu.c
+++ b/drivers/irqchip/irq-sni-exiu.c
@@ -12,6 +12,7 @@
  * published by the Free Software Foundation.
  */
 
+#include <linux/gpio/driver.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
 #include <linux/irq.h>
@@ -20,6 +21,7 @@
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/of_irq.h>
+#include <linux/platform_device.h>
 
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 
@@ -134,9 +136,13 @@ static int exiu_domain_translate(struct irq_domain *domain,
 
 		*hwirq = fwspec->param[1] - info->spi_base;
 		*type = fwspec->param[2] & IRQ_TYPE_SENSE_MASK;
-		return 0;
+	} else {
+		if (fwspec->param_count != 2)
+			return -EINVAL;
+		*hwirq = fwspec->param[0];
+		*type = fwspec->param[2] & IRQ_TYPE_SENSE_MASK;
 	}
-	return -EINVAL;
+	return 0;
 }
 
 static int exiu_domain_alloc(struct irq_domain *dom, unsigned int virq,
@@ -147,16 +153,23 @@ static int exiu_domain_alloc(struct irq_domain *dom, unsigned int virq,
 	struct exiu_irq_data *info = dom->host_data;
 	irq_hw_number_t hwirq;
 
-	if (fwspec->param_count != 3)
-		return -EINVAL;	/* Not GIC compliant */
-	if (fwspec->param[0] != GIC_SPI)
-		return -EINVAL;	/* No PPI should point to this domain */
-
+	parent_fwspec = *fwspec;
+	if (is_of_node(dom->parent->fwnode)) {
+		if (fwspec->param_count != 3)
+			return -EINVAL;	/* Not GIC compliant */
+		if (fwspec->param[0] != GIC_SPI)
+			return -EINVAL;	/* No PPI should point to this domain */
+
+		hwirq = fwspec->param[1] - info->spi_base;
+	} else if (is_fwnode_irqchip(dom->parent->fwnode)) {
+		hwirq = fwspec->param[0];
+		parent_fwspec.param[0] = hwirq + info->spi_base + 32;
+	} else {
+		return -EINVAL;
+	}
 	WARN_ON(nr_irqs != 1);
-	hwirq = fwspec->param[1] - info->spi_base;
 	irq_domain_set_hwirq_and_chip(dom, virq, hwirq, &exiu_irq_chip, info);
 
-	parent_fwspec = *fwspec;
 	parent_fwspec.fwnode = dom->parent->fwnode;
 	return irq_domain_alloc_irqs_parent(dom, virq, nr_irqs, &parent_fwspec);
 }
@@ -244,3 +257,54 @@ static int __init exiu_dt_init(struct device_node *node,
 	return 0;
 }
 IRQCHIP_DECLARE(exiu, "socionext,synquacer-exiu", exiu_dt_init);
+
+#ifdef CONFIG_ACPI
+static int exiu_acpi_gpio_to_irq(struct gpio_chip *gc, u32 gpio)
+{
+	struct irq_fwspec fwspec;
+
+	fwspec.fwnode		= gc->parent->fwnode;
+	fwspec.param_count	= 2;
+	fwspec.param[0]		= gpio;
+	fwspec.param[1]		= IRQ_TYPE_LEVEL_HIGH;
+
+	return irq_create_fwspec_mapping(&fwspec);
+}
+
+int exiu_acpi_init(struct platform_device *pdev, struct gpio_chip *gc)
+{
+	struct irq_domain *parent_domain = NULL, *domain;
+	struct resource *res;
+	int irq;
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq > 0)
+		parent_domain = irq_get_irq_data(irq)->domain;
+
+	if (!parent_domain) {
+		dev_err(&pdev->dev, "unable to obtain parent domain\n");
+		return -ENODEV;
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	if (!res) {
+		dev_err(&pdev->dev, "failed to parse memory resource\n");
+		return -ENXIO;
+	}
+
+	domain = exiu_init(parent_domain, dev_fwnode(&pdev->dev), res);
+	if (IS_ERR(domain)) {
+		dev_err(&pdev->dev, "failed to create IRQ domain (%ld)\n",
+			PTR_ERR(domain));
+		return PTR_ERR(domain);
+	}
+
+	gc->irq.domain = domain;
+	gc->to_irq = exiu_acpi_gpio_to_irq;
+
+	dev_info(&pdev->dev, "%d interrupts forwarded\n", NUM_IRQS);
+
+	return 0;
+}
+EXPORT_SYMBOL(exiu_acpi_init);
+#endif
-- 
2.20.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [RFC PATCH 3/3] gpio: mb86s70: enable ACPI and irqchip support
  2019-04-25 10:20 ` Ard Biesheuvel
@ 2019-04-25 10:20   ` Ard Biesheuvel
  -1 siblings, 0 replies; 34+ messages in thread
From: Ard Biesheuvel @ 2019-04-25 10:20 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Graeme Gregory, Ard Biesheuvel, Marc Zyngier, Linus Walleij,
	linux-gpio, Masahisa Kojima

In order to support this GPIO block in combination with an EXIU
interrupt controller on ACPI systems such as Socionext SynQuacer,
add the enumeration boilerplate, and add the EXIU irqchip handling
to the probe path. Also, make the clock handling conditonal on
non-ACPI enumeration, since ACPI handles this internally.

Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 drivers/gpio/Kconfig        |  4 ++
 drivers/gpio/gpio-mb86s7x.c | 58 +++++++++++++++++---
 2 files changed, 53 insertions(+), 9 deletions(-)

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 3f50526a771f..2c2773ea9627 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -315,6 +315,10 @@ config GPIO_MB86S7X
 	help
 	  Say yes here to support the GPIO controller in Fujitsu MB86S70 SoCs.
 
+config GPIO_MB86S7X_ACPI
+	def_bool y
+	depends on ACPI && ARCH_SYNQUACER
+
 config GPIO_MENZ127
 	tristate "MEN 16Z127 GPIO support"
 	depends on MCB
diff --git a/drivers/gpio/gpio-mb86s7x.c b/drivers/gpio/gpio-mb86s7x.c
index 3134c0d2bfe4..d254783f7e71 100644
--- a/drivers/gpio/gpio-mb86s7x.c
+++ b/drivers/gpio/gpio-mb86s7x.c
@@ -14,6 +14,7 @@
  *  GNU General Public License for more details.
  */
 
+#include <linux/acpi.h>
 #include <linux/io.h>
 #include <linux/init.h>
 #include <linux/clk.h>
@@ -27,6 +28,8 @@
 #include <linux/spinlock.h>
 #include <linux/slab.h>
 
+#include "gpiolib.h"
+
 /*
  * Only first 8bits of a register correspond to each pin,
  * so there are 4 registers for 32 pins.
@@ -44,6 +47,8 @@ struct mb86s70_gpio_chip {
 	spinlock_t lock;
 };
 
+int exiu_acpi_init(struct platform_device *pdev, struct gpio_chip *gc);
+
 static int mb86s70_gpio_request(struct gpio_chip *gc, unsigned gpio)
 {
 	struct mb86s70_gpio_chip *gchip = gpiochip_get_data(gc);
@@ -143,6 +148,12 @@ static void mb86s70_gpio_set(struct gpio_chip *gc, unsigned gpio, int value)
 	spin_unlock_irqrestore(&gchip->lock, flags);
 }
 
+static bool mb86s70_gpio_have_acpi(struct platform_device *pdev)
+{
+	return IS_ENABLED(CONFIG_GPIO_MB86S7X_ACPI) &&
+	       ACPI_COMPANION(&pdev->dev);
+}
+
 static int mb86s70_gpio_probe(struct platform_device *pdev)
 {
 	struct mb86s70_gpio_chip *gchip;
@@ -160,13 +171,15 @@ static int mb86s70_gpio_probe(struct platform_device *pdev)
 	if (IS_ERR(gchip->base))
 		return PTR_ERR(gchip->base);
 
-	gchip->clk = devm_clk_get(&pdev->dev, NULL);
-	if (IS_ERR(gchip->clk))
-		return PTR_ERR(gchip->clk);
+	if (!mb86s70_gpio_have_acpi(pdev)) {
+		gchip->clk = devm_clk_get(&pdev->dev, NULL);
+		if (IS_ERR(gchip->clk))
+			return PTR_ERR(gchip->clk);
 
-	ret = clk_prepare_enable(gchip->clk);
-	if (ret)
-		return ret;
+		ret = clk_prepare_enable(gchip->clk);
+		if (ret)
+			return ret;
+	}
 
 	spin_lock_init(&gchip->lock);
 
@@ -182,21 +195,39 @@ static int mb86s70_gpio_probe(struct platform_device *pdev)
 	gchip->gc.parent = &pdev->dev;
 	gchip->gc.base = -1;
 
+	if (mb86s70_gpio_have_acpi(pdev)) {
+		ret = exiu_acpi_init(pdev, &gchip->gc);
+		if (ret) {
+			dev_err(&pdev->dev, "couldn't register gpio irqchip\n");
+			return ret;
+		}
+	}
+
 	ret = gpiochip_add_data(&gchip->gc, gchip);
 	if (ret) {
 		dev_err(&pdev->dev, "couldn't register gpio driver\n");
-		clk_disable_unprepare(gchip->clk);
+		if (gchip->clk)
+			clk_disable_unprepare(gchip->clk);
+		return ret;
 	}
 
-	return ret;
+	if (mb86s70_gpio_have_acpi(pdev))
+		acpi_gpiochip_request_interrupts(&gchip->gc);
+
+	return 0;
 }
 
 static int mb86s70_gpio_remove(struct platform_device *pdev)
 {
 	struct mb86s70_gpio_chip *gchip = platform_get_drvdata(pdev);
 
+	if (gchip->gc.irq.domain) {
+		acpi_gpiochip_free_interrupts(&gchip->gc);
+		irq_domain_remove(gchip->gc.irq.domain);
+	}
 	gpiochip_remove(&gchip->gc);
-	clk_disable_unprepare(gchip->clk);
+	if (gchip->clk)
+		clk_disable_unprepare(gchip->clk);
 
 	return 0;
 }
@@ -207,10 +238,19 @@ static const struct of_device_id mb86s70_gpio_dt_ids[] = {
 };
 MODULE_DEVICE_TABLE(of, mb86s70_gpio_dt_ids);
 
+#ifdef CONFIG_ACPI
+static const struct acpi_device_id mb86s70_gpio_acpi_ids[] = {
+	{ "SCX0007" },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(acpi, mb86s70_gpio_acpi_ids);
+#endif
+
 static struct platform_driver mb86s70_gpio_driver = {
 	.driver = {
 		.name = "mb86s70-gpio",
 		.of_match_table = mb86s70_gpio_dt_ids,
+		.acpi_match_table = ACPI_PTR(mb86s70_gpio_acpi_ids),
 	},
 	.probe = mb86s70_gpio_probe,
 	.remove = mb86s70_gpio_remove,
-- 
2.20.1

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [RFC PATCH 3/3] gpio: mb86s70: enable ACPI and irqchip support
@ 2019-04-25 10:20   ` Ard Biesheuvel
  0 siblings, 0 replies; 34+ messages in thread
From: Ard Biesheuvel @ 2019-04-25 10:20 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Graeme Gregory, Ard Biesheuvel, Marc Zyngier, Linus Walleij,
	linux-gpio, Masahisa Kojima

In order to support this GPIO block in combination with an EXIU
interrupt controller on ACPI systems such as Socionext SynQuacer,
add the enumeration boilerplate, and add the EXIU irqchip handling
to the probe path. Also, make the clock handling conditonal on
non-ACPI enumeration, since ACPI handles this internally.

Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 drivers/gpio/Kconfig        |  4 ++
 drivers/gpio/gpio-mb86s7x.c | 58 +++++++++++++++++---
 2 files changed, 53 insertions(+), 9 deletions(-)

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 3f50526a771f..2c2773ea9627 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -315,6 +315,10 @@ config GPIO_MB86S7X
 	help
 	  Say yes here to support the GPIO controller in Fujitsu MB86S70 SoCs.
 
+config GPIO_MB86S7X_ACPI
+	def_bool y
+	depends on ACPI && ARCH_SYNQUACER
+
 config GPIO_MENZ127
 	tristate "MEN 16Z127 GPIO support"
 	depends on MCB
diff --git a/drivers/gpio/gpio-mb86s7x.c b/drivers/gpio/gpio-mb86s7x.c
index 3134c0d2bfe4..d254783f7e71 100644
--- a/drivers/gpio/gpio-mb86s7x.c
+++ b/drivers/gpio/gpio-mb86s7x.c
@@ -14,6 +14,7 @@
  *  GNU General Public License for more details.
  */
 
+#include <linux/acpi.h>
 #include <linux/io.h>
 #include <linux/init.h>
 #include <linux/clk.h>
@@ -27,6 +28,8 @@
 #include <linux/spinlock.h>
 #include <linux/slab.h>
 
+#include "gpiolib.h"
+
 /*
  * Only first 8bits of a register correspond to each pin,
  * so there are 4 registers for 32 pins.
@@ -44,6 +47,8 @@ struct mb86s70_gpio_chip {
 	spinlock_t lock;
 };
 
+int exiu_acpi_init(struct platform_device *pdev, struct gpio_chip *gc);
+
 static int mb86s70_gpio_request(struct gpio_chip *gc, unsigned gpio)
 {
 	struct mb86s70_gpio_chip *gchip = gpiochip_get_data(gc);
@@ -143,6 +148,12 @@ static void mb86s70_gpio_set(struct gpio_chip *gc, unsigned gpio, int value)
 	spin_unlock_irqrestore(&gchip->lock, flags);
 }
 
+static bool mb86s70_gpio_have_acpi(struct platform_device *pdev)
+{
+	return IS_ENABLED(CONFIG_GPIO_MB86S7X_ACPI) &&
+	       ACPI_COMPANION(&pdev->dev);
+}
+
 static int mb86s70_gpio_probe(struct platform_device *pdev)
 {
 	struct mb86s70_gpio_chip *gchip;
@@ -160,13 +171,15 @@ static int mb86s70_gpio_probe(struct platform_device *pdev)
 	if (IS_ERR(gchip->base))
 		return PTR_ERR(gchip->base);
 
-	gchip->clk = devm_clk_get(&pdev->dev, NULL);
-	if (IS_ERR(gchip->clk))
-		return PTR_ERR(gchip->clk);
+	if (!mb86s70_gpio_have_acpi(pdev)) {
+		gchip->clk = devm_clk_get(&pdev->dev, NULL);
+		if (IS_ERR(gchip->clk))
+			return PTR_ERR(gchip->clk);
 
-	ret = clk_prepare_enable(gchip->clk);
-	if (ret)
-		return ret;
+		ret = clk_prepare_enable(gchip->clk);
+		if (ret)
+			return ret;
+	}
 
 	spin_lock_init(&gchip->lock);
 
@@ -182,21 +195,39 @@ static int mb86s70_gpio_probe(struct platform_device *pdev)
 	gchip->gc.parent = &pdev->dev;
 	gchip->gc.base = -1;
 
+	if (mb86s70_gpio_have_acpi(pdev)) {
+		ret = exiu_acpi_init(pdev, &gchip->gc);
+		if (ret) {
+			dev_err(&pdev->dev, "couldn't register gpio irqchip\n");
+			return ret;
+		}
+	}
+
 	ret = gpiochip_add_data(&gchip->gc, gchip);
 	if (ret) {
 		dev_err(&pdev->dev, "couldn't register gpio driver\n");
-		clk_disable_unprepare(gchip->clk);
+		if (gchip->clk)
+			clk_disable_unprepare(gchip->clk);
+		return ret;
 	}
 
-	return ret;
+	if (mb86s70_gpio_have_acpi(pdev))
+		acpi_gpiochip_request_interrupts(&gchip->gc);
+
+	return 0;
 }
 
 static int mb86s70_gpio_remove(struct platform_device *pdev)
 {
 	struct mb86s70_gpio_chip *gchip = platform_get_drvdata(pdev);
 
+	if (gchip->gc.irq.domain) {
+		acpi_gpiochip_free_interrupts(&gchip->gc);
+		irq_domain_remove(gchip->gc.irq.domain);
+	}
 	gpiochip_remove(&gchip->gc);
-	clk_disable_unprepare(gchip->clk);
+	if (gchip->clk)
+		clk_disable_unprepare(gchip->clk);
 
 	return 0;
 }
@@ -207,10 +238,19 @@ static const struct of_device_id mb86s70_gpio_dt_ids[] = {
 };
 MODULE_DEVICE_TABLE(of, mb86s70_gpio_dt_ids);
 
+#ifdef CONFIG_ACPI
+static const struct acpi_device_id mb86s70_gpio_acpi_ids[] = {
+	{ "SCX0007" },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(acpi, mb86s70_gpio_acpi_ids);
+#endif
+
 static struct platform_driver mb86s70_gpio_driver = {
 	.driver = {
 		.name = "mb86s70-gpio",
 		.of_match_table = mb86s70_gpio_dt_ids,
+		.acpi_match_table = ACPI_PTR(mb86s70_gpio_acpi_ids),
 	},
 	.probe = mb86s70_gpio_probe,
 	.remove = mb86s70_gpio_remove,
-- 
2.20.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* Re: [RFC PATCH 2/3] irqchip/exiu: implement ACPI gpiolib/irqchip support
  2019-04-25 10:20   ` Ard Biesheuvel
@ 2019-04-25 13:14     ` Linus Walleij
  -1 siblings, 0 replies; 34+ messages in thread
From: Linus Walleij @ 2019-04-25 13:14 UTC (permalink / raw)
  To: Ard Biesheuvel, Mika Westerberg
  Cc: Marc Zyngier, open list:GPIO SUBSYSTEM, Graeme Gregory,
	Linux ARM, Masahisa Kojima

Hi Ard!

Thanks for your patch!

As it involves ACPI I suggest to include Mika Westerberg on review since
he's doing the core gpiolib ACPI stuff.

On Thu, Apr 25, 2019 at 12:20 PM Ard Biesheuvel
<ard.biesheuvel@linaro.org> wrote:

> Expose the existing EXIU hierarchical irqchip domain code to permit
> the interrupt controller to be used as the irqchip component of a
> GPIO controller on ACPI systems.
>
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>

(...)

> +#include <linux/gpio/driver.h>

So now this is starting to go from being a pure irqchip driver
to a combined irq+gpio driver.

> +       gc->irq.domain = domain;
> +       gc->to_irq = exiu_acpi_gpio_to_irq;

And there is some gpiochip involved.

> +EXPORT_SYMBOL(exiu_acpi_init);

Including exporting functions.

What about we just move this driver over to drivers/gpio and
start working out a combined GPIO+irqchip driver there? I am
working on adding generic hierarchical irqchip helpers in the
gpiolib core and then it's gonna be nice to have all combined
drivers under the drivers/gpio folder.

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [RFC PATCH 2/3] irqchip/exiu: implement ACPI gpiolib/irqchip support
@ 2019-04-25 13:14     ` Linus Walleij
  0 siblings, 0 replies; 34+ messages in thread
From: Linus Walleij @ 2019-04-25 13:14 UTC (permalink / raw)
  To: Ard Biesheuvel, Mika Westerberg
  Cc: Marc Zyngier, open list:GPIO SUBSYSTEM, Graeme Gregory,
	Linux ARM, Masahisa Kojima

Hi Ard!

Thanks for your patch!

As it involves ACPI I suggest to include Mika Westerberg on review since
he's doing the core gpiolib ACPI stuff.

On Thu, Apr 25, 2019 at 12:20 PM Ard Biesheuvel
<ard.biesheuvel@linaro.org> wrote:

> Expose the existing EXIU hierarchical irqchip domain code to permit
> the interrupt controller to be used as the irqchip component of a
> GPIO controller on ACPI systems.
>
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>

(...)

> +#include <linux/gpio/driver.h>

So now this is starting to go from being a pure irqchip driver
to a combined irq+gpio driver.

> +       gc->irq.domain = domain;
> +       gc->to_irq = exiu_acpi_gpio_to_irq;

And there is some gpiochip involved.

> +EXPORT_SYMBOL(exiu_acpi_init);

Including exporting functions.

What about we just move this driver over to drivers/gpio and
start working out a combined GPIO+irqchip driver there? I am
working on adding generic hierarchical irqchip helpers in the
gpiolib core and then it's gonna be nice to have all combined
drivers under the drivers/gpio folder.

Yours,
Linus Walleij

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [RFC PATCH 3/3] gpio: mb86s70: enable ACPI and irqchip support
  2019-04-25 10:20   ` Ard Biesheuvel
@ 2019-04-25 13:23     ` Linus Walleij
  -1 siblings, 0 replies; 34+ messages in thread
From: Linus Walleij @ 2019-04-25 13:23 UTC (permalink / raw)
  To: Ard Biesheuvel, Mika Westerberg
  Cc: Marc Zyngier, open list:GPIO SUBSYSTEM, Graeme Gregory,
	Linux ARM, Masahisa Kojima

Hi Ard, thanks for your patch!

Including Mika here as well, he knows how ACPI is supposed to
be wired up with GPIOs.

On Thu, Apr 25, 2019 at 12:20 PM Ard Biesheuvel
<ard.biesheuvel@linaro.org> wrote:

> In order to support this GPIO block in combination with an EXIU
> interrupt controller on ACPI systems such as Socionext SynQuacer,
> add the enumeration boilerplate, and add the EXIU irqchip handling
> to the probe path. Also, make the clock handling conditonal on
> non-ACPI enumeration, since ACPI handles this internally.
>
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
(...)

> +config GPIO_MB86S7X_ACPI
> +       def_bool y
> +       depends on ACPI && ARCH_SYNQUACER

I would say

depends on ACPI
depends on (ARCH_SYNQUACER || COMPILE_TEST)

so we get some compiler coverage.

> +#include <linux/acpi.h>
>  #include <linux/io.h>
>  #include <linux/init.h>
>  #include <linux/clk.h>
> @@ -27,6 +28,8 @@
>  #include <linux/spinlock.h>
>  #include <linux/slab.h>
>
> +#include "gpiolib.h"

Normally not a good sign to dereference gpiolib internals,
but there are some few exceptions. Why do you do this?

> +int exiu_acpi_init(struct platform_device *pdev, struct gpio_chip *gc);

Just merge it all into one file instead of having these crisscrossy calls.
I prefer some minor #ifdef or straight C if (IS_ENABLED()) around
specific code.

> -       return ret;
> +       if (mb86s70_gpio_have_acpi(pdev))
> +               acpi_gpiochip_request_interrupts(&gchip->gc);
> +
> +       return 0;

I guess this is right...

>         struct mb86s70_gpio_chip *gchip = platform_get_drvdata(pdev);
>
> +       if (gchip->gc.irq.domain) {
> +               acpi_gpiochip_free_interrupts(&gchip->gc);
> +               irq_domain_remove(gchip->gc.irq.domain);
> +       }

Mika can possibly comment on the right way to do ACPI bring-up
and take-down.

Overall it looks pretty straightforward to me, but I'd prefer to just
merge the irqchip driver over into the gpio driver, I can't see why
not.

Or is the irqchip used without the GPIO driver sometimes?

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [RFC PATCH 3/3] gpio: mb86s70: enable ACPI and irqchip support
@ 2019-04-25 13:23     ` Linus Walleij
  0 siblings, 0 replies; 34+ messages in thread
From: Linus Walleij @ 2019-04-25 13:23 UTC (permalink / raw)
  To: Ard Biesheuvel, Mika Westerberg
  Cc: Marc Zyngier, open list:GPIO SUBSYSTEM, Graeme Gregory,
	Linux ARM, Masahisa Kojima

Hi Ard, thanks for your patch!

Including Mika here as well, he knows how ACPI is supposed to
be wired up with GPIOs.

On Thu, Apr 25, 2019 at 12:20 PM Ard Biesheuvel
<ard.biesheuvel@linaro.org> wrote:

> In order to support this GPIO block in combination with an EXIU
> interrupt controller on ACPI systems such as Socionext SynQuacer,
> add the enumeration boilerplate, and add the EXIU irqchip handling
> to the probe path. Also, make the clock handling conditonal on
> non-ACPI enumeration, since ACPI handles this internally.
>
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
(...)

> +config GPIO_MB86S7X_ACPI
> +       def_bool y
> +       depends on ACPI && ARCH_SYNQUACER

I would say

depends on ACPI
depends on (ARCH_SYNQUACER || COMPILE_TEST)

so we get some compiler coverage.

> +#include <linux/acpi.h>
>  #include <linux/io.h>
>  #include <linux/init.h>
>  #include <linux/clk.h>
> @@ -27,6 +28,8 @@
>  #include <linux/spinlock.h>
>  #include <linux/slab.h>
>
> +#include "gpiolib.h"

Normally not a good sign to dereference gpiolib internals,
but there are some few exceptions. Why do you do this?

> +int exiu_acpi_init(struct platform_device *pdev, struct gpio_chip *gc);

Just merge it all into one file instead of having these crisscrossy calls.
I prefer some minor #ifdef or straight C if (IS_ENABLED()) around
specific code.

> -       return ret;
> +       if (mb86s70_gpio_have_acpi(pdev))
> +               acpi_gpiochip_request_interrupts(&gchip->gc);
> +
> +       return 0;

I guess this is right...

>         struct mb86s70_gpio_chip *gchip = platform_get_drvdata(pdev);
>
> +       if (gchip->gc.irq.domain) {
> +               acpi_gpiochip_free_interrupts(&gchip->gc);
> +               irq_domain_remove(gchip->gc.irq.domain);
> +       }

Mika can possibly comment on the right way to do ACPI bring-up
and take-down.

Overall it looks pretty straightforward to me, but I'd prefer to just
merge the irqchip driver over into the gpio driver, I can't see why
not.

Or is the irqchip used without the GPIO driver sometimes?

Yours,
Linus Walleij

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [RFC PATCH 3/3] gpio: mb86s70: enable ACPI and irqchip support
  2019-04-25 13:23     ` Linus Walleij
@ 2019-04-25 13:35       ` Ard Biesheuvel
  -1 siblings, 0 replies; 34+ messages in thread
From: Ard Biesheuvel @ 2019-04-25 13:35 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Graeme Gregory, Marc Zyngier, open list:GPIO SUBSYSTEM,
	Masahisa Kojima, Mika Westerberg, Linux ARM

On Thu, 25 Apr 2019 at 15:24, Linus Walleij <linus.walleij@linaro.org> wrote:
>
> Hi Ard, thanks for your patch!
>
> Including Mika here as well, he knows how ACPI is supposed to
> be wired up with GPIOs.
>
> On Thu, Apr 25, 2019 at 12:20 PM Ard Biesheuvel
> <ard.biesheuvel@linaro.org> wrote:
>
> > In order to support this GPIO block in combination with an EXIU
> > interrupt controller on ACPI systems such as Socionext SynQuacer,
> > add the enumeration boilerplate, and add the EXIU irqchip handling
> > to the probe path. Also, make the clock handling conditonal on
> > non-ACPI enumeration, since ACPI handles this internally.
> >
> > Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> (...)
>
> > +config GPIO_MB86S7X_ACPI
> > +       def_bool y
> > +       depends on ACPI && ARCH_SYNQUACER
>
> I would say
>
> depends on ACPI
> depends on (ARCH_SYNQUACER || COMPILE_TEST)
>
> so we get some compiler coverage.
>
> > +#include <linux/acpi.h>
> >  #include <linux/io.h>
> >  #include <linux/init.h>
> >  #include <linux/clk.h>
> > @@ -27,6 +28,8 @@
> >  #include <linux/spinlock.h>
> >  #include <linux/slab.h>
> >
> > +#include "gpiolib.h"
>
> Normally not a good sign to dereference gpiolib internals,
> but there are some few exceptions. Why do you do this?
>

I needed this for acpi_gpiochip_request_interrupts() et al

> > +int exiu_acpi_init(struct platform_device *pdev, struct gpio_chip *gc);
>
> Just merge it all into one file instead of having these crisscrossy calls.
> I prefer some minor #ifdef or straight C if (IS_ENABLED()) around
> specific code.
>

Fair enough, but please see below.

> > -       return ret;
> > +       if (mb86s70_gpio_have_acpi(pdev))
> > +               acpi_gpiochip_request_interrupts(&gchip->gc);
> > +
> > +       return 0;
>
> I guess this is right...
>
> >         struct mb86s70_gpio_chip *gchip = platform_get_drvdata(pdev);
> >
> > +       if (gchip->gc.irq.domain) {
> > +               acpi_gpiochip_free_interrupts(&gchip->gc);
> > +               irq_domain_remove(gchip->gc.irq.domain);
> > +       }
>
> Mika can possibly comment on the right way to do ACPI bring-up
> and take-down.
>
> Overall it looks pretty straightforward to me, but I'd prefer to just
> merge the irqchip driver over into the gpio driver, I can't see why
> not.
>
> Or is the irqchip used without the GPIO driver sometimes?
>

This is where it becomes a bit nasty: the GPIO controller and the EXIU
interrupt controller are two separate IP blocks, but they are
obviously complimentary. *However*, on SynQuacer, the first 4 physical
lines are not shared between the two, and so you could have 4
interrupt lines handled through the EXIU and 4 different GPIO lines
through the GPIO unit.

On DT, we don't care since we model them as two different units. On
ACPI, however, we cannot model interrupt controllers in the same way,
and so I decided to merge them.

Perhaps the solution is to model the EXIU as a pseudo-GPIO block that
only supports interrupts and not ordinary GPIO?

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [RFC PATCH 3/3] gpio: mb86s70: enable ACPI and irqchip support
@ 2019-04-25 13:35       ` Ard Biesheuvel
  0 siblings, 0 replies; 34+ messages in thread
From: Ard Biesheuvel @ 2019-04-25 13:35 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Graeme Gregory, Marc Zyngier, open list:GPIO SUBSYSTEM,
	Masahisa Kojima, Mika Westerberg, Linux ARM

On Thu, 25 Apr 2019 at 15:24, Linus Walleij <linus.walleij@linaro.org> wrote:
>
> Hi Ard, thanks for your patch!
>
> Including Mika here as well, he knows how ACPI is supposed to
> be wired up with GPIOs.
>
> On Thu, Apr 25, 2019 at 12:20 PM Ard Biesheuvel
> <ard.biesheuvel@linaro.org> wrote:
>
> > In order to support this GPIO block in combination with an EXIU
> > interrupt controller on ACPI systems such as Socionext SynQuacer,
> > add the enumeration boilerplate, and add the EXIU irqchip handling
> > to the probe path. Also, make the clock handling conditonal on
> > non-ACPI enumeration, since ACPI handles this internally.
> >
> > Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> (...)
>
> > +config GPIO_MB86S7X_ACPI
> > +       def_bool y
> > +       depends on ACPI && ARCH_SYNQUACER
>
> I would say
>
> depends on ACPI
> depends on (ARCH_SYNQUACER || COMPILE_TEST)
>
> so we get some compiler coverage.
>
> > +#include <linux/acpi.h>
> >  #include <linux/io.h>
> >  #include <linux/init.h>
> >  #include <linux/clk.h>
> > @@ -27,6 +28,8 @@
> >  #include <linux/spinlock.h>
> >  #include <linux/slab.h>
> >
> > +#include "gpiolib.h"
>
> Normally not a good sign to dereference gpiolib internals,
> but there are some few exceptions. Why do you do this?
>

I needed this for acpi_gpiochip_request_interrupts() et al

> > +int exiu_acpi_init(struct platform_device *pdev, struct gpio_chip *gc);
>
> Just merge it all into one file instead of having these crisscrossy calls.
> I prefer some minor #ifdef or straight C if (IS_ENABLED()) around
> specific code.
>

Fair enough, but please see below.

> > -       return ret;
> > +       if (mb86s70_gpio_have_acpi(pdev))
> > +               acpi_gpiochip_request_interrupts(&gchip->gc);
> > +
> > +       return 0;
>
> I guess this is right...
>
> >         struct mb86s70_gpio_chip *gchip = platform_get_drvdata(pdev);
> >
> > +       if (gchip->gc.irq.domain) {
> > +               acpi_gpiochip_free_interrupts(&gchip->gc);
> > +               irq_domain_remove(gchip->gc.irq.domain);
> > +       }
>
> Mika can possibly comment on the right way to do ACPI bring-up
> and take-down.
>
> Overall it looks pretty straightforward to me, but I'd prefer to just
> merge the irqchip driver over into the gpio driver, I can't see why
> not.
>
> Or is the irqchip used without the GPIO driver sometimes?
>

This is where it becomes a bit nasty: the GPIO controller and the EXIU
interrupt controller are two separate IP blocks, but they are
obviously complimentary. *However*, on SynQuacer, the first 4 physical
lines are not shared between the two, and so you could have 4
interrupt lines handled through the EXIU and 4 different GPIO lines
through the GPIO unit.

On DT, we don't care since we model them as two different units. On
ACPI, however, we cannot model interrupt controllers in the same way,
and so I decided to merge them.

Perhaps the solution is to model the EXIU as a pseudo-GPIO block that
only supports interrupts and not ordinary GPIO?

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [RFC PATCH 3/3] gpio: mb86s70: enable ACPI and irqchip support
  2019-04-25 13:23     ` Linus Walleij
@ 2019-04-25 14:27       ` Mika Westerberg
  -1 siblings, 0 replies; 34+ messages in thread
From: Mika Westerberg @ 2019-04-25 14:27 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Graeme Gregory, Ard Biesheuvel, Marc Zyngier,
	open list:GPIO SUBSYSTEM, Masahisa Kojima, Linux ARM

On Thu, Apr 25, 2019 at 03:23:53PM +0200, Linus Walleij wrote:
> > -       return ret;
> > +       if (mb86s70_gpio_have_acpi(pdev))
> > +               acpi_gpiochip_request_interrupts(&gchip->gc);
> > +
> > +       return 0;
> 
> I guess this is right...
> 
> >         struct mb86s70_gpio_chip *gchip = platform_get_drvdata(pdev);
> >
> > +       if (gchip->gc.irq.domain) {
> > +               acpi_gpiochip_free_interrupts(&gchip->gc);
> > +               irq_domain_remove(gchip->gc.irq.domain);
> > +       }
> 
> Mika can possibly comment on the right way to do ACPI bring-up
> and take-down.

Only comment I have is that normally you don't need to call
acpi_gpiochip_request_interrupts() and acpi_gpiochip_free_interrupts()
in GPIO chip drivers itself. The core should take care of this if the
device ACPI description has an _AEI method.

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [RFC PATCH 3/3] gpio: mb86s70: enable ACPI and irqchip support
@ 2019-04-25 14:27       ` Mika Westerberg
  0 siblings, 0 replies; 34+ messages in thread
From: Mika Westerberg @ 2019-04-25 14:27 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Graeme Gregory, Ard Biesheuvel, Marc Zyngier,
	open list:GPIO SUBSYSTEM, Masahisa Kojima, Linux ARM

On Thu, Apr 25, 2019 at 03:23:53PM +0200, Linus Walleij wrote:
> > -       return ret;
> > +       if (mb86s70_gpio_have_acpi(pdev))
> > +               acpi_gpiochip_request_interrupts(&gchip->gc);
> > +
> > +       return 0;
> 
> I guess this is right...
> 
> >         struct mb86s70_gpio_chip *gchip = platform_get_drvdata(pdev);
> >
> > +       if (gchip->gc.irq.domain) {
> > +               acpi_gpiochip_free_interrupts(&gchip->gc);
> > +               irq_domain_remove(gchip->gc.irq.domain);
> > +       }
> 
> Mika can possibly comment on the right way to do ACPI bring-up
> and take-down.

Only comment I have is that normally you don't need to call
acpi_gpiochip_request_interrupts() and acpi_gpiochip_free_interrupts()
in GPIO chip drivers itself. The core should take care of this if the
device ACPI description has an _AEI method.

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [RFC PATCH 2/3] irqchip/exiu: implement ACPI gpiolib/irqchip support
  2019-04-25 10:20   ` Ard Biesheuvel
@ 2019-04-25 15:33     ` Marc Zyngier
  -1 siblings, 0 replies; 34+ messages in thread
From: Marc Zyngier @ 2019-04-25 15:33 UTC (permalink / raw)
  To: Ard Biesheuvel, linux-arm-kernel
  Cc: linux-gpio, Linus Walleij, Graeme Gregory, Masahisa Kojima

Hi Ard,

On 25/04/2019 11:20, Ard Biesheuvel wrote:
> Expose the existing EXIU hierarchical irqchip domain code to permit
> the interrupt controller to be used as the irqchip component of a
> GPIO controller on ACPI systems.
> 
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> ---
>  drivers/irqchip/irq-sni-exiu.c | 82 +++++++++++++++++---
>  1 file changed, 73 insertions(+), 9 deletions(-)
> 

[...]

> +int exiu_acpi_init(struct platform_device *pdev, struct gpio_chip *gc)
> +{
> +	struct irq_domain *parent_domain = NULL, *domain;
> +	struct resource *res;
> +	int irq;
> +
> +	irq = platform_get_irq(pdev, 0);
> +	if (irq > 0)
> +		parent_domain = irq_get_irq_data(irq)->domain;
> +
> +	if (!parent_domain) {
> +		dev_err(&pdev->dev, "unable to obtain parent domain\n");
> +		return -ENODEV;
> +	}
> +
> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
> +	if (!res) {
> +		dev_err(&pdev->dev, "failed to parse memory resource\n");
> +		return -ENXIO;
> +	}
> +
> +	domain = exiu_init(parent_domain, dev_fwnode(&pdev->dev), res);
> +	if (IS_ERR(domain)) {
> +		dev_err(&pdev->dev, "failed to create IRQ domain (%ld)\n",
> +			PTR_ERR(domain));
> +		return PTR_ERR(domain);
> +	}
> +
> +	gc->irq.domain = domain;
> +	gc->to_irq = exiu_acpi_gpio_to_irq;
> +
> +	dev_info(&pdev->dev, "%d interrupts forwarded\n", NUM_IRQS);
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL(exiu_acpi_init);
> +#endif
> 

I must say I'm not overly keen on this function. Why can't this be
probed as an ACPI device, creating the corresponding domain, and leaving
to the GPIO driver the task of doing the GPIO stuff?

I appreciate there is a dependency between the two, but that's something
we should be able to solve (probe deferral?).

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [RFC PATCH 2/3] irqchip/exiu: implement ACPI gpiolib/irqchip support
@ 2019-04-25 15:33     ` Marc Zyngier
  0 siblings, 0 replies; 34+ messages in thread
From: Marc Zyngier @ 2019-04-25 15:33 UTC (permalink / raw)
  To: Ard Biesheuvel, linux-arm-kernel
  Cc: linux-gpio, Linus Walleij, Graeme Gregory, Masahisa Kojima

Hi Ard,

On 25/04/2019 11:20, Ard Biesheuvel wrote:
> Expose the existing EXIU hierarchical irqchip domain code to permit
> the interrupt controller to be used as the irqchip component of a
> GPIO controller on ACPI systems.
> 
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> ---
>  drivers/irqchip/irq-sni-exiu.c | 82 +++++++++++++++++---
>  1 file changed, 73 insertions(+), 9 deletions(-)
> 

[...]

> +int exiu_acpi_init(struct platform_device *pdev, struct gpio_chip *gc)
> +{
> +	struct irq_domain *parent_domain = NULL, *domain;
> +	struct resource *res;
> +	int irq;
> +
> +	irq = platform_get_irq(pdev, 0);
> +	if (irq > 0)
> +		parent_domain = irq_get_irq_data(irq)->domain;
> +
> +	if (!parent_domain) {
> +		dev_err(&pdev->dev, "unable to obtain parent domain\n");
> +		return -ENODEV;
> +	}
> +
> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
> +	if (!res) {
> +		dev_err(&pdev->dev, "failed to parse memory resource\n");
> +		return -ENXIO;
> +	}
> +
> +	domain = exiu_init(parent_domain, dev_fwnode(&pdev->dev), res);
> +	if (IS_ERR(domain)) {
> +		dev_err(&pdev->dev, "failed to create IRQ domain (%ld)\n",
> +			PTR_ERR(domain));
> +		return PTR_ERR(domain);
> +	}
> +
> +	gc->irq.domain = domain;
> +	gc->to_irq = exiu_acpi_gpio_to_irq;
> +
> +	dev_info(&pdev->dev, "%d interrupts forwarded\n", NUM_IRQS);
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL(exiu_acpi_init);
> +#endif
> 

I must say I'm not overly keen on this function. Why can't this be
probed as an ACPI device, creating the corresponding domain, and leaving
to the GPIO driver the task of doing the GPIO stuff?

I appreciate there is a dependency between the two, but that's something
we should be able to solve (probe deferral?).

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [RFC PATCH 3/3] gpio: mb86s70: enable ACPI and irqchip support
  2019-04-25 14:27       ` Mika Westerberg
@ 2019-04-26  8:19         ` Ard Biesheuvel
  -1 siblings, 0 replies; 34+ messages in thread
From: Ard Biesheuvel @ 2019-04-26  8:19 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: Graeme Gregory, Marc Zyngier, Linus Walleij,
	open list:GPIO SUBSYSTEM, Masahisa Kojima, Linux ARM

On Thu, 25 Apr 2019 at 16:27, Mika Westerberg
<mika.westerberg@linux.intel.com> wrote:
>
> On Thu, Apr 25, 2019 at 03:23:53PM +0200, Linus Walleij wrote:
> > > -       return ret;
> > > +       if (mb86s70_gpio_have_acpi(pdev))
> > > +               acpi_gpiochip_request_interrupts(&gchip->gc);
> > > +
> > > +       return 0;
> >
> > I guess this is right...
> >
> > >         struct mb86s70_gpio_chip *gchip = platform_get_drvdata(pdev);
> > >
> > > +       if (gchip->gc.irq.domain) {
> > > +               acpi_gpiochip_free_interrupts(&gchip->gc);
> > > +               irq_domain_remove(gchip->gc.irq.domain);
> > > +       }
> >
> > Mika can possibly comment on the right way to do ACPI bring-up
> > and take-down.
>
> Only comment I have is that normally you don't need to call
> acpi_gpiochip_request_interrupts() and acpi_gpiochip_free_interrupts()
> in GPIO chip drivers itself. The core should take care of this if the
> device ACPI description has an _AEI method.

Thanks Mika.

The core only takes care of this for nested/cascaded domains. In this
case, the calls are needed, or the ACPI event interrupt don't get
registered.

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [RFC PATCH 3/3] gpio: mb86s70: enable ACPI and irqchip support
@ 2019-04-26  8:19         ` Ard Biesheuvel
  0 siblings, 0 replies; 34+ messages in thread
From: Ard Biesheuvel @ 2019-04-26  8:19 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: Graeme Gregory, Marc Zyngier, Linus Walleij,
	open list:GPIO SUBSYSTEM, Masahisa Kojima, Linux ARM

On Thu, 25 Apr 2019 at 16:27, Mika Westerberg
<mika.westerberg@linux.intel.com> wrote:
>
> On Thu, Apr 25, 2019 at 03:23:53PM +0200, Linus Walleij wrote:
> > > -       return ret;
> > > +       if (mb86s70_gpio_have_acpi(pdev))
> > > +               acpi_gpiochip_request_interrupts(&gchip->gc);
> > > +
> > > +       return 0;
> >
> > I guess this is right...
> >
> > >         struct mb86s70_gpio_chip *gchip = platform_get_drvdata(pdev);
> > >
> > > +       if (gchip->gc.irq.domain) {
> > > +               acpi_gpiochip_free_interrupts(&gchip->gc);
> > > +               irq_domain_remove(gchip->gc.irq.domain);
> > > +       }
> >
> > Mika can possibly comment on the right way to do ACPI bring-up
> > and take-down.
>
> Only comment I have is that normally you don't need to call
> acpi_gpiochip_request_interrupts() and acpi_gpiochip_free_interrupts()
> in GPIO chip drivers itself. The core should take care of this if the
> device ACPI description has an _AEI method.

Thanks Mika.

The core only takes care of this for nested/cascaded domains. In this
case, the calls are needed, or the ACPI event interrupt don't get
registered.

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [RFC PATCH 2/3] irqchip/exiu: implement ACPI gpiolib/irqchip support
  2019-04-25 15:33     ` Marc Zyngier
@ 2019-04-26  8:24       ` Ard Biesheuvel
  -1 siblings, 0 replies; 34+ messages in thread
From: Ard Biesheuvel @ 2019-04-26  8:24 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: open list:GPIO SUBSYSTEM, Linus Walleij, Graeme Gregory,
	linux-arm-kernel, Masahisa Kojima

On Thu, 25 Apr 2019 at 17:33, Marc Zyngier <marc.zyngier@arm.com> wrote:
>
> Hi Ard,
>
> On 25/04/2019 11:20, Ard Biesheuvel wrote:
> > Expose the existing EXIU hierarchical irqchip domain code to permit
> > the interrupt controller to be used as the irqchip component of a
> > GPIO controller on ACPI systems.
> >
> > Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> > ---
> >  drivers/irqchip/irq-sni-exiu.c | 82 +++++++++++++++++---
> >  1 file changed, 73 insertions(+), 9 deletions(-)
> >
>
> [...]
>
> > +int exiu_acpi_init(struct platform_device *pdev, struct gpio_chip *gc)
> > +{
> > +     struct irq_domain *parent_domain = NULL, *domain;
> > +     struct resource *res;
> > +     int irq;
> > +
> > +     irq = platform_get_irq(pdev, 0);
> > +     if (irq > 0)
> > +             parent_domain = irq_get_irq_data(irq)->domain;
> > +
> > +     if (!parent_domain) {
> > +             dev_err(&pdev->dev, "unable to obtain parent domain\n");
> > +             return -ENODEV;
> > +     }
> > +
> > +     res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
> > +     if (!res) {
> > +             dev_err(&pdev->dev, "failed to parse memory resource\n");
> > +             return -ENXIO;
> > +     }
> > +
> > +     domain = exiu_init(parent_domain, dev_fwnode(&pdev->dev), res);
> > +     if (IS_ERR(domain)) {
> > +             dev_err(&pdev->dev, "failed to create IRQ domain (%ld)\n",
> > +                     PTR_ERR(domain));
> > +             return PTR_ERR(domain);
> > +     }
> > +
> > +     gc->irq.domain = domain;
> > +     gc->to_irq = exiu_acpi_gpio_to_irq;
> > +
> > +     dev_info(&pdev->dev, "%d interrupts forwarded\n", NUM_IRQS);
> > +
> > +     return 0;
> > +}
> > +EXPORT_SYMBOL(exiu_acpi_init);
> > +#endif
> >
>
> I must say I'm not overly keen on this function. Why can't this be
> probed as an ACPI device, creating the corresponding domain, and leaving
> to the GPIO driver the task of doing the GPIO stuff?
>

Because ACPI only permits 'system' interrupts or GPIO interrupts, it
does not allow arbitrary device objects in the ACPI namespace to be
targeted as interrupt controllers.

> I appreciate there is a dependency between the two, but that's something
> we should be able to solve (probe deferral?).
>

Perhaps it would be better to just clone the irqchip part into the
GPIO driver? Everything else needs to be modified anyway, including
the domain alloc/translate methods.

That still leaves the question how to deal with the first four signal
lines, which are not shared between the EXIU and the GPIO controller.
but personally, I'm happy to just categorize that as "don't do that"
territory, and just ignore it for the time being.

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [RFC PATCH 2/3] irqchip/exiu: implement ACPI gpiolib/irqchip support
@ 2019-04-26  8:24       ` Ard Biesheuvel
  0 siblings, 0 replies; 34+ messages in thread
From: Ard Biesheuvel @ 2019-04-26  8:24 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: open list:GPIO SUBSYSTEM, Linus Walleij, Graeme Gregory,
	linux-arm-kernel, Masahisa Kojima

On Thu, 25 Apr 2019 at 17:33, Marc Zyngier <marc.zyngier@arm.com> wrote:
>
> Hi Ard,
>
> On 25/04/2019 11:20, Ard Biesheuvel wrote:
> > Expose the existing EXIU hierarchical irqchip domain code to permit
> > the interrupt controller to be used as the irqchip component of a
> > GPIO controller on ACPI systems.
> >
> > Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> > ---
> >  drivers/irqchip/irq-sni-exiu.c | 82 +++++++++++++++++---
> >  1 file changed, 73 insertions(+), 9 deletions(-)
> >
>
> [...]
>
> > +int exiu_acpi_init(struct platform_device *pdev, struct gpio_chip *gc)
> > +{
> > +     struct irq_domain *parent_domain = NULL, *domain;
> > +     struct resource *res;
> > +     int irq;
> > +
> > +     irq = platform_get_irq(pdev, 0);
> > +     if (irq > 0)
> > +             parent_domain = irq_get_irq_data(irq)->domain;
> > +
> > +     if (!parent_domain) {
> > +             dev_err(&pdev->dev, "unable to obtain parent domain\n");
> > +             return -ENODEV;
> > +     }
> > +
> > +     res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
> > +     if (!res) {
> > +             dev_err(&pdev->dev, "failed to parse memory resource\n");
> > +             return -ENXIO;
> > +     }
> > +
> > +     domain = exiu_init(parent_domain, dev_fwnode(&pdev->dev), res);
> > +     if (IS_ERR(domain)) {
> > +             dev_err(&pdev->dev, "failed to create IRQ domain (%ld)\n",
> > +                     PTR_ERR(domain));
> > +             return PTR_ERR(domain);
> > +     }
> > +
> > +     gc->irq.domain = domain;
> > +     gc->to_irq = exiu_acpi_gpio_to_irq;
> > +
> > +     dev_info(&pdev->dev, "%d interrupts forwarded\n", NUM_IRQS);
> > +
> > +     return 0;
> > +}
> > +EXPORT_SYMBOL(exiu_acpi_init);
> > +#endif
> >
>
> I must say I'm not overly keen on this function. Why can't this be
> probed as an ACPI device, creating the corresponding domain, and leaving
> to the GPIO driver the task of doing the GPIO stuff?
>

Because ACPI only permits 'system' interrupts or GPIO interrupts, it
does not allow arbitrary device objects in the ACPI namespace to be
targeted as interrupt controllers.

> I appreciate there is a dependency between the two, but that's something
> we should be able to solve (probe deferral?).
>

Perhaps it would be better to just clone the irqchip part into the
GPIO driver? Everything else needs to be modified anyway, including
the domain alloc/translate methods.

That still leaves the question how to deal with the first four signal
lines, which are not shared between the EXIU and the GPIO controller.
but personally, I'm happy to just categorize that as "don't do that"
territory, and just ignore it for the time being.

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [RFC PATCH 2/3] irqchip/exiu: implement ACPI gpiolib/irqchip support
  2019-04-26  8:24       ` Ard Biesheuvel
@ 2019-04-26  8:44         ` Marc Zyngier
  -1 siblings, 0 replies; 34+ messages in thread
From: Marc Zyngier @ 2019-04-26  8:44 UTC (permalink / raw)
  To: Ard Biesheuvel
  Cc: open list:GPIO SUBSYSTEM, Linus Walleij, Graeme Gregory,
	linux-arm-kernel, Masahisa Kojima

On 26/04/2019 09:24, Ard Biesheuvel wrote:
> On Thu, 25 Apr 2019 at 17:33, Marc Zyngier <marc.zyngier@arm.com> wrote:
>>
>> Hi Ard,
>>
>> On 25/04/2019 11:20, Ard Biesheuvel wrote:
>>> Expose the existing EXIU hierarchical irqchip domain code to permit
>>> the interrupt controller to be used as the irqchip component of a
>>> GPIO controller on ACPI systems.
>>>
>>> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
>>> ---
>>>  drivers/irqchip/irq-sni-exiu.c | 82 +++++++++++++++++---
>>>  1 file changed, 73 insertions(+), 9 deletions(-)
>>>
>>
>> [...]
>>
>>> +int exiu_acpi_init(struct platform_device *pdev, struct gpio_chip *gc)
>>> +{
>>> +     struct irq_domain *parent_domain = NULL, *domain;
>>> +     struct resource *res;
>>> +     int irq;
>>> +
>>> +     irq = platform_get_irq(pdev, 0);
>>> +     if (irq > 0)
>>> +             parent_domain = irq_get_irq_data(irq)->domain;
>>> +
>>> +     if (!parent_domain) {
>>> +             dev_err(&pdev->dev, "unable to obtain parent domain\n");
>>> +             return -ENODEV;
>>> +     }
>>> +
>>> +     res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
>>> +     if (!res) {
>>> +             dev_err(&pdev->dev, "failed to parse memory resource\n");
>>> +             return -ENXIO;
>>> +     }
>>> +
>>> +     domain = exiu_init(parent_domain, dev_fwnode(&pdev->dev), res);
>>> +     if (IS_ERR(domain)) {
>>> +             dev_err(&pdev->dev, "failed to create IRQ domain (%ld)\n",
>>> +                     PTR_ERR(domain));
>>> +             return PTR_ERR(domain);
>>> +     }
>>> +
>>> +     gc->irq.domain = domain;
>>> +     gc->to_irq = exiu_acpi_gpio_to_irq;
>>> +
>>> +     dev_info(&pdev->dev, "%d interrupts forwarded\n", NUM_IRQS);
>>> +
>>> +     return 0;
>>> +}
>>> +EXPORT_SYMBOL(exiu_acpi_init);
>>> +#endif
>>>
>>
>> I must say I'm not overly keen on this function. Why can't this be
>> probed as an ACPI device, creating the corresponding domain, and leaving
>> to the GPIO driver the task of doing the GPIO stuff?
>>
> 
> Because ACPI only permits 'system' interrupts or GPIO interrupts, it
> does not allow arbitrary device objects in the ACPI namespace to be
> targeted as interrupt controllers.

Hmmm. We already have at least one driver (irq-mbigen.c) that does
exactly that. It uses interrupts from the GIC (it is notionally behind
the ITS), and offers a bunch of interrupt lines itself. Why is it different?

> 
>> I appreciate there is a dependency between the two, but that's something
>> we should be able to solve (probe deferral?).
>>
> 
> Perhaps it would be better to just clone the irqchip part into the
> GPIO driver? Everything else needs to be modified anyway, including
> the domain alloc/translate methods.
> 
> That still leaves the question how to deal with the first four signal
> lines, which are not shared between the EXIU and the GPIO controller.
> but personally, I'm happy to just categorize that as "don't do that"
> territory, and just ignore it for the time being.
> 

Maybe. But I'd really like to understand why the above doesn't work in
your case (as you can tell, my ACPI-foo is pretty basic...).

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [RFC PATCH 2/3] irqchip/exiu: implement ACPI gpiolib/irqchip support
@ 2019-04-26  8:44         ` Marc Zyngier
  0 siblings, 0 replies; 34+ messages in thread
From: Marc Zyngier @ 2019-04-26  8:44 UTC (permalink / raw)
  To: Ard Biesheuvel
  Cc: open list:GPIO SUBSYSTEM, Linus Walleij, Graeme Gregory,
	linux-arm-kernel, Masahisa Kojima

On 26/04/2019 09:24, Ard Biesheuvel wrote:
> On Thu, 25 Apr 2019 at 17:33, Marc Zyngier <marc.zyngier@arm.com> wrote:
>>
>> Hi Ard,
>>
>> On 25/04/2019 11:20, Ard Biesheuvel wrote:
>>> Expose the existing EXIU hierarchical irqchip domain code to permit
>>> the interrupt controller to be used as the irqchip component of a
>>> GPIO controller on ACPI systems.
>>>
>>> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
>>> ---
>>>  drivers/irqchip/irq-sni-exiu.c | 82 +++++++++++++++++---
>>>  1 file changed, 73 insertions(+), 9 deletions(-)
>>>
>>
>> [...]
>>
>>> +int exiu_acpi_init(struct platform_device *pdev, struct gpio_chip *gc)
>>> +{
>>> +     struct irq_domain *parent_domain = NULL, *domain;
>>> +     struct resource *res;
>>> +     int irq;
>>> +
>>> +     irq = platform_get_irq(pdev, 0);
>>> +     if (irq > 0)
>>> +             parent_domain = irq_get_irq_data(irq)->domain;
>>> +
>>> +     if (!parent_domain) {
>>> +             dev_err(&pdev->dev, "unable to obtain parent domain\n");
>>> +             return -ENODEV;
>>> +     }
>>> +
>>> +     res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
>>> +     if (!res) {
>>> +             dev_err(&pdev->dev, "failed to parse memory resource\n");
>>> +             return -ENXIO;
>>> +     }
>>> +
>>> +     domain = exiu_init(parent_domain, dev_fwnode(&pdev->dev), res);
>>> +     if (IS_ERR(domain)) {
>>> +             dev_err(&pdev->dev, "failed to create IRQ domain (%ld)\n",
>>> +                     PTR_ERR(domain));
>>> +             return PTR_ERR(domain);
>>> +     }
>>> +
>>> +     gc->irq.domain = domain;
>>> +     gc->to_irq = exiu_acpi_gpio_to_irq;
>>> +
>>> +     dev_info(&pdev->dev, "%d interrupts forwarded\n", NUM_IRQS);
>>> +
>>> +     return 0;
>>> +}
>>> +EXPORT_SYMBOL(exiu_acpi_init);
>>> +#endif
>>>
>>
>> I must say I'm not overly keen on this function. Why can't this be
>> probed as an ACPI device, creating the corresponding domain, and leaving
>> to the GPIO driver the task of doing the GPIO stuff?
>>
> 
> Because ACPI only permits 'system' interrupts or GPIO interrupts, it
> does not allow arbitrary device objects in the ACPI namespace to be
> targeted as interrupt controllers.

Hmmm. We already have at least one driver (irq-mbigen.c) that does
exactly that. It uses interrupts from the GIC (it is notionally behind
the ITS), and offers a bunch of interrupt lines itself. Why is it different?

> 
>> I appreciate there is a dependency between the two, but that's something
>> we should be able to solve (probe deferral?).
>>
> 
> Perhaps it would be better to just clone the irqchip part into the
> GPIO driver? Everything else needs to be modified anyway, including
> the domain alloc/translate methods.
> 
> That still leaves the question how to deal with the first four signal
> lines, which are not shared between the EXIU and the GPIO controller.
> but personally, I'm happy to just categorize that as "don't do that"
> territory, and just ignore it for the time being.
> 

Maybe. But I'd really like to understand why the above doesn't work in
your case (as you can tell, my ACPI-foo is pretty basic...).

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [RFC PATCH 3/3] gpio: mb86s70: enable ACPI and irqchip support
  2019-04-26  8:19         ` Ard Biesheuvel
@ 2019-04-26  9:15           ` Mika Westerberg
  -1 siblings, 0 replies; 34+ messages in thread
From: Mika Westerberg @ 2019-04-26  9:15 UTC (permalink / raw)
  To: Ard Biesheuvel
  Cc: Graeme Gregory, Marc Zyngier, Linus Walleij,
	open list:GPIO SUBSYSTEM, Masahisa Kojima, Linux ARM

On Fri, Apr 26, 2019 at 10:19:42AM +0200, Ard Biesheuvel wrote:
> On Thu, 25 Apr 2019 at 16:27, Mika Westerberg
> <mika.westerberg@linux.intel.com> wrote:
> >
> > On Thu, Apr 25, 2019 at 03:23:53PM +0200, Linus Walleij wrote:
> > > > -       return ret;
> > > > +       if (mb86s70_gpio_have_acpi(pdev))
> > > > +               acpi_gpiochip_request_interrupts(&gchip->gc);
> > > > +
> > > > +       return 0;
> > >
> > > I guess this is right...
> > >
> > > >         struct mb86s70_gpio_chip *gchip = platform_get_drvdata(pdev);
> > > >
> > > > +       if (gchip->gc.irq.domain) {
> > > > +               acpi_gpiochip_free_interrupts(&gchip->gc);
> > > > +               irq_domain_remove(gchip->gc.irq.domain);
> > > > +       }
> > >
> > > Mika can possibly comment on the right way to do ACPI bring-up
> > > and take-down.
> >
> > Only comment I have is that normally you don't need to call
> > acpi_gpiochip_request_interrupts() and acpi_gpiochip_free_interrupts()
> > in GPIO chip drivers itself. The core should take care of this if the
> > device ACPI description has an _AEI method.
> 
> Thanks Mika.
> 
> The core only takes care of this for nested/cascaded domains. In this
> case, the calls are needed, or the ACPI event interrupt don't get
> registered.

I see. Then I agree calling those directly in the driver is the right
thing to do.

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [RFC PATCH 3/3] gpio: mb86s70: enable ACPI and irqchip support
@ 2019-04-26  9:15           ` Mika Westerberg
  0 siblings, 0 replies; 34+ messages in thread
From: Mika Westerberg @ 2019-04-26  9:15 UTC (permalink / raw)
  To: Ard Biesheuvel
  Cc: Graeme Gregory, Marc Zyngier, Linus Walleij,
	open list:GPIO SUBSYSTEM, Masahisa Kojima, Linux ARM

On Fri, Apr 26, 2019 at 10:19:42AM +0200, Ard Biesheuvel wrote:
> On Thu, 25 Apr 2019 at 16:27, Mika Westerberg
> <mika.westerberg@linux.intel.com> wrote:
> >
> > On Thu, Apr 25, 2019 at 03:23:53PM +0200, Linus Walleij wrote:
> > > > -       return ret;
> > > > +       if (mb86s70_gpio_have_acpi(pdev))
> > > > +               acpi_gpiochip_request_interrupts(&gchip->gc);
> > > > +
> > > > +       return 0;
> > >
> > > I guess this is right...
> > >
> > > >         struct mb86s70_gpio_chip *gchip = platform_get_drvdata(pdev);
> > > >
> > > > +       if (gchip->gc.irq.domain) {
> > > > +               acpi_gpiochip_free_interrupts(&gchip->gc);
> > > > +               irq_domain_remove(gchip->gc.irq.domain);
> > > > +       }
> > >
> > > Mika can possibly comment on the right way to do ACPI bring-up
> > > and take-down.
> >
> > Only comment I have is that normally you don't need to call
> > acpi_gpiochip_request_interrupts() and acpi_gpiochip_free_interrupts()
> > in GPIO chip drivers itself. The core should take care of this if the
> > device ACPI description has an _AEI method.
> 
> Thanks Mika.
> 
> The core only takes care of this for nested/cascaded domains. In this
> case, the calls are needed, or the ACPI event interrupt don't get
> registered.

I see. Then I agree calling those directly in the driver is the right
thing to do.

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [RFC PATCH 2/3] irqchip/exiu: implement ACPI gpiolib/irqchip support
  2019-04-26  8:44         ` Marc Zyngier
@ 2019-04-26 11:45           ` Ard Biesheuvel
  -1 siblings, 0 replies; 34+ messages in thread
From: Ard Biesheuvel @ 2019-04-26 11:45 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: open list:GPIO SUBSYSTEM, Linus Walleij, Graeme Gregory,
	linux-arm-kernel, Masahisa Kojima

On Fri, 26 Apr 2019 at 10:44, Marc Zyngier <marc.zyngier@arm.com> wrote:
>
> On 26/04/2019 09:24, Ard Biesheuvel wrote:
> > On Thu, 25 Apr 2019 at 17:33, Marc Zyngier <marc.zyngier@arm.com> wrote:
> >>
> >> Hi Ard,
> >>
> >> On 25/04/2019 11:20, Ard Biesheuvel wrote:
> >>> Expose the existing EXIU hierarchical irqchip domain code to permit
> >>> the interrupt controller to be used as the irqchip component of a
> >>> GPIO controller on ACPI systems.
> >>>
> >>> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> >>> ---
> >>>  drivers/irqchip/irq-sni-exiu.c | 82 +++++++++++++++++---
> >>>  1 file changed, 73 insertions(+), 9 deletions(-)
> >>>
> >>
> >> [...]
> >>
> >>> +int exiu_acpi_init(struct platform_device *pdev, struct gpio_chip *gc)
> >>> +{
> >>> +     struct irq_domain *parent_domain = NULL, *domain;
> >>> +     struct resource *res;
> >>> +     int irq;
> >>> +
> >>> +     irq = platform_get_irq(pdev, 0);
> >>> +     if (irq > 0)
> >>> +             parent_domain = irq_get_irq_data(irq)->domain;
> >>> +
> >>> +     if (!parent_domain) {
> >>> +             dev_err(&pdev->dev, "unable to obtain parent domain\n");
> >>> +             return -ENODEV;
> >>> +     }
> >>> +
> >>> +     res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
> >>> +     if (!res) {
> >>> +             dev_err(&pdev->dev, "failed to parse memory resource\n");
> >>> +             return -ENXIO;
> >>> +     }
> >>> +
> >>> +     domain = exiu_init(parent_domain, dev_fwnode(&pdev->dev), res);
> >>> +     if (IS_ERR(domain)) {
> >>> +             dev_err(&pdev->dev, "failed to create IRQ domain (%ld)\n",
> >>> +                     PTR_ERR(domain));
> >>> +             return PTR_ERR(domain);
> >>> +     }
> >>> +
> >>> +     gc->irq.domain = domain;
> >>> +     gc->to_irq = exiu_acpi_gpio_to_irq;
> >>> +
> >>> +     dev_info(&pdev->dev, "%d interrupts forwarded\n", NUM_IRQS);
> >>> +
> >>> +     return 0;
> >>> +}
> >>> +EXPORT_SYMBOL(exiu_acpi_init);
> >>> +#endif
> >>>
> >>
> >> I must say I'm not overly keen on this function. Why can't this be
> >> probed as an ACPI device, creating the corresponding domain, and leaving
> >> to the GPIO driver the task of doing the GPIO stuff?
> >>
> >
> > Because ACPI only permits 'system' interrupts or GPIO interrupts, it
> > does not allow arbitrary device objects in the ACPI namespace to be
> > targeted as interrupt controllers.
>
> Hmmm. We already have at least one driver (irq-mbigen.c) that does
> exactly that. It uses interrupts from the GIC (it is notionally behind
> the ITS), and offers a bunch of interrupt lines itself. Why is it different?
>

You are right, it isn't. It turns out that there is another way to
signal ACPI events based on interrupts, and it involves the ACPI0013
GED device. I will try to model it that way instead.

> >
> >> I appreciate there is a dependency between the two, but that's something
> >> we should be able to solve (probe deferral?).
> >>
> >
> > Perhaps it would be better to just clone the irqchip part into the
> > GPIO driver? Everything else needs to be modified anyway, including
> > the domain alloc/translate methods.
> >
> > That still leaves the question how to deal with the first four signal
> > lines, which are not shared between the EXIU and the GPIO controller.
> > but personally, I'm happy to just categorize that as "don't do that"
> > territory, and just ignore it for the time being.
> >
>
> Maybe. But I'd really like to understand why the above doesn't work in
> your case (as you can tell, my ACPI-foo is pretty basic...).
>

As is mine. I am just trying to make sense of all of this so we can
report non-fatal RAS errors via ACPI events.

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [RFC PATCH 2/3] irqchip/exiu: implement ACPI gpiolib/irqchip support
@ 2019-04-26 11:45           ` Ard Biesheuvel
  0 siblings, 0 replies; 34+ messages in thread
From: Ard Biesheuvel @ 2019-04-26 11:45 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: open list:GPIO SUBSYSTEM, Linus Walleij, Graeme Gregory,
	linux-arm-kernel, Masahisa Kojima

On Fri, 26 Apr 2019 at 10:44, Marc Zyngier <marc.zyngier@arm.com> wrote:
>
> On 26/04/2019 09:24, Ard Biesheuvel wrote:
> > On Thu, 25 Apr 2019 at 17:33, Marc Zyngier <marc.zyngier@arm.com> wrote:
> >>
> >> Hi Ard,
> >>
> >> On 25/04/2019 11:20, Ard Biesheuvel wrote:
> >>> Expose the existing EXIU hierarchical irqchip domain code to permit
> >>> the interrupt controller to be used as the irqchip component of a
> >>> GPIO controller on ACPI systems.
> >>>
> >>> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> >>> ---
> >>>  drivers/irqchip/irq-sni-exiu.c | 82 +++++++++++++++++---
> >>>  1 file changed, 73 insertions(+), 9 deletions(-)
> >>>
> >>
> >> [...]
> >>
> >>> +int exiu_acpi_init(struct platform_device *pdev, struct gpio_chip *gc)
> >>> +{
> >>> +     struct irq_domain *parent_domain = NULL, *domain;
> >>> +     struct resource *res;
> >>> +     int irq;
> >>> +
> >>> +     irq = platform_get_irq(pdev, 0);
> >>> +     if (irq > 0)
> >>> +             parent_domain = irq_get_irq_data(irq)->domain;
> >>> +
> >>> +     if (!parent_domain) {
> >>> +             dev_err(&pdev->dev, "unable to obtain parent domain\n");
> >>> +             return -ENODEV;
> >>> +     }
> >>> +
> >>> +     res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
> >>> +     if (!res) {
> >>> +             dev_err(&pdev->dev, "failed to parse memory resource\n");
> >>> +             return -ENXIO;
> >>> +     }
> >>> +
> >>> +     domain = exiu_init(parent_domain, dev_fwnode(&pdev->dev), res);
> >>> +     if (IS_ERR(domain)) {
> >>> +             dev_err(&pdev->dev, "failed to create IRQ domain (%ld)\n",
> >>> +                     PTR_ERR(domain));
> >>> +             return PTR_ERR(domain);
> >>> +     }
> >>> +
> >>> +     gc->irq.domain = domain;
> >>> +     gc->to_irq = exiu_acpi_gpio_to_irq;
> >>> +
> >>> +     dev_info(&pdev->dev, "%d interrupts forwarded\n", NUM_IRQS);
> >>> +
> >>> +     return 0;
> >>> +}
> >>> +EXPORT_SYMBOL(exiu_acpi_init);
> >>> +#endif
> >>>
> >>
> >> I must say I'm not overly keen on this function. Why can't this be
> >> probed as an ACPI device, creating the corresponding domain, and leaving
> >> to the GPIO driver the task of doing the GPIO stuff?
> >>
> >
> > Because ACPI only permits 'system' interrupts or GPIO interrupts, it
> > does not allow arbitrary device objects in the ACPI namespace to be
> > targeted as interrupt controllers.
>
> Hmmm. We already have at least one driver (irq-mbigen.c) that does
> exactly that. It uses interrupts from the GIC (it is notionally behind
> the ITS), and offers a bunch of interrupt lines itself. Why is it different?
>

You are right, it isn't. It turns out that there is another way to
signal ACPI events based on interrupts, and it involves the ACPI0013
GED device. I will try to model it that way instead.

> >
> >> I appreciate there is a dependency between the two, but that's something
> >> we should be able to solve (probe deferral?).
> >>
> >
> > Perhaps it would be better to just clone the irqchip part into the
> > GPIO driver? Everything else needs to be modified anyway, including
> > the domain alloc/translate methods.
> >
> > That still leaves the question how to deal with the first four signal
> > lines, which are not shared between the EXIU and the GPIO controller.
> > but personally, I'm happy to just categorize that as "don't do that"
> > territory, and just ignore it for the time being.
> >
>
> Maybe. But I'd really like to understand why the above doesn't work in
> your case (as you can tell, my ACPI-foo is pretty basic...).
>

As is mine. I am just trying to make sense of all of this so we can
report non-fatal RAS errors via ACPI events.

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [RFC PATCH 2/3] irqchip/exiu: implement ACPI gpiolib/irqchip support
  2019-04-26 11:45           ` Ard Biesheuvel
@ 2019-04-26 22:27             ` Ard Biesheuvel
  -1 siblings, 0 replies; 34+ messages in thread
From: Ard Biesheuvel @ 2019-04-26 22:27 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: open list:GPIO SUBSYSTEM, Linus Walleij, Graeme Gregory,
	linux-arm-kernel, Masahisa Kojima

On Fri, 26 Apr 2019 at 13:45, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote:
>
> On Fri, 26 Apr 2019 at 10:44, Marc Zyngier <marc.zyngier@arm.com> wrote:
> >
> > On 26/04/2019 09:24, Ard Biesheuvel wrote:
> > > On Thu, 25 Apr 2019 at 17:33, Marc Zyngier <marc.zyngier@arm.com> wrote:
> > >>
> > >> Hi Ard,
> > >>
> > >> On 25/04/2019 11:20, Ard Biesheuvel wrote:
> > >>> Expose the existing EXIU hierarchical irqchip domain code to permit
> > >>> the interrupt controller to be used as the irqchip component of a
> > >>> GPIO controller on ACPI systems.
> > >>>
> > >>> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> > >>> ---
> > >>>  drivers/irqchip/irq-sni-exiu.c | 82 +++++++++++++++++---
> > >>>  1 file changed, 73 insertions(+), 9 deletions(-)
> > >>>
> > >>
> > >> [...]
> > >>
> > >>> +int exiu_acpi_init(struct platform_device *pdev, struct gpio_chip *gc)
> > >>> +{
> > >>> +     struct irq_domain *parent_domain = NULL, *domain;
> > >>> +     struct resource *res;
> > >>> +     int irq;
> > >>> +
> > >>> +     irq = platform_get_irq(pdev, 0);
> > >>> +     if (irq > 0)
> > >>> +             parent_domain = irq_get_irq_data(irq)->domain;
> > >>> +
> > >>> +     if (!parent_domain) {
> > >>> +             dev_err(&pdev->dev, "unable to obtain parent domain\n");
> > >>> +             return -ENODEV;
> > >>> +     }
> > >>> +
> > >>> +     res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
> > >>> +     if (!res) {
> > >>> +             dev_err(&pdev->dev, "failed to parse memory resource\n");
> > >>> +             return -ENXIO;
> > >>> +     }
> > >>> +
> > >>> +     domain = exiu_init(parent_domain, dev_fwnode(&pdev->dev), res);
> > >>> +     if (IS_ERR(domain)) {
> > >>> +             dev_err(&pdev->dev, "failed to create IRQ domain (%ld)\n",
> > >>> +                     PTR_ERR(domain));
> > >>> +             return PTR_ERR(domain);
> > >>> +     }
> > >>> +
> > >>> +     gc->irq.domain = domain;
> > >>> +     gc->to_irq = exiu_acpi_gpio_to_irq;
> > >>> +
> > >>> +     dev_info(&pdev->dev, "%d interrupts forwarded\n", NUM_IRQS);
> > >>> +
> > >>> +     return 0;
> > >>> +}
> > >>> +EXPORT_SYMBOL(exiu_acpi_init);
> > >>> +#endif
> > >>>
> > >>
> > >> I must say I'm not overly keen on this function. Why can't this be
> > >> probed as an ACPI device, creating the corresponding domain, and leaving
> > >> to the GPIO driver the task of doing the GPIO stuff?
> > >>
> > >
> > > Because ACPI only permits 'system' interrupts or GPIO interrupts, it
> > > does not allow arbitrary device objects in the ACPI namespace to be
> > > targeted as interrupt controllers.
> >
> > Hmmm. We already have at least one driver (irq-mbigen.c) that does
> > exactly that. It uses interrupts from the GIC (it is notionally behind
> > the ITS), and offers a bunch of interrupt lines itself. Why is it different?
> >
>
> You are right, it isn't. It turns out that there is another way to
> signal ACPI events based on interrupts, and it involves the ACPI0013
> GED device. I will try to model it that way instead.
>

Unfortunately, this doesn't work either. The GED device can respond to
GSIVs only, and so going via the EXIU doesn't work.

I have attempted to hack it up via AML, but the GED driver uses a
threaded interrupt, and so the interrupt is re-enabled at the GIC
before the AML handler is executed (which clears it in the EXIU)

For the RAS case, I guess we could let the firmware pick an arbitrary
unused SPI and signal that directly into the GIC, but for the power
button (which is physically wired to the EXIU), we have to model the
EXIU either has a separate pseudo-GPIO controller, or as part of the
real GPIO block.

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [RFC PATCH 2/3] irqchip/exiu: implement ACPI gpiolib/irqchip support
@ 2019-04-26 22:27             ` Ard Biesheuvel
  0 siblings, 0 replies; 34+ messages in thread
From: Ard Biesheuvel @ 2019-04-26 22:27 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: open list:GPIO SUBSYSTEM, Linus Walleij, Graeme Gregory,
	linux-arm-kernel, Masahisa Kojima

On Fri, 26 Apr 2019 at 13:45, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote:
>
> On Fri, 26 Apr 2019 at 10:44, Marc Zyngier <marc.zyngier@arm.com> wrote:
> >
> > On 26/04/2019 09:24, Ard Biesheuvel wrote:
> > > On Thu, 25 Apr 2019 at 17:33, Marc Zyngier <marc.zyngier@arm.com> wrote:
> > >>
> > >> Hi Ard,
> > >>
> > >> On 25/04/2019 11:20, Ard Biesheuvel wrote:
> > >>> Expose the existing EXIU hierarchical irqchip domain code to permit
> > >>> the interrupt controller to be used as the irqchip component of a
> > >>> GPIO controller on ACPI systems.
> > >>>
> > >>> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> > >>> ---
> > >>>  drivers/irqchip/irq-sni-exiu.c | 82 +++++++++++++++++---
> > >>>  1 file changed, 73 insertions(+), 9 deletions(-)
> > >>>
> > >>
> > >> [...]
> > >>
> > >>> +int exiu_acpi_init(struct platform_device *pdev, struct gpio_chip *gc)
> > >>> +{
> > >>> +     struct irq_domain *parent_domain = NULL, *domain;
> > >>> +     struct resource *res;
> > >>> +     int irq;
> > >>> +
> > >>> +     irq = platform_get_irq(pdev, 0);
> > >>> +     if (irq > 0)
> > >>> +             parent_domain = irq_get_irq_data(irq)->domain;
> > >>> +
> > >>> +     if (!parent_domain) {
> > >>> +             dev_err(&pdev->dev, "unable to obtain parent domain\n");
> > >>> +             return -ENODEV;
> > >>> +     }
> > >>> +
> > >>> +     res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
> > >>> +     if (!res) {
> > >>> +             dev_err(&pdev->dev, "failed to parse memory resource\n");
> > >>> +             return -ENXIO;
> > >>> +     }
> > >>> +
> > >>> +     domain = exiu_init(parent_domain, dev_fwnode(&pdev->dev), res);
> > >>> +     if (IS_ERR(domain)) {
> > >>> +             dev_err(&pdev->dev, "failed to create IRQ domain (%ld)\n",
> > >>> +                     PTR_ERR(domain));
> > >>> +             return PTR_ERR(domain);
> > >>> +     }
> > >>> +
> > >>> +     gc->irq.domain = domain;
> > >>> +     gc->to_irq = exiu_acpi_gpio_to_irq;
> > >>> +
> > >>> +     dev_info(&pdev->dev, "%d interrupts forwarded\n", NUM_IRQS);
> > >>> +
> > >>> +     return 0;
> > >>> +}
> > >>> +EXPORT_SYMBOL(exiu_acpi_init);
> > >>> +#endif
> > >>>
> > >>
> > >> I must say I'm not overly keen on this function. Why can't this be
> > >> probed as an ACPI device, creating the corresponding domain, and leaving
> > >> to the GPIO driver the task of doing the GPIO stuff?
> > >>
> > >
> > > Because ACPI only permits 'system' interrupts or GPIO interrupts, it
> > > does not allow arbitrary device objects in the ACPI namespace to be
> > > targeted as interrupt controllers.
> >
> > Hmmm. We already have at least one driver (irq-mbigen.c) that does
> > exactly that. It uses interrupts from the GIC (it is notionally behind
> > the ITS), and offers a bunch of interrupt lines itself. Why is it different?
> >
>
> You are right, it isn't. It turns out that there is another way to
> signal ACPI events based on interrupts, and it involves the ACPI0013
> GED device. I will try to model it that way instead.
>

Unfortunately, this doesn't work either. The GED device can respond to
GSIVs only, and so going via the EXIU doesn't work.

I have attempted to hack it up via AML, but the GED driver uses a
threaded interrupt, and so the interrupt is re-enabled at the GIC
before the AML handler is executed (which clears it in the EXIU)

For the RAS case, I guess we could let the firmware pick an arbitrary
unused SPI and signal that directly into the GIC, but for the power
button (which is physically wired to the EXIU), we have to model the
EXIU either has a separate pseudo-GPIO controller, or as part of the
real GPIO block.

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [RFC PATCH 2/3] irqchip/exiu: implement ACPI gpiolib/irqchip support
  2019-04-26 22:27             ` Ard Biesheuvel
@ 2019-04-29  9:09               ` Ard Biesheuvel
  -1 siblings, 0 replies; 34+ messages in thread
From: Ard Biesheuvel @ 2019-04-29  9:09 UTC (permalink / raw)
  To: Marc Zyngier, Mika Westerberg
  Cc: open list:GPIO SUBSYSTEM, Linus Walleij, Graeme Gregory,
	linux-arm-kernel, Masahisa Kojima

On Sat, 27 Apr 2019 at 00:27, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote:
>
> On Fri, 26 Apr 2019 at 13:45, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote:
> >
> > On Fri, 26 Apr 2019 at 10:44, Marc Zyngier <marc.zyngier@arm.com> wrote:
> > >
> > > On 26/04/2019 09:24, Ard Biesheuvel wrote:
> > > > On Thu, 25 Apr 2019 at 17:33, Marc Zyngier <marc.zyngier@arm.com> wrote:
> > > >>
> > > >> Hi Ard,
> > > >>
> > > >> On 25/04/2019 11:20, Ard Biesheuvel wrote:
> > > >>> Expose the existing EXIU hierarchical irqchip domain code to permit
> > > >>> the interrupt controller to be used as the irqchip component of a
> > > >>> GPIO controller on ACPI systems.
> > > >>>
> > > >>> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> > > >>> ---
> > > >>>  drivers/irqchip/irq-sni-exiu.c | 82 +++++++++++++++++---
> > > >>>  1 file changed, 73 insertions(+), 9 deletions(-)
> > > >>>
> > > >>
> > > >> [...]
> > > >>
> > > >>> +int exiu_acpi_init(struct platform_device *pdev, struct gpio_chip *gc)
> > > >>> +{
> > > >>> +     struct irq_domain *parent_domain = NULL, *domain;
> > > >>> +     struct resource *res;
> > > >>> +     int irq;
> > > >>> +
> > > >>> +     irq = platform_get_irq(pdev, 0);
> > > >>> +     if (irq > 0)
> > > >>> +             parent_domain = irq_get_irq_data(irq)->domain;
> > > >>> +
> > > >>> +     if (!parent_domain) {
> > > >>> +             dev_err(&pdev->dev, "unable to obtain parent domain\n");
> > > >>> +             return -ENODEV;
> > > >>> +     }
> > > >>> +
> > > >>> +     res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
> > > >>> +     if (!res) {
> > > >>> +             dev_err(&pdev->dev, "failed to parse memory resource\n");
> > > >>> +             return -ENXIO;
> > > >>> +     }
> > > >>> +
> > > >>> +     domain = exiu_init(parent_domain, dev_fwnode(&pdev->dev), res);
> > > >>> +     if (IS_ERR(domain)) {
> > > >>> +             dev_err(&pdev->dev, "failed to create IRQ domain (%ld)\n",
> > > >>> +                     PTR_ERR(domain));
> > > >>> +             return PTR_ERR(domain);
> > > >>> +     }
> > > >>> +
> > > >>> +     gc->irq.domain = domain;
> > > >>> +     gc->to_irq = exiu_acpi_gpio_to_irq;
> > > >>> +
> > > >>> +     dev_info(&pdev->dev, "%d interrupts forwarded\n", NUM_IRQS);
> > > >>> +
> > > >>> +     return 0;
> > > >>> +}
> > > >>> +EXPORT_SYMBOL(exiu_acpi_init);
> > > >>> +#endif
> > > >>>
> > > >>
> > > >> I must say I'm not overly keen on this function. Why can't this be
> > > >> probed as an ACPI device, creating the corresponding domain, and leaving
> > > >> to the GPIO driver the task of doing the GPIO stuff?
> > > >>
> > > >
> > > > Because ACPI only permits 'system' interrupts or GPIO interrupts, it
> > > > does not allow arbitrary device objects in the ACPI namespace to be
> > > > targeted as interrupt controllers.
> > >
> > > Hmmm. We already have at least one driver (irq-mbigen.c) that does
> > > exactly that. It uses interrupts from the GIC (it is notionally behind
> > > the ITS), and offers a bunch of interrupt lines itself. Why is it different?
> > >
> >
> > You are right, it isn't. It turns out that there is another way to
> > signal ACPI events based on interrupts, and it involves the ACPI0013
> > GED device. I will try to model it that way instead.
> >
>
> Unfortunately, this doesn't work either. The GED device can respond to
> GSIVs only, and so going via the EXIU doesn't work.
>
> I have attempted to hack it up via AML, but the GED driver uses a
> threaded interrupt, and so the interrupt is re-enabled at the GIC
> before the AML handler is executed (which clears it in the EXIU)
>
> For the RAS case, I guess we could let the firmware pick an arbitrary
> unused SPI and signal that directly into the GIC, but for the power
> button (which is physically wired to the EXIU), we have to model the
> EXIU either has a separate pseudo-GPIO controller, or as part of the
> real GPIO block.

(+ Mika)

I made some progress describing the EXIU and GPIO controllers as follow.

    Device (EXIU) {
      Name (_HID, "SCX0008")
      Name (_UID, Zero)
      Name (_CRS, ResourceTemplate () {
        Memory32Fixed (ReadWrite, SYNQUACER_EXIU_BASE, SYNQUACER_EXIU_SIZE)
        Interrupt (ResourceConsumer, Level, ActiveHigh, ExclusiveAndWake) {
          144, 145, 146, 147, 148, 149, 150, 151,
          152, 153, 154, 155, 156, 157, 158, 159,
          160, 161, 162, 163, 164, 165, 166, 167,
          168, 169, 170, 171, 172, 173, 174, 175,
        }
      })
      Name (_DSD, Package () {
        ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
        Package () {
          Package () { "socionext,spi-base", 112 },
        }
      })
    }

and

    Device (GPIO) {
      Name (_HID, "SCX0007")
      Name (_UID, Zero)
      Name (_CRS, ResourceTemplate () {
        Memory32Fixed (ReadWrite, SYNQUACER_GPIO_BASE, SYNQUACER_GPIO_SIZE)
        Interrupt (ResourceConsumer, Edge, ActiveLow,
ExclusiveAndWake, 0, "\\_SB.EXIU") {
          7,
        }
      })
      Name (_AEI, ResourceTemplate () {
        GpioInt (Edge, ActiveHigh, ExclusiveAndWake, PullDefault, 0,
"\\_SB.GPIO")
        {
          7
        }
      })
      Method (_E07) {
        Notify (\_SB.PWRB, 0x80)
      }
    }

This is actually a fairly accurate depiction of reality: the EXIU is a
separate unit, and only some of the GPIOs are routed through it.

In the GPIO controller's to_irq() callback, I return the Linux IRQ
number based on the platform IRQ resources claimed by the GPIO device,
and I end up with something like

 46:          0 ... 0      EXIU   7 Edge      ACPI:Event

which looks correct to me. debugfs tells me it is mapped as

handler:  handle_fasteoi_irq
device:   (null)
status:   0x00000001
istate:   0x00000020
            IRQS_ONESHOT
ddepth:   0
wdepth:   1
dstate:   0x03404201
            IRQ_TYPE_EDGE_RISING
            IRQD_ACTIVATED
            IRQD_IRQ_STARTED
            IRQD_SINGLE_TARGET
            IRQD_WAKEUP_STATE
node:     0
affinity: 0-23
effectiv: 0
domain:  \_SB_.EXIU
 hwirq:   0x7
 chip:    EXIU
  flags:   0x55
             IRQCHIP_SET_TYPE_MASKED
             IRQCHIP_MASK_ON_SUSPEND
             IRQCHIP_SKIP_SET_WAKE
             IRQCHIP_EOI_THREADED
 parent:
    domain:  irqchip@(____ptrval____)-1
     hwirq:   0x97
     chip:    GICv3
      flags:   0x15
                 IRQCHIP_SET_TYPE_MASKED
                 IRQCHIP_MASK_ON_SUSPEND
                 IRQCHIP_SKIP_SET_WAKE

The EXIU domain is described as

name:   \_SB_.EXIU
 size:   32
 mapped: 1
 flags:  0x00000041
 parent: irqchip@(____ptrval____)-1
    name:   irqchip@(____ptrval____)-1
     size:   0
     mapped: 55
     flags:  0x00000041

Unfortunately, the system locks up entirely as soon as the interrupt
is triggered (I use a DIP switch in this case). So while the
description is accurate and the correct interrupt does get mapped,
something is still not working entirely as expected.

Any thoughts?

Thanks,
Ard.

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [RFC PATCH 2/3] irqchip/exiu: implement ACPI gpiolib/irqchip support
@ 2019-04-29  9:09               ` Ard Biesheuvel
  0 siblings, 0 replies; 34+ messages in thread
From: Ard Biesheuvel @ 2019-04-29  9:09 UTC (permalink / raw)
  To: Marc Zyngier, Mika Westerberg
  Cc: open list:GPIO SUBSYSTEM, Linus Walleij, Graeme Gregory,
	linux-arm-kernel, Masahisa Kojima

On Sat, 27 Apr 2019 at 00:27, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote:
>
> On Fri, 26 Apr 2019 at 13:45, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote:
> >
> > On Fri, 26 Apr 2019 at 10:44, Marc Zyngier <marc.zyngier@arm.com> wrote:
> > >
> > > On 26/04/2019 09:24, Ard Biesheuvel wrote:
> > > > On Thu, 25 Apr 2019 at 17:33, Marc Zyngier <marc.zyngier@arm.com> wrote:
> > > >>
> > > >> Hi Ard,
> > > >>
> > > >> On 25/04/2019 11:20, Ard Biesheuvel wrote:
> > > >>> Expose the existing EXIU hierarchical irqchip domain code to permit
> > > >>> the interrupt controller to be used as the irqchip component of a
> > > >>> GPIO controller on ACPI systems.
> > > >>>
> > > >>> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> > > >>> ---
> > > >>>  drivers/irqchip/irq-sni-exiu.c | 82 +++++++++++++++++---
> > > >>>  1 file changed, 73 insertions(+), 9 deletions(-)
> > > >>>
> > > >>
> > > >> [...]
> > > >>
> > > >>> +int exiu_acpi_init(struct platform_device *pdev, struct gpio_chip *gc)
> > > >>> +{
> > > >>> +     struct irq_domain *parent_domain = NULL, *domain;
> > > >>> +     struct resource *res;
> > > >>> +     int irq;
> > > >>> +
> > > >>> +     irq = platform_get_irq(pdev, 0);
> > > >>> +     if (irq > 0)
> > > >>> +             parent_domain = irq_get_irq_data(irq)->domain;
> > > >>> +
> > > >>> +     if (!parent_domain) {
> > > >>> +             dev_err(&pdev->dev, "unable to obtain parent domain\n");
> > > >>> +             return -ENODEV;
> > > >>> +     }
> > > >>> +
> > > >>> +     res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
> > > >>> +     if (!res) {
> > > >>> +             dev_err(&pdev->dev, "failed to parse memory resource\n");
> > > >>> +             return -ENXIO;
> > > >>> +     }
> > > >>> +
> > > >>> +     domain = exiu_init(parent_domain, dev_fwnode(&pdev->dev), res);
> > > >>> +     if (IS_ERR(domain)) {
> > > >>> +             dev_err(&pdev->dev, "failed to create IRQ domain (%ld)\n",
> > > >>> +                     PTR_ERR(domain));
> > > >>> +             return PTR_ERR(domain);
> > > >>> +     }
> > > >>> +
> > > >>> +     gc->irq.domain = domain;
> > > >>> +     gc->to_irq = exiu_acpi_gpio_to_irq;
> > > >>> +
> > > >>> +     dev_info(&pdev->dev, "%d interrupts forwarded\n", NUM_IRQS);
> > > >>> +
> > > >>> +     return 0;
> > > >>> +}
> > > >>> +EXPORT_SYMBOL(exiu_acpi_init);
> > > >>> +#endif
> > > >>>
> > > >>
> > > >> I must say I'm not overly keen on this function. Why can't this be
> > > >> probed as an ACPI device, creating the corresponding domain, and leaving
> > > >> to the GPIO driver the task of doing the GPIO stuff?
> > > >>
> > > >
> > > > Because ACPI only permits 'system' interrupts or GPIO interrupts, it
> > > > does not allow arbitrary device objects in the ACPI namespace to be
> > > > targeted as interrupt controllers.
> > >
> > > Hmmm. We already have at least one driver (irq-mbigen.c) that does
> > > exactly that. It uses interrupts from the GIC (it is notionally behind
> > > the ITS), and offers a bunch of interrupt lines itself. Why is it different?
> > >
> >
> > You are right, it isn't. It turns out that there is another way to
> > signal ACPI events based on interrupts, and it involves the ACPI0013
> > GED device. I will try to model it that way instead.
> >
>
> Unfortunately, this doesn't work either. The GED device can respond to
> GSIVs only, and so going via the EXIU doesn't work.
>
> I have attempted to hack it up via AML, but the GED driver uses a
> threaded interrupt, and so the interrupt is re-enabled at the GIC
> before the AML handler is executed (which clears it in the EXIU)
>
> For the RAS case, I guess we could let the firmware pick an arbitrary
> unused SPI and signal that directly into the GIC, but for the power
> button (which is physically wired to the EXIU), we have to model the
> EXIU either has a separate pseudo-GPIO controller, or as part of the
> real GPIO block.

(+ Mika)

I made some progress describing the EXIU and GPIO controllers as follow.

    Device (EXIU) {
      Name (_HID, "SCX0008")
      Name (_UID, Zero)
      Name (_CRS, ResourceTemplate () {
        Memory32Fixed (ReadWrite, SYNQUACER_EXIU_BASE, SYNQUACER_EXIU_SIZE)
        Interrupt (ResourceConsumer, Level, ActiveHigh, ExclusiveAndWake) {
          144, 145, 146, 147, 148, 149, 150, 151,
          152, 153, 154, 155, 156, 157, 158, 159,
          160, 161, 162, 163, 164, 165, 166, 167,
          168, 169, 170, 171, 172, 173, 174, 175,
        }
      })
      Name (_DSD, Package () {
        ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
        Package () {
          Package () { "socionext,spi-base", 112 },
        }
      })
    }

and

    Device (GPIO) {
      Name (_HID, "SCX0007")
      Name (_UID, Zero)
      Name (_CRS, ResourceTemplate () {
        Memory32Fixed (ReadWrite, SYNQUACER_GPIO_BASE, SYNQUACER_GPIO_SIZE)
        Interrupt (ResourceConsumer, Edge, ActiveLow,
ExclusiveAndWake, 0, "\\_SB.EXIU") {
          7,
        }
      })
      Name (_AEI, ResourceTemplate () {
        GpioInt (Edge, ActiveHigh, ExclusiveAndWake, PullDefault, 0,
"\\_SB.GPIO")
        {
          7
        }
      })
      Method (_E07) {
        Notify (\_SB.PWRB, 0x80)
      }
    }

This is actually a fairly accurate depiction of reality: the EXIU is a
separate unit, and only some of the GPIOs are routed through it.

In the GPIO controller's to_irq() callback, I return the Linux IRQ
number based on the platform IRQ resources claimed by the GPIO device,
and I end up with something like

 46:          0 ... 0      EXIU   7 Edge      ACPI:Event

which looks correct to me. debugfs tells me it is mapped as

handler:  handle_fasteoi_irq
device:   (null)
status:   0x00000001
istate:   0x00000020
            IRQS_ONESHOT
ddepth:   0
wdepth:   1
dstate:   0x03404201
            IRQ_TYPE_EDGE_RISING
            IRQD_ACTIVATED
            IRQD_IRQ_STARTED
            IRQD_SINGLE_TARGET
            IRQD_WAKEUP_STATE
node:     0
affinity: 0-23
effectiv: 0
domain:  \_SB_.EXIU
 hwirq:   0x7
 chip:    EXIU
  flags:   0x55
             IRQCHIP_SET_TYPE_MASKED
             IRQCHIP_MASK_ON_SUSPEND
             IRQCHIP_SKIP_SET_WAKE
             IRQCHIP_EOI_THREADED
 parent:
    domain:  irqchip@(____ptrval____)-1
     hwirq:   0x97
     chip:    GICv3
      flags:   0x15
                 IRQCHIP_SET_TYPE_MASKED
                 IRQCHIP_MASK_ON_SUSPEND
                 IRQCHIP_SKIP_SET_WAKE

The EXIU domain is described as

name:   \_SB_.EXIU
 size:   32
 mapped: 1
 flags:  0x00000041
 parent: irqchip@(____ptrval____)-1
    name:   irqchip@(____ptrval____)-1
     size:   0
     mapped: 55
     flags:  0x00000041

Unfortunately, the system locks up entirely as soon as the interrupt
is triggered (I use a DIP switch in this case). So while the
description is accurate and the correct interrupt does get mapped,
something is still not working entirely as expected.

Any thoughts?

Thanks,
Ard.

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [RFC PATCH 2/3] irqchip/exiu: implement ACPI gpiolib/irqchip support
  2019-04-29  9:09               ` Ard Biesheuvel
@ 2019-04-29  9:35                 ` Marc Zyngier
  -1 siblings, 0 replies; 34+ messages in thread
From: Marc Zyngier @ 2019-04-29  9:35 UTC (permalink / raw)
  To: Ard Biesheuvel, Mika Westerberg
  Cc: open list:GPIO SUBSYSTEM, Linus Walleij, Graeme Gregory,
	linux-arm-kernel, Masahisa Kojima

On 29/04/2019 10:09, Ard Biesheuvel wrote:
> On Sat, 27 Apr 2019 at 00:27, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote:
>>
>> On Fri, 26 Apr 2019 at 13:45, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote:
>>>
>>> On Fri, 26 Apr 2019 at 10:44, Marc Zyngier <marc.zyngier@arm.com> wrote:
>>>>
>>>> On 26/04/2019 09:24, Ard Biesheuvel wrote:
>>>>> On Thu, 25 Apr 2019 at 17:33, Marc Zyngier <marc.zyngier@arm.com> wrote:
>>>>>>
>>>>>> Hi Ard,
>>>>>>
>>>>>> On 25/04/2019 11:20, Ard Biesheuvel wrote:
>>>>>>> Expose the existing EXIU hierarchical irqchip domain code to permit
>>>>>>> the interrupt controller to be used as the irqchip component of a
>>>>>>> GPIO controller on ACPI systems.
>>>>>>>
>>>>>>> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
>>>>>>> ---
>>>>>>>  drivers/irqchip/irq-sni-exiu.c | 82 +++++++++++++++++---
>>>>>>>  1 file changed, 73 insertions(+), 9 deletions(-)
>>>>>>>
>>>>>>
>>>>>> [...]
>>>>>>
>>>>>>> +int exiu_acpi_init(struct platform_device *pdev, struct gpio_chip *gc)
>>>>>>> +{
>>>>>>> +     struct irq_domain *parent_domain = NULL, *domain;
>>>>>>> +     struct resource *res;
>>>>>>> +     int irq;
>>>>>>> +
>>>>>>> +     irq = platform_get_irq(pdev, 0);
>>>>>>> +     if (irq > 0)
>>>>>>> +             parent_domain = irq_get_irq_data(irq)->domain;
>>>>>>> +
>>>>>>> +     if (!parent_domain) {
>>>>>>> +             dev_err(&pdev->dev, "unable to obtain parent domain\n");
>>>>>>> +             return -ENODEV;
>>>>>>> +     }
>>>>>>> +
>>>>>>> +     res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
>>>>>>> +     if (!res) {
>>>>>>> +             dev_err(&pdev->dev, "failed to parse memory resource\n");
>>>>>>> +             return -ENXIO;
>>>>>>> +     }
>>>>>>> +
>>>>>>> +     domain = exiu_init(parent_domain, dev_fwnode(&pdev->dev), res);
>>>>>>> +     if (IS_ERR(domain)) {
>>>>>>> +             dev_err(&pdev->dev, "failed to create IRQ domain (%ld)\n",
>>>>>>> +                     PTR_ERR(domain));
>>>>>>> +             return PTR_ERR(domain);
>>>>>>> +     }
>>>>>>> +
>>>>>>> +     gc->irq.domain = domain;
>>>>>>> +     gc->to_irq = exiu_acpi_gpio_to_irq;
>>>>>>> +
>>>>>>> +     dev_info(&pdev->dev, "%d interrupts forwarded\n", NUM_IRQS);
>>>>>>> +
>>>>>>> +     return 0;
>>>>>>> +}
>>>>>>> +EXPORT_SYMBOL(exiu_acpi_init);
>>>>>>> +#endif
>>>>>>>
>>>>>>
>>>>>> I must say I'm not overly keen on this function. Why can't this be
>>>>>> probed as an ACPI device, creating the corresponding domain, and leaving
>>>>>> to the GPIO driver the task of doing the GPIO stuff?
>>>>>>
>>>>>
>>>>> Because ACPI only permits 'system' interrupts or GPIO interrupts, it
>>>>> does not allow arbitrary device objects in the ACPI namespace to be
>>>>> targeted as interrupt controllers.
>>>>
>>>> Hmmm. We already have at least one driver (irq-mbigen.c) that does
>>>> exactly that. It uses interrupts from the GIC (it is notionally behind
>>>> the ITS), and offers a bunch of interrupt lines itself. Why is it different?
>>>>
>>>
>>> You are right, it isn't. It turns out that there is another way to
>>> signal ACPI events based on interrupts, and it involves the ACPI0013
>>> GED device. I will try to model it that way instead.
>>>
>>
>> Unfortunately, this doesn't work either. The GED device can respond to
>> GSIVs only, and so going via the EXIU doesn't work.
>>
>> I have attempted to hack it up via AML, but the GED driver uses a
>> threaded interrupt, and so the interrupt is re-enabled at the GIC
>> before the AML handler is executed (which clears it in the EXIU)
>>
>> For the RAS case, I guess we could let the firmware pick an arbitrary
>> unused SPI and signal that directly into the GIC, but for the power
>> button (which is physically wired to the EXIU), we have to model the
>> EXIU either has a separate pseudo-GPIO controller, or as part of the
>> real GPIO block.
> 
> (+ Mika)
> 
> I made some progress describing the EXIU and GPIO controllers as follow.
> 
>     Device (EXIU) {
>       Name (_HID, "SCX0008")
>       Name (_UID, Zero)
>       Name (_CRS, ResourceTemplate () {
>         Memory32Fixed (ReadWrite, SYNQUACER_EXIU_BASE, SYNQUACER_EXIU_SIZE)
>         Interrupt (ResourceConsumer, Level, ActiveHigh, ExclusiveAndWake) {
>           144, 145, 146, 147, 148, 149, 150, 151,
>           152, 153, 154, 155, 156, 157, 158, 159,
>           160, 161, 162, 163, 164, 165, 166, 167,
>           168, 169, 170, 171, 172, 173, 174, 175,
>         }
>       })
>       Name (_DSD, Package () {
>         ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>         Package () {
>           Package () { "socionext,spi-base", 112 },
>         }
>       })
>     }
> 
> and
> 
>     Device (GPIO) {
>       Name (_HID, "SCX0007")
>       Name (_UID, Zero)
>       Name (_CRS, ResourceTemplate () {
>         Memory32Fixed (ReadWrite, SYNQUACER_GPIO_BASE, SYNQUACER_GPIO_SIZE)
>         Interrupt (ResourceConsumer, Edge, ActiveLow,
> ExclusiveAndWake, 0, "\\_SB.EXIU") {
>           7,
>         }
>       })
>       Name (_AEI, ResourceTemplate () {
>         GpioInt (Edge, ActiveHigh, ExclusiveAndWake, PullDefault, 0,
> "\\_SB.GPIO")
>         {
>           7
>         }
>       })
>       Method (_E07) {
>         Notify (\_SB.PWRB, 0x80)
>       }
>     }
> 
> This is actually a fairly accurate depiction of reality: the EXIU is a
> separate unit, and only some of the GPIOs are routed through it.
> 
> In the GPIO controller's to_irq() callback, I return the Linux IRQ
> number based on the platform IRQ resources claimed by the GPIO device,
> and I end up with something like
> 
>  46:          0 ... 0      EXIU   7 Edge      ACPI:Event
> 
> which looks correct to me. debugfs tells me it is mapped as
> 
> handler:  handle_fasteoi_irq
> device:   (null)
> status:   0x00000001
> istate:   0x00000020
>             IRQS_ONESHOT
> ddepth:   0
> wdepth:   1
> dstate:   0x03404201
>             IRQ_TYPE_EDGE_RISING
>             IRQD_ACTIVATED
>             IRQD_IRQ_STARTED
>             IRQD_SINGLE_TARGET
>             IRQD_WAKEUP_STATE
> node:     0
> affinity: 0-23
> effectiv: 0
> domain:  \_SB_.EXIU
>  hwirq:   0x7
>  chip:    EXIU
>   flags:   0x55
>              IRQCHIP_SET_TYPE_MASKED
>              IRQCHIP_MASK_ON_SUSPEND
>              IRQCHIP_SKIP_SET_WAKE
>              IRQCHIP_EOI_THREADED
>  parent:
>     domain:  irqchip@(____ptrval____)-1
>      hwirq:   0x97
>      chip:    GICv3
>       flags:   0x15
>                  IRQCHIP_SET_TYPE_MASKED
>                  IRQCHIP_MASK_ON_SUSPEND
>                  IRQCHIP_SKIP_SET_WAKE
> 
> The EXIU domain is described as
> 
> name:   \_SB_.EXIU
>  size:   32
>  mapped: 1
>  flags:  0x00000041
>  parent: irqchip@(____ptrval____)-1
>     name:   irqchip@(____ptrval____)-1
>      size:   0
>      mapped: 55
>      flags:  0x00000041
> 
> Unfortunately, the system locks up entirely as soon as the interrupt
> is triggered (I use a DIP switch in this case). So while the
> description is accurate and the correct interrupt does get mapped,
> something is still not working entirely as expected.
> 
> Any thoughts?

It feels like an interrupt storm with an edge vs level misconfiguration.
Can you check that the IRQ_TYPE_EDGE_RISING is correctly propagated
across the hierarchy?

The EXIU block has:

Interrupt (ResourceConsumer, Level, ActiveHigh, ExclusiveAndWake) {

while the GPIO block has:

Interrupt (ResourceConsumer, Edge, ActiveLow, ExclusiveAndWake, 0,
"\\_SB.EXIU")

and the interrupt is configured for yet another trigger
(IRQ_TYPE_EDGE_RISING).

Hope this helps,

	M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [RFC PATCH 2/3] irqchip/exiu: implement ACPI gpiolib/irqchip support
@ 2019-04-29  9:35                 ` Marc Zyngier
  0 siblings, 0 replies; 34+ messages in thread
From: Marc Zyngier @ 2019-04-29  9:35 UTC (permalink / raw)
  To: Ard Biesheuvel, Mika Westerberg
  Cc: open list:GPIO SUBSYSTEM, Linus Walleij, Graeme Gregory,
	linux-arm-kernel, Masahisa Kojima

On 29/04/2019 10:09, Ard Biesheuvel wrote:
> On Sat, 27 Apr 2019 at 00:27, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote:
>>
>> On Fri, 26 Apr 2019 at 13:45, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote:
>>>
>>> On Fri, 26 Apr 2019 at 10:44, Marc Zyngier <marc.zyngier@arm.com> wrote:
>>>>
>>>> On 26/04/2019 09:24, Ard Biesheuvel wrote:
>>>>> On Thu, 25 Apr 2019 at 17:33, Marc Zyngier <marc.zyngier@arm.com> wrote:
>>>>>>
>>>>>> Hi Ard,
>>>>>>
>>>>>> On 25/04/2019 11:20, Ard Biesheuvel wrote:
>>>>>>> Expose the existing EXIU hierarchical irqchip domain code to permit
>>>>>>> the interrupt controller to be used as the irqchip component of a
>>>>>>> GPIO controller on ACPI systems.
>>>>>>>
>>>>>>> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
>>>>>>> ---
>>>>>>>  drivers/irqchip/irq-sni-exiu.c | 82 +++++++++++++++++---
>>>>>>>  1 file changed, 73 insertions(+), 9 deletions(-)
>>>>>>>
>>>>>>
>>>>>> [...]
>>>>>>
>>>>>>> +int exiu_acpi_init(struct platform_device *pdev, struct gpio_chip *gc)
>>>>>>> +{
>>>>>>> +     struct irq_domain *parent_domain = NULL, *domain;
>>>>>>> +     struct resource *res;
>>>>>>> +     int irq;
>>>>>>> +
>>>>>>> +     irq = platform_get_irq(pdev, 0);
>>>>>>> +     if (irq > 0)
>>>>>>> +             parent_domain = irq_get_irq_data(irq)->domain;
>>>>>>> +
>>>>>>> +     if (!parent_domain) {
>>>>>>> +             dev_err(&pdev->dev, "unable to obtain parent domain\n");
>>>>>>> +             return -ENODEV;
>>>>>>> +     }
>>>>>>> +
>>>>>>> +     res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
>>>>>>> +     if (!res) {
>>>>>>> +             dev_err(&pdev->dev, "failed to parse memory resource\n");
>>>>>>> +             return -ENXIO;
>>>>>>> +     }
>>>>>>> +
>>>>>>> +     domain = exiu_init(parent_domain, dev_fwnode(&pdev->dev), res);
>>>>>>> +     if (IS_ERR(domain)) {
>>>>>>> +             dev_err(&pdev->dev, "failed to create IRQ domain (%ld)\n",
>>>>>>> +                     PTR_ERR(domain));
>>>>>>> +             return PTR_ERR(domain);
>>>>>>> +     }
>>>>>>> +
>>>>>>> +     gc->irq.domain = domain;
>>>>>>> +     gc->to_irq = exiu_acpi_gpio_to_irq;
>>>>>>> +
>>>>>>> +     dev_info(&pdev->dev, "%d interrupts forwarded\n", NUM_IRQS);
>>>>>>> +
>>>>>>> +     return 0;
>>>>>>> +}
>>>>>>> +EXPORT_SYMBOL(exiu_acpi_init);
>>>>>>> +#endif
>>>>>>>
>>>>>>
>>>>>> I must say I'm not overly keen on this function. Why can't this be
>>>>>> probed as an ACPI device, creating the corresponding domain, and leaving
>>>>>> to the GPIO driver the task of doing the GPIO stuff?
>>>>>>
>>>>>
>>>>> Because ACPI only permits 'system' interrupts or GPIO interrupts, it
>>>>> does not allow arbitrary device objects in the ACPI namespace to be
>>>>> targeted as interrupt controllers.
>>>>
>>>> Hmmm. We already have at least one driver (irq-mbigen.c) that does
>>>> exactly that. It uses interrupts from the GIC (it is notionally behind
>>>> the ITS), and offers a bunch of interrupt lines itself. Why is it different?
>>>>
>>>
>>> You are right, it isn't. It turns out that there is another way to
>>> signal ACPI events based on interrupts, and it involves the ACPI0013
>>> GED device. I will try to model it that way instead.
>>>
>>
>> Unfortunately, this doesn't work either. The GED device can respond to
>> GSIVs only, and so going via the EXIU doesn't work.
>>
>> I have attempted to hack it up via AML, but the GED driver uses a
>> threaded interrupt, and so the interrupt is re-enabled at the GIC
>> before the AML handler is executed (which clears it in the EXIU)
>>
>> For the RAS case, I guess we could let the firmware pick an arbitrary
>> unused SPI and signal that directly into the GIC, but for the power
>> button (which is physically wired to the EXIU), we have to model the
>> EXIU either has a separate pseudo-GPIO controller, or as part of the
>> real GPIO block.
> 
> (+ Mika)
> 
> I made some progress describing the EXIU and GPIO controllers as follow.
> 
>     Device (EXIU) {
>       Name (_HID, "SCX0008")
>       Name (_UID, Zero)
>       Name (_CRS, ResourceTemplate () {
>         Memory32Fixed (ReadWrite, SYNQUACER_EXIU_BASE, SYNQUACER_EXIU_SIZE)
>         Interrupt (ResourceConsumer, Level, ActiveHigh, ExclusiveAndWake) {
>           144, 145, 146, 147, 148, 149, 150, 151,
>           152, 153, 154, 155, 156, 157, 158, 159,
>           160, 161, 162, 163, 164, 165, 166, 167,
>           168, 169, 170, 171, 172, 173, 174, 175,
>         }
>       })
>       Name (_DSD, Package () {
>         ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>         Package () {
>           Package () { "socionext,spi-base", 112 },
>         }
>       })
>     }
> 
> and
> 
>     Device (GPIO) {
>       Name (_HID, "SCX0007")
>       Name (_UID, Zero)
>       Name (_CRS, ResourceTemplate () {
>         Memory32Fixed (ReadWrite, SYNQUACER_GPIO_BASE, SYNQUACER_GPIO_SIZE)
>         Interrupt (ResourceConsumer, Edge, ActiveLow,
> ExclusiveAndWake, 0, "\\_SB.EXIU") {
>           7,
>         }
>       })
>       Name (_AEI, ResourceTemplate () {
>         GpioInt (Edge, ActiveHigh, ExclusiveAndWake, PullDefault, 0,
> "\\_SB.GPIO")
>         {
>           7
>         }
>       })
>       Method (_E07) {
>         Notify (\_SB.PWRB, 0x80)
>       }
>     }
> 
> This is actually a fairly accurate depiction of reality: the EXIU is a
> separate unit, and only some of the GPIOs are routed through it.
> 
> In the GPIO controller's to_irq() callback, I return the Linux IRQ
> number based on the platform IRQ resources claimed by the GPIO device,
> and I end up with something like
> 
>  46:          0 ... 0      EXIU   7 Edge      ACPI:Event
> 
> which looks correct to me. debugfs tells me it is mapped as
> 
> handler:  handle_fasteoi_irq
> device:   (null)
> status:   0x00000001
> istate:   0x00000020
>             IRQS_ONESHOT
> ddepth:   0
> wdepth:   1
> dstate:   0x03404201
>             IRQ_TYPE_EDGE_RISING
>             IRQD_ACTIVATED
>             IRQD_IRQ_STARTED
>             IRQD_SINGLE_TARGET
>             IRQD_WAKEUP_STATE
> node:     0
> affinity: 0-23
> effectiv: 0
> domain:  \_SB_.EXIU
>  hwirq:   0x7
>  chip:    EXIU
>   flags:   0x55
>              IRQCHIP_SET_TYPE_MASKED
>              IRQCHIP_MASK_ON_SUSPEND
>              IRQCHIP_SKIP_SET_WAKE
>              IRQCHIP_EOI_THREADED
>  parent:
>     domain:  irqchip@(____ptrval____)-1
>      hwirq:   0x97
>      chip:    GICv3
>       flags:   0x15
>                  IRQCHIP_SET_TYPE_MASKED
>                  IRQCHIP_MASK_ON_SUSPEND
>                  IRQCHIP_SKIP_SET_WAKE
> 
> The EXIU domain is described as
> 
> name:   \_SB_.EXIU
>  size:   32
>  mapped: 1
>  flags:  0x00000041
>  parent: irqchip@(____ptrval____)-1
>     name:   irqchip@(____ptrval____)-1
>      size:   0
>      mapped: 55
>      flags:  0x00000041
> 
> Unfortunately, the system locks up entirely as soon as the interrupt
> is triggered (I use a DIP switch in this case). So while the
> description is accurate and the correct interrupt does get mapped,
> something is still not working entirely as expected.
> 
> Any thoughts?

It feels like an interrupt storm with an edge vs level misconfiguration.
Can you check that the IRQ_TYPE_EDGE_RISING is correctly propagated
across the hierarchy?

The EXIU block has:

Interrupt (ResourceConsumer, Level, ActiveHigh, ExclusiveAndWake) {

while the GPIO block has:

Interrupt (ResourceConsumer, Edge, ActiveLow, ExclusiveAndWake, 0,
"\\_SB.EXIU")

and the interrupt is configured for yet another trigger
(IRQ_TYPE_EDGE_RISING).

Hope this helps,

	M.
-- 
Jazz is not dead. It just smells funny...

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 34+ messages in thread

end of thread, other threads:[~2019-04-29  9:35 UTC | newest]

Thread overview: 34+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-04-25 10:20 [RFC PATCH 0/3] synquacer: implement ACPI gpio/interrupt support Ard Biesheuvel
2019-04-25 10:20 ` Ard Biesheuvel
2019-04-25 10:20 ` [RFC PATCH 1/3] irqchip/exiu: preparatory refactor for ACPI support Ard Biesheuvel
2019-04-25 10:20   ` Ard Biesheuvel
2019-04-25 10:20 ` [RFC PATCH 2/3] irqchip/exiu: implement ACPI gpiolib/irqchip support Ard Biesheuvel
2019-04-25 10:20   ` Ard Biesheuvel
2019-04-25 13:14   ` Linus Walleij
2019-04-25 13:14     ` Linus Walleij
2019-04-25 15:33   ` Marc Zyngier
2019-04-25 15:33     ` Marc Zyngier
2019-04-26  8:24     ` Ard Biesheuvel
2019-04-26  8:24       ` Ard Biesheuvel
2019-04-26  8:44       ` Marc Zyngier
2019-04-26  8:44         ` Marc Zyngier
2019-04-26 11:45         ` Ard Biesheuvel
2019-04-26 11:45           ` Ard Biesheuvel
2019-04-26 22:27           ` Ard Biesheuvel
2019-04-26 22:27             ` Ard Biesheuvel
2019-04-29  9:09             ` Ard Biesheuvel
2019-04-29  9:09               ` Ard Biesheuvel
2019-04-29  9:35               ` Marc Zyngier
2019-04-29  9:35                 ` Marc Zyngier
2019-04-25 10:20 ` [RFC PATCH 3/3] gpio: mb86s70: enable ACPI and irqchip support Ard Biesheuvel
2019-04-25 10:20   ` Ard Biesheuvel
2019-04-25 13:23   ` Linus Walleij
2019-04-25 13:23     ` Linus Walleij
2019-04-25 13:35     ` Ard Biesheuvel
2019-04-25 13:35       ` Ard Biesheuvel
2019-04-25 14:27     ` Mika Westerberg
2019-04-25 14:27       ` Mika Westerberg
2019-04-26  8:19       ` Ard Biesheuvel
2019-04-26  8:19         ` Ard Biesheuvel
2019-04-26  9:15         ` Mika Westerberg
2019-04-26  9:15           ` Mika Westerberg

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.