public inbox for linux-acpi@vger.kernel.org
 help / color / mirror / Atom feed
From: Sunil V L <sunilvl@ventanamicro.com>
To: linux-doc@vger.kernel.org, linux-riscv@lists.infradead.org,
	linux-kernel@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org, linux-acpi@vger.kernel.org,
	linux-pci@vger.kernel.org
Cc: Jonathan Corbet <corbet@lwn.net>,
	Paul Walmsley <paul.walmsley@sifive.com>,
	Palmer Dabbelt <palmer@dabbelt.com>,
	Albert Ou <aou@eecs.berkeley.edu>,
	Catalin Marinas <catalin.marinas@arm.com>,
	Will Deacon <will@kernel.org>,
	"Rafael J . Wysocki" <rafael@kernel.org>,
	Len Brown <lenb@kernel.org>,
	Andy Shevchenko <andriy.shevchenko@linux.intel.com>,
	Daniel Scally <djrscally@gmail.com>,
	Heikki Krogerus <heikki.krogerus@linux.intel.com>,
	Sakari Ailus <sakari.ailus@linux.intel.com>,
	Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	Daniel Lezcano <daniel.lezcano@linaro.org>,
	Thomas Gleixner <tglx@linutronix.de>,
	Anup Patel <anup@brainfault.org>, Marc Zyngier <maz@kernel.org>,
	Bjorn Helgaas <bhelgaas@google.com>,
	Robert Moore <robert.moore@intel.com>,
	Haibo Xu <haibo1.xu@intel.com>,
	Andrew Jones <ajones@ventanamicro.com>,
	Conor Dooley <conor.dooley@microchip.com>,
	Atish Kumar Patra <atishp@rivosinc.com>,
	Sunil V L <sunilvl@ventanamicro.com>
Subject: [RFC PATCH v1 17/21] ACPI: RISC-V: Create APLIC platform device
Date: Thu,  3 Aug 2023 23:29:12 +0530	[thread overview]
Message-ID: <20230803175916.3174453-18-sunilvl@ventanamicro.com> (raw)
In-Reply-To: <20230803175916.3174453-1-sunilvl@ventanamicro.com>

Since APLIC needs to be a platform device, probe the
MADT and create platform devices for each APLIC in the
system. Use software node framework for the fwnode
which allows to create properties and hence the
actual irqchip driver doesn't need to do anything
different for ACPI vs DT.

Signed-off-by: Sunil V L <sunilvl@ventanamicro.com>
---
 Documentation/riscv/acpi.rst |   6 ++
 drivers/acpi/riscv/init.c    |   1 +
 drivers/acpi/riscv/init.h    |   1 +
 drivers/acpi/riscv/irqchip.c | 183 +++++++++++++++++++++++++++++++++++
 4 files changed, 191 insertions(+)

diff --git a/Documentation/riscv/acpi.rst b/Documentation/riscv/acpi.rst
index e2406546bc16..9ea9008288ea 100644
--- a/Documentation/riscv/acpi.rst
+++ b/Documentation/riscv/acpi.rst
@@ -29,3 +29,9 @@ properties are created using the data in MADT table.
 
 ``riscv,ext-intc-id`` - The unique ID of the external interrupts connected
 to this hart.
+
+2) RISC-V Advanced Platform Level Interrupt Controller (APLIC)
+-----------
+
+``riscv,gsi-base`` - The global system interrupt number where this APLIC’s
+interrupt inputs start.
diff --git a/drivers/acpi/riscv/init.c b/drivers/acpi/riscv/init.c
index be61c08ea385..ee747211174f 100644
--- a/drivers/acpi/riscv/init.c
+++ b/drivers/acpi/riscv/init.c
@@ -11,4 +11,5 @@
 void __init acpi_riscv_init(void)
 {
 	riscv_acpi_imsic_platform_init();
+	riscv_acpi_aplic_platform_init();
 }
diff --git a/drivers/acpi/riscv/init.h b/drivers/acpi/riscv/init.h
index a2f72bb294d3..17bcf0baaadb 100644
--- a/drivers/acpi/riscv/init.h
+++ b/drivers/acpi/riscv/init.h
@@ -2,3 +2,4 @@
 #include <linux/init.h>
 
 void __init riscv_acpi_imsic_platform_init(void);
+void __init riscv_acpi_aplic_platform_init(void);
diff --git a/drivers/acpi/riscv/irqchip.c b/drivers/acpi/riscv/irqchip.c
index ca96bf109cf7..7fb7befdb303 100644
--- a/drivers/acpi/riscv/irqchip.c
+++ b/drivers/acpi/riscv/irqchip.c
@@ -23,6 +23,8 @@ LIST_HEAD(rintc_list);
 
 static struct fwnode_handle *imsic_acpi_fwnode;
 
+LIST_HEAD(aplic_list);
+
 struct fwnode_handle *acpi_rintc_create_irqchip_fwnode(struct acpi_madt_rintc *rintc)
 {
 	struct property_entry props[6] = {};
@@ -124,3 +126,184 @@ void __init riscv_acpi_imsic_platform_init(void)
 	if (ret)
 		platform_device_put(pdev);
 }
+
+/*
+ * The ext_intc_id format is as follows:
+ * Bits [31:24] APLIC/PLIC ID
+ * Bits [15:0] APLIC IDC ID / PLIC S-Mode Context ID for this hart
+ */
+#define APLIC_PLIC_ID(x) ((x) >> 24)
+#define IDC_CONTEXT_ID(x) ((x) & 0x0000ffff)
+
+static struct fwnode_handle *acpi_ext_intc_get_rintc_fwnode(u8 aplic_plic_id, u16 index)
+{
+	struct riscv_irqchip_list *rintc_element;
+	struct fwnode_handle *fwnode;
+	struct list_head *i, *tmp;
+	u32 id;
+	int rc;
+
+	list_for_each_safe(i, tmp, &rintc_list) {
+		rintc_element = list_entry(i, struct riscv_irqchip_list, list);
+		fwnode = rintc_element->fwnode;
+		rc = fwnode_property_read_u32_array(fwnode, "riscv,ext-intc-id", &id, 1);
+		if (rc)
+			continue;
+
+		if ((APLIC_PLIC_ID(id) == aplic_plic_id) && (IDC_CONTEXT_ID(id) == index))
+			return fwnode;
+	}
+
+	return NULL;
+}
+
+static struct fwnode_handle *acpi_aplic_create_fwnode(struct acpi_madt_aplic *aplic)
+{
+	struct fwnode_handle *fwnode, *parent_fwnode;
+	struct riscv_irqchip_list *aplic_element;
+	struct software_node_ref_args *refs;
+	struct property_entry props[8] = {};
+	unsigned int i;
+
+	props[0] = PROPERTY_ENTRY_U32("riscv,gsi-base", aplic->gsi_base);
+	props[1] = PROPERTY_ENTRY_U32("riscv,num-sources", aplic->num_sources);
+	props[2] = PROPERTY_ENTRY_U32("riscv,num-idcs", aplic->num_idcs);
+	props[3] = PROPERTY_ENTRY_U32("riscv,aplic-id", aplic->id);
+	props[4] = PROPERTY_ENTRY_U64("riscv,aplic-base", aplic->base_addr);
+	props[5] = PROPERTY_ENTRY_U32("riscv,aplic-size", aplic->size);
+	if (aplic->num_idcs) {
+		refs = kcalloc(aplic->num_idcs, sizeof(*refs), GFP_KERNEL);
+		if (!refs)
+			return NULL;
+
+		for (i = 0; i < aplic->num_idcs; i++) {
+			parent_fwnode = acpi_ext_intc_get_rintc_fwnode(aplic->id, i);
+			refs[i] = SOFTWARE_NODE_REFERENCE(to_software_node(parent_fwnode),
+							  RV_IRQ_EXT);
+		}
+		props[6] = PROPERTY_ENTRY_REF_ARRAY_LEN("interrupts-extended",
+							refs, aplic->num_idcs);
+	} else {
+		props[6] = PROPERTY_ENTRY_BOOL("msi-parent");
+	}
+
+	fwnode = fwnode_create_software_node_early(props, NULL);
+
+	if (fwnode) {
+		aplic_element = kzalloc(sizeof(*aplic_element), GFP_KERNEL);
+		if (!aplic_element) {
+			fwnode_remove_software_node(fwnode);
+			return NULL;
+		}
+
+		aplic_element->fwnode = fwnode;
+		list_add_tail(&aplic_element->list, &aplic_list);
+	}
+
+	return fwnode;
+}
+
+static struct fwnode_handle *aplic_get_gsi_domain_id(u32 gsi)
+{
+	struct riscv_irqchip_list *aplic_element;
+	struct fwnode_handle *fwnode;
+	struct list_head *i, *tmp;
+	u32 gsi_base;
+	u32 nr_irqs;
+	int rc;
+
+	list_for_each_safe(i, tmp, &aplic_list) {
+		aplic_element = list_entry(i, struct riscv_irqchip_list, list);
+		fwnode = aplic_element->fwnode;
+		rc = fwnode_property_read_u32_array(fwnode, "riscv,gsi-base", &gsi_base, 1);
+		if (!rc) {
+			rc = fwnode_property_read_u32_array(fwnode, "riscv,num-sources",
+							    &nr_irqs, 1);
+			if (!rc && (gsi >= gsi_base && gsi < gsi_base + nr_irqs))
+				return fwnode;
+		}
+	}
+
+	return NULL;
+}
+
+static u32 __init aplic_gsi_to_irq(u32 gsi)
+{
+	return acpi_register_gsi(NULL, gsi, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_HIGH);
+}
+
+static int __init aplic_create_platform_device(struct fwnode_handle *fwnode)
+{
+	struct platform_device *pdev;
+	u32 aplic_size, aplic_id;
+	struct resource *res;
+	u64 aplic_base;
+	int ret;
+
+	if (!fwnode)
+		return -ENODEV;
+
+	ret = fwnode_property_read_u64_array(fwnode, "riscv,aplic-base", &aplic_base, 1);
+	if (ret)
+		return -ENODEV;
+
+	ret = fwnode_property_read_u32_array(fwnode, "riscv,aplic-size", &aplic_size, 1);
+	if (ret)
+		return -ENODEV;
+
+	ret = fwnode_property_read_u32_array(fwnode, "riscv,aplic-id", &aplic_id, 1);
+	if (ret)
+		return -ENODEV;
+
+	pdev = platform_device_alloc("riscv-aplic", aplic_id);
+	if (!pdev)
+		return -ENOMEM;
+
+	res = kcalloc(1, sizeof(*res), GFP_KERNEL);
+	if (!res) {
+		ret = -ENOMEM;
+		goto dev_put;
+	}
+
+	res->start = aplic_base;
+	res->end = res->start + aplic_size - 1;
+	res->flags = IORESOURCE_MEM;
+	ret = platform_device_add_resources(pdev, res, 1);
+	/*
+	 * Resources are duplicated in platform_device_add_resources,
+	 * free their allocated memory
+	 */
+	kfree(res);
+
+	pdev->dev.fwnode = fwnode;
+	ret = platform_device_add(pdev);
+	if (ret)
+		goto dev_put;
+
+	return 0;
+
+dev_put:
+	platform_device_put(pdev);
+	return ret;
+}
+
+static int __init aplic_parse_madt(union acpi_subtable_headers *header,
+				   const unsigned long end)
+{
+	struct acpi_madt_aplic *aplic = (struct acpi_madt_aplic *)header;
+	struct fwnode_handle *fwnode;
+
+	fwnode = acpi_aplic_create_fwnode(aplic);
+	if (fwnode)
+		aplic_create_platform_device(fwnode);
+
+	return 0;
+}
+
+void __init riscv_acpi_aplic_platform_init(void)
+{
+	if (acpi_table_parse_madt(ACPI_MADT_TYPE_APLIC, aplic_parse_madt, 0) > 0) {
+		acpi_set_irq_model(ACPI_IRQ_MODEL_APLIC, aplic_get_gsi_domain_id);
+		acpi_set_gsi_to_irq_fallback(aplic_gsi_to_irq);
+	}
+}
-- 
2.39.2


  parent reply	other threads:[~2023-08-03 18:03 UTC|newest]

Thread overview: 51+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-08-03 17:58 [RFC PATCH v1 00/21] RISC-V: ACPI: Add external interrupt controller support Sunil V L
2023-08-03 17:58 ` [RFC PATCH v1 01/21] ACPICA: MADT: Add RISC-V external interrupt controllers Sunil V L
2023-08-03 17:58 ` [RFC PATCH v1 02/21] ACPICA: RHCT: Add flags, CMO and MMU nodes Sunil V L
2023-08-03 17:58 ` [RFC PATCH v1 03/21] RISC-V: ACPI: Fix acpi_os_ioremap to return iomem address Sunil V L
2023-08-07  8:20   ` Andrew Jones
2023-08-03 17:58 ` [RFC PATCH v1 04/21] RISC-V: ACPI: Enhance acpi_os_ioremap with MMIO remapping Sunil V L
2023-08-04  5:47   ` Andy Shevchenko
2023-08-04  8:19     ` Sunil V L
2023-08-07  8:41   ` Andrew Jones
2023-08-03 17:59 ` [RFC PATCH v1 05/21] arm64: PCI: Migrate ACPI related functions to pci-acpi.c Sunil V L
2023-08-04  5:53   ` Andy Shevchenko
2023-08-04  8:23     ` Sunil V L
2023-08-07 22:41   ` Bjorn Helgaas
2023-08-08  4:52     ` Sunil V L
2023-08-08 13:11       ` Andy Shevchenko
2023-08-08 13:11     ` Andy Shevchenko
2023-08-03 17:59 ` [RFC PATCH v1 06/21] RISC-V: ACPI: Implement PCI related functionality Sunil V L
2023-08-03 17:59 ` [RFC PATCH v1 07/21] RISC-V: Kconfig: Select ECAM and MCFG Sunil V L
2023-08-03 17:59 ` [RFC PATCH v1 08/21] RISC-V: ACPI: RHCT: Add function to get CBO block sizes Sunil V L
2023-08-04  6:00   ` Andy Shevchenko
2023-08-04  9:33     ` Sunil V L
2023-08-03 17:59 ` [RFC PATCH v1 09/21] RISC-V: cacheflush: Initialize CBO variables on ACPI systems Sunil V L
2023-08-04  5:56   ` Andy Shevchenko
2023-08-04  9:20     ` Sunil V L
2023-08-04 14:59       ` Andy Shevchenko
2023-08-04 15:19         ` Conor Dooley
2023-08-04 16:52           ` Andy Shevchenko
2023-08-04 16:56             ` Andy Shevchenko
2023-08-03 17:59 ` [RFC PATCH v1 10/21] clocksource/timer-riscv: ACPI: Add timer_cannot_wakeup_cpu Sunil V L
2023-08-03 17:59 ` [RFC PATCH v1 11/21] swnode: Add support to create early during boot Sunil V L
2023-08-04  6:09   ` Andy Shevchenko
2023-08-04  8:11     ` Sunil V L
2023-08-08 13:17       ` Marc Zyngier
2023-08-09  5:44         ` Sunil V L
2023-08-08 13:06   ` Marc Zyngier
2023-08-03 17:59 ` [RFC PATCH v1 12/21] irqchip/riscv-intc: Use swnode framework to create fwnode Sunil V L
2023-08-08  8:31   ` Conor Dooley
2023-08-09  5:49     ` Sunil V L
2023-08-03 17:59 ` [RFC PATCH v1 13/21] irqchip/riscv-imsic-early: Add ACPI support Sunil V L
2023-08-03 17:59 ` [RFC PATCH v1 14/21] ACPI: bus: Add acpi_riscv_init function Sunil V L
2023-08-03 17:59 ` [RFC PATCH v1 15/21] ACPI: RISC-V: Create IMSIC platform device Sunil V L
2023-08-03 17:59 ` [RFC PATCH v1 16/21] ACPI: Add APLIC IRQ model for RISC-V Sunil V L
2023-08-03 17:59 ` Sunil V L [this message]
2023-08-03 17:59 ` [RFC PATCH v1 18/21] irqchip/irq-riscv-aplic-msi: Add ACPI support Sunil V L
2023-08-03 17:59 ` [RFC PATCH v1 19/21] ACPI: bus: Add PLIC IRQ model Sunil V L
2023-08-03 17:59 ` [RFC PATCH v1 20/21] RISC-V: ACPI: Create PLIC platform device Sunil V L
2023-08-08  8:41   ` Conor Dooley
2023-08-08 10:57     ` Anup Patel
2023-08-08 11:30       ` Conor Dooley
2023-08-09  5:47     ` Sunil V L
2023-08-03 17:59 ` [RFC PATCH v1 21/21] irqchip/sifive-plic: Add GSI conversion support Sunil V L

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230803175916.3174453-18-sunilvl@ventanamicro.com \
    --to=sunilvl@ventanamicro.com \
    --cc=ajones@ventanamicro.com \
    --cc=andriy.shevchenko@linux.intel.com \
    --cc=anup@brainfault.org \
    --cc=aou@eecs.berkeley.edu \
    --cc=atishp@rivosinc.com \
    --cc=bhelgaas@google.com \
    --cc=catalin.marinas@arm.com \
    --cc=conor.dooley@microchip.com \
    --cc=corbet@lwn.net \
    --cc=daniel.lezcano@linaro.org \
    --cc=djrscally@gmail.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=haibo1.xu@intel.com \
    --cc=heikki.krogerus@linux.intel.com \
    --cc=lenb@kernel.org \
    --cc=linux-acpi@vger.kernel.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pci@vger.kernel.org \
    --cc=linux-riscv@lists.infradead.org \
    --cc=maz@kernel.org \
    --cc=palmer@dabbelt.com \
    --cc=paul.walmsley@sifive.com \
    --cc=rafael@kernel.org \
    --cc=robert.moore@intel.com \
    --cc=sakari.ailus@linux.intel.com \
    --cc=tglx@linutronix.de \
    --cc=will@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox