linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Hanjun Guo <hanjun.guo@linaro.org>
To: Marc Zyngier <marc.zyngier@arm.com>,
	Jason Cooper <jason@lakedaemon.net>,
	Will Deacon <will.deacon@arm.com>,
	Catalin Marinas <catalin.marinas@arm.com>,
	"Rafael J. Wysocki" <rjw@rjwysocki.net>
Cc: Thomas Gleixner <tglx@linutronix.de>,
	Jiang Liu <jiang.liu@linux.intel.com>,
	Bjorn Helgaas <bhelgaas@google.com>,
	Lorenzo Pieralisi <Lorenzo.Pieralisi@arm.com>,
	Suravee Suthikulpanit <Suravee.Suthikulpanit@amd.com>,
	Timur Tabi <timur@codeaurora.org>,
	Tomasz Nowicki <tomasz.nowicki@linaro.org>,
	Grant Likely <grant.likely@linaro.org>,
	Mark Brown <broonie@kernel.org>, Wei Huang <wei@redhat.com>,
	linux-arm-kernel@lists.infradead.org, linux-acpi@vger.kernel.org,
	linux-kernel@vger.kernel.org, linaro-acpi@lists.linaro.org,
	Hanjun Guo <hanjun.guo@linaro.org>
Subject: [PATCH v4 08/10] ACPI: GIC: Add ACPI helper functions to query irq-domain tokens for for GIC MSI and ITS
Date: Wed, 29 Jul 2015 18:08:57 +0800	[thread overview]
Message-ID: <1438164539-29256-9-git-send-email-hanjun.guo@linaro.org> (raw)
In-Reply-To: <1438164539-29256-1-git-send-email-hanjun.guo@linaro.org>

From: Suravee Suthikulpanit <Suravee.Suthikulpanit@amd.com>

This patch introduces acpi_gic_get_msi_token(), which returns irq-domain
token that can be used to look up MSI doamin of a device.
In both GIC MSI and ITS cases, the base_address specified in the GIC MSI
or GIC ITS structure is used as a token for MSI domain.

In addition, this patch also provides low-level helper functions to parse
and query GIC MSI structure and GIC ITS from MADT. Once parsed, it keeps
a copy of the structure for use in subsequent queries to avoid having
to map and parse MADT multiple times.

Signed-off-by: Suravee Suthikulpanit <Suravee.Suthikulpanit@amd.com>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 drivers/acpi/Makefile   |   1 +
 drivers/acpi/acpi_gic.c | 234 ++++++++++++++++++++++++++++++++++++++++++++++++
 include/acpi/acpi_gic.h |  23 +++++
 include/linux/acpi.h    |   1 +
 4 files changed, 259 insertions(+)
 create mode 100644 drivers/acpi/acpi_gic.c
 create mode 100644 include/acpi/acpi_gic.h

diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
index 8321430..def54b9 100644
--- a/drivers/acpi/Makefile
+++ b/drivers/acpi/Makefile
@@ -54,6 +54,7 @@ acpi-$(CONFIG_ACPI_NUMA)	+= numa.o
 acpi-$(CONFIG_ACPI_PROCFS_POWER) += cm_sbs.o
 acpi-y				+= acpi_lpat.o
 acpi-$(CONFIG_ACPI_GENERIC_GSI) += gsi.o
+acpi-$(CONFIG_ARM_GIC_ACPI)	+= acpi_gic.o
 
 # These are (potentially) separate modules
 
diff --git a/drivers/acpi/acpi_gic.c b/drivers/acpi/acpi_gic.c
new file mode 100644
index 0000000..11ee4eb
--- /dev/null
+++ b/drivers/acpi/acpi_gic.c
@@ -0,0 +1,234 @@
+/*
+ * File: acpi_gic.c
+ *
+ * ACPI helper functions for ARM GIC
+ *
+ * Copyright (C) 2015 Advanced Micro Devices, Inc.
+ * Authors: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
+ */
+
+#include <linux/acpi.h>
+#include <linux/init.h>
+
+/*
+ * GIC MSI Frame data structures
+ */
+struct gic_msi_frame_handle {
+	struct list_head list;
+	struct acpi_madt_generic_msi_frame frame;
+};
+
+static LIST_HEAD(msi_frame_list);
+
+static int acpi_num_msi;
+
+/*
+ * GIC ITS data structures
+ */
+struct gic_its_handle {
+	struct list_head list;
+	struct acpi_madt_generic_translator trans;
+};
+
+static LIST_HEAD(its_list);
+
+static int acpi_num_its;
+
+/*
+ * GIC MSI Frame parsing stuff
+ */
+inline int acpi_gic_get_num_msi_frame(void)
+{
+	return acpi_num_msi;
+}
+
+static int __init
+acpi_parse_madt_msi(struct acpi_subtable_header *header,
+		    const unsigned long end)
+{
+	struct gic_msi_frame_handle *h;
+	struct acpi_madt_generic_msi_frame *frame;
+
+	frame = (struct acpi_madt_generic_msi_frame *)header;
+	if (BAD_MADT_ENTRY(frame, end))
+		return -EINVAL;
+
+	h = kzalloc(sizeof(struct gic_msi_frame_handle *), GFP_KERNEL);
+	if (!h)
+		return -ENOMEM;
+
+	/** Note:
+	 * We make a copy of this structure since this code is called
+	 * prior to acpi_early_init(), which sets the acpi_gbl_permanent_mmap.
+	 * Therefore, we could not keep just the pointer sincce the memory
+	 * could be unmapped.
+	 */
+	memcpy(&h->frame, frame, sizeof(struct acpi_madt_generic_msi_frame));
+
+	list_add(&h->list, &msi_frame_list);
+
+	return 0;
+}
+
+int __init acpi_gic_msi_init(struct acpi_table_header *table)
+{
+	int ret = 0;
+
+	if (acpi_num_msi > 0)
+		return ret;
+
+	ret = acpi_parse_entries(ACPI_SIG_MADT,
+				 sizeof(struct acpi_table_madt),
+				 acpi_parse_madt_msi, table,
+				 ACPI_MADT_TYPE_GENERIC_MSI_FRAME, 0);
+	if (ret == 0) {
+		pr_debug("No valid ACPI GIC MSI FRAME exist\n");
+		return ret;
+	}
+
+	acpi_num_msi = ret;
+	return 0;
+}
+
+int acpi_gic_get_msi_frame(int index, struct acpi_madt_generic_msi_frame **p)
+{
+	int i = 0;
+	struct gic_msi_frame_handle *m;
+
+	if (index >= acpi_num_msi)
+		return -EINVAL;
+
+	list_for_each_entry(m, &msi_frame_list, list) {
+		if (i == index)
+			break;
+		i++;
+	}
+
+	if (i == acpi_num_msi)
+		return -EINVAL;
+
+	*p = &(m->frame);
+	return  0;
+}
+
+/*
+ * GIC ITS parsing stuff
+ */
+inline int acpi_gic_get_num_its(void)
+{
+	return acpi_num_its;
+}
+
+static int __init
+acpi_parse_madt_its(struct acpi_subtable_header *header,
+		    const unsigned long end)
+{
+	struct gic_its_handle *h;
+	struct acpi_madt_generic_translator *trans;
+
+	trans = (struct acpi_madt_generic_translator *)header;
+	if (BAD_MADT_ENTRY(trans, end))
+		return -EINVAL;
+
+	h = kzalloc(sizeof(struct gic_its_handle *), GFP_KERNEL);
+	if (!h)
+		return -ENOMEM;
+
+	memcpy(&h->trans, trans, sizeof(struct acpi_madt_generic_translator));
+
+	list_add(&h->list, &its_list);
+
+	return 0;
+}
+
+int __init acpi_gic_madt_gic_its_init(struct acpi_table_header *table)
+{
+	int ret = 0;
+
+	if (acpi_num_its > 0)
+		return ret;
+
+	ret = acpi_parse_entries(ACPI_SIG_MADT,
+				 sizeof(struct acpi_table_madt),
+				 acpi_parse_madt_its, table,
+				 ACPI_MADT_TYPE_GENERIC_TRANSLATOR, 0);
+	if (ret == 0) {
+		pr_debug("No valid ACPI GIC ITS exist\n");
+		return ret;
+	}
+
+	acpi_num_its = ret;
+	return 0;
+}
+
+int acpi_gic_get_its(int index, struct acpi_madt_generic_translator **p)
+{
+	int i = 0;
+	struct gic_its_handle *m;
+
+	if (index >= acpi_num_its)
+		return -EINVAL;
+
+	list_for_each_entry(m, &its_list, list) {
+		if (i == index)
+			break;
+		i++;
+	}
+
+	if (i == acpi_num_its)
+		return -EINVAL;
+
+	*p = &(m->trans);
+	return  0;
+}
+
+static void *acpi_gic_msi_token(struct device *dev)
+{
+	int err;
+	struct acpi_madt_generic_msi_frame *msi;
+
+	/**
+	* Since ACPI 5.1 currently does not define
+	* a way to associate MSI frame ID to a device,
+	* we can only support single MSI frame (index 0)
+	* at the moment.
+	*/
+	err = acpi_gic_get_msi_frame(0, &msi);
+	if (err)
+		return NULL;
+
+	return (void *) msi->base_address;
+}
+
+static void *acpi_gic_its_token(struct device *dev)
+{
+	int err;
+	struct acpi_madt_generic_translator *trans;
+	int its_id = 0;
+
+	/**
+	 * TODO: We need a way to retrieve GIC ITS ID from
+	 * struct device pointer (in this case, the device
+	 * would be the PCI host controller.
+	 *
+	 * This would be done by the IORT-related code.
+	 *
+	 * its_id = get_its_id(dev);
+	 */
+
+	err = acpi_gic_get_its(its_id, &trans);
+	if (err)
+		return NULL;
+
+	return (void *) trans->base_address;
+}
+
+void *acpi_gic_get_msi_token(struct device *dev)
+{
+	void *token = acpi_gic_msi_token(dev);
+
+	if (!token)
+		token = acpi_gic_its_token(dev);
+
+	return token;
+}
diff --git a/include/acpi/acpi_gic.h b/include/acpi/acpi_gic.h
new file mode 100644
index 0000000..34fa475
--- /dev/null
+++ b/include/acpi/acpi_gic.h
@@ -0,0 +1,23 @@
+/*
+ *  include/acpi/acpi_gic.h
+ *
+ * Copyright (C) 2015 Advanced Micro Devices, Inc.
+ * Authors: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
+ */
+
+#ifndef __ACPI_GIC_H__
+#define __ACPI_GIC_H__
+
+#ifdef CONFIG_ACPI
+int acpi_gic_get_num_msi_frame(void);
+int acpi_gic_msi_init(struct acpi_table_header *table);
+int acpi_gic_get_msi_frame(int index, struct acpi_madt_generic_msi_frame **p);
+
+int acpi_gic_get_num_its(void);
+int acpi_gic_its_init(struct acpi_table_header *table);
+int acpi_gic_get_its(int index, struct acpi_madt_generic_translator **p);
+
+void *acpi_gic_get_msi_token(struct device *dev);
+#endif
+
+#endif /*__ACPI_GIC_H__*/
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 04dd0bb..5d58b61 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -44,6 +44,7 @@
 
 #include <acpi/acpi_bus.h>
 #include <acpi/acpi_drivers.h>
+#include <acpi/acpi_gic.h>
 #include <acpi/acpi_numa.h>
 #include <acpi/acpi_io.h>
 #include <asm/acpi.h>
-- 
1.9.1


  parent reply	other threads:[~2015-07-29 10:10 UTC|newest]

Thread overview: 43+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-07-29 10:08 [PATCH v4 00/10] ACPI GIC Self-probing, GICv2m and GICv3 support Hanjun Guo
2015-07-29 10:08 ` [PATCH v4 01/10] irqchip / GIC: Add GIC version support in ACPI MADT Hanjun Guo
2015-08-04 12:06   ` Marc Zyngier
2015-08-05 12:40     ` Hanjun Guo
2015-08-05 12:57       ` Marc Zyngier
2015-08-05 13:11         ` Hanjun Guo
2015-07-29 10:08 ` [PATCH v4 02/10] ACPI / irqchip: Add self-probe infrastructure to initialize IRQ controller Hanjun Guo
2015-08-04 12:27   ` Marc Zyngier
2015-08-05 13:24     ` Hanjun Guo
2015-08-06 16:29       ` Marc Zyngier
2015-07-29 10:08 ` [PATCH v4 03/10] irqchip / GIC / ACPI: Use IRQCHIP_ACPI_DECLARE to simplify GICv2 init code Hanjun Guo
2015-07-29 10:08 ` [PATCH v4 04/10] irqchip / GICv3: Refactor gic_of_init() for GICv3 driver Hanjun Guo
2015-07-29 10:08 ` [PATCH v4 05/10] irqchip / GICv3: remove the useless comparision of device node in xlate Hanjun Guo
2015-07-29 10:08 ` [PATCH v4 06/10] irqchip / GICv3: Add ACPI support for GICv3+ initialization Hanjun Guo
2015-08-04 13:17   ` Marc Zyngier
2015-08-05 14:00     ` Hanjun Guo
2015-08-06 16:42       ` Marc Zyngier
2015-08-11  7:19         ` Hanjun Guo
2015-07-29 10:08 ` [PATCH v4 07/10] irqchip / GICv3 / ACPI: Add GICR support via GICC structures Hanjun Guo
2015-08-04 13:37   ` Marc Zyngier
2015-08-05 14:11     ` Hanjun Guo
2015-08-06 16:42       ` Marc Zyngier
2015-07-29 10:08 ` Hanjun Guo [this message]
2015-08-04 14:02   ` [PATCH v4 08/10] ACPI: GIC: Add ACPI helper functions to query irq-domain tokens for for GIC MSI and ITS Marc Zyngier
2015-08-09  8:02     ` Suravee Suthikulpanit
2015-07-29 10:08 ` [PATCH v4 09/10] PCI: ACPI: Bind GIC MSI frame to PCI host bridge Hanjun Guo
2015-08-04 14:04   ` Marc Zyngier
2015-08-07  8:42     ` Hanjun Guo
2015-08-09  8:02     ` Suravee Suthikulpanit
2015-08-07 10:03   ` Tomasz Nowicki
2015-08-07 10:48     ` Mark Brown
2015-08-07 12:06     ` Marc Zyngier
2015-07-29 10:08 ` [PATCH v4 10/10] irqchip / gicv2m: Introducing gicv2m_acpi_init() Hanjun Guo
2015-08-04 14:23   ` Marc Zyngier
2015-08-09  8:04     ` Suravee Suthikulpanit
2015-08-11 22:01 ` [PATCH v4 00/10] ACPI GIC Self-probing, GICv2m and GICv3 support Timur Tabi
2015-08-11 22:24   ` [Linaro-acpi] " G Gregory
2015-08-11 22:25   ` Marc Zyngier
2015-08-11 22:36     ` Timur Tabi
2015-08-11 22:48       ` Marc Zyngier
2015-08-11 23:33         ` Timur Tabi
2015-08-12  7:21           ` Marc Zyngier
2015-08-12 19:20             ` Timur Tabi

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=1438164539-29256-9-git-send-email-hanjun.guo@linaro.org \
    --to=hanjun.guo@linaro.org \
    --cc=Lorenzo.Pieralisi@arm.com \
    --cc=Suravee.Suthikulpanit@amd.com \
    --cc=bhelgaas@google.com \
    --cc=broonie@kernel.org \
    --cc=catalin.marinas@arm.com \
    --cc=grant.likely@linaro.org \
    --cc=jason@lakedaemon.net \
    --cc=jiang.liu@linux.intel.com \
    --cc=linaro-acpi@lists.linaro.org \
    --cc=linux-acpi@vger.kernel.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=marc.zyngier@arm.com \
    --cc=rjw@rjwysocki.net \
    --cc=tglx@linutronix.de \
    --cc=timur@codeaurora.org \
    --cc=tomasz.nowicki@linaro.org \
    --cc=wei@redhat.com \
    --cc=will.deacon@arm.com \
    /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;
as well as URLs for NNTP newsgroup(s).