All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v7 0/4] gicv2m: acpi: Add ACPI support for GICv2m MSI
@ 2015-12-10 16:55 ` Suravee Suthikulpanit
  0 siblings, 0 replies; 42+ messages in thread
From: Suravee Suthikulpanit @ 2015-12-10 16:55 UTC (permalink / raw)
  To: marc.zyngier, tglx, jason, rjw, bhelgaas
  Cc: Lorenzo Pieralisi, Will Deacon, Catalin Marinas, hanjun.guo,
	tomasz.nowicki, graeme.gregory, dhdang, linux-arm-kernel,
	linux-kernel, linux-acpi, linux-pci, Suravee Suthikulpanit

This patch series has been forked from the following patch series since
it no longer depends on the rest of the patches.

  [PATCH v4 00/10] ACPI GIC Self-probing, GICv2m and GICv3 support
  https://lkml.org/lkml/2015/7/29/234

It has been ported to use the newly introduced device fwnode_handle 
for ACPI irqdmain introduced by Marc in the following patch series:

  [PATCH v2 00/17] Divorcing irqdomain and device_node

The following git branch contains the submitted patches along with
the pre-requsite patches (mainly for ARM64 PCI support for ACPI).

  https://github.com/ssuthiku/linux.git	v2m-multiframe-v7

This has been tested on AMD Seattle (Overdrive) RevB system. 

NOTE: I have not tested ACPI GICv2m multiframe support since
I don't have access to such system. Any helps are appreciated.

Thanks,
Suravee

Changes from V6: (https://lkml.org/lkml/2015/12/9/660)
  - Minor logic change recommended by Marc
  - Added Reviewed-by Marc for patch 4
  - Added Tested-by Duc for patch 4 

Changes from V5: (https://lkml.org/lkml/2015/12/08/763)
  - Remove previous patch 3
  - Clean up based on Marc's review (patch 1.4)
  - Add Ackedb-by and Reviewed-by (Patch 1,2,3)
  - Expose single gicv2m_init() function for both OF and ACPI
    (per Marc's suggestion)
  - Remove gicv2m name from pr_info since this is no longer useful
    (in patch 3) (per Marc's suggestion)

Changes from V4: (https://lkml.org/lkml/2015/12/08/613)
  - Fix build error when not specifying CONFIG_IRQ_DOMAIN.

Changes from V3: (https://lkml.org/lkml/2015/10/21/691)
  - Merged patch 2 into 1, and got rid off pci_msi_get_fwnode()
    since only ACPI will likely use this. (per Marc suggestion)
  - Rebased to 4.4.0-rc4

Changes from V2: (https://lkml.org/lkml/2015/10/14/1010)
  - Minor clean up from Tomasz review comment in patch 6/6.

Changes from V1: (https://lkml.org/lkml/2015/10/13/859)
  - Rebase on top of Marc's patch to addng support for multiple MSI frames
    (https://lkml.org/lkml/2015/10/14/271)
  - Adding fwnode convenient functions (patch 3 and 4)

Suravee Suthikulpanit (4):
  acpi: pci: Setup MSI domain for ACPI based pci devices
  irqdomain: introduce is_fwnode_irqchip helper
  gicv2m: Refactor to prepare for ACPI support
  gicv2m: acpi: Introducing GICv2m ACPI support

 drivers/irqchip/irq-gic-v2m.c   | 163 ++++++++++++++++++++++++++++++++++------
 drivers/irqchip/irq-gic.c       |   8 +-
 drivers/pci/pci-acpi.c          |  42 +++++++++++
 drivers/pci/probe.c             |   2 +
 include/linux/irqchip/arm-gic.h |   3 +-
 include/linux/irqdomain.h       |  10 +++
 include/linux/pci.h             |  10 +++
 kernel/irq/irqdomain.c          |   2 +-
 8 files changed, 214 insertions(+), 26 deletions(-)

-- 
2.1.0

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

* [PATCH v7 0/4] gicv2m: acpi: Add ACPI support for GICv2m MSI
@ 2015-12-10 16:55 ` Suravee Suthikulpanit
  0 siblings, 0 replies; 42+ messages in thread
From: Suravee Suthikulpanit @ 2015-12-10 16:55 UTC (permalink / raw)
  To: marc.zyngier, tglx, jason, rjw, bhelgaas
  Cc: Lorenzo Pieralisi, Will Deacon, Catalin Marinas, hanjun.guo,
	tomasz.nowicki, graeme.gregory, dhdang, linux-arm-kernel,
	linux-kernel, linux-acpi, linux-pci, Suravee Suthikulpanit

This patch series has been forked from the following patch series since
it no longer depends on the rest of the patches.

  [PATCH v4 00/10] ACPI GIC Self-probing, GICv2m and GICv3 support
  https://lkml.org/lkml/2015/7/29/234

It has been ported to use the newly introduced device fwnode_handle 
for ACPI irqdmain introduced by Marc in the following patch series:

  [PATCH v2 00/17] Divorcing irqdomain and device_node

The following git branch contains the submitted patches along with
the pre-requsite patches (mainly for ARM64 PCI support for ACPI).

  https://github.com/ssuthiku/linux.git	v2m-multiframe-v7

This has been tested on AMD Seattle (Overdrive) RevB system. 

NOTE: I have not tested ACPI GICv2m multiframe support since
I don't have access to such system. Any helps are appreciated.

Thanks,
Suravee

Changes from V6: (https://lkml.org/lkml/2015/12/9/660)
  - Minor logic change recommended by Marc
  - Added Reviewed-by Marc for patch 4
  - Added Tested-by Duc for patch 4 

Changes from V5: (https://lkml.org/lkml/2015/12/08/763)
  - Remove previous patch 3
  - Clean up based on Marc's review (patch 1.4)
  - Add Ackedb-by and Reviewed-by (Patch 1,2,3)
  - Expose single gicv2m_init() function for both OF and ACPI
    (per Marc's suggestion)
  - Remove gicv2m name from pr_info since this is no longer useful
    (in patch 3) (per Marc's suggestion)

Changes from V4: (https://lkml.org/lkml/2015/12/08/613)
  - Fix build error when not specifying CONFIG_IRQ_DOMAIN.

Changes from V3: (https://lkml.org/lkml/2015/10/21/691)
  - Merged patch 2 into 1, and got rid off pci_msi_get_fwnode()
    since only ACPI will likely use this. (per Marc suggestion)
  - Rebased to 4.4.0-rc4

Changes from V2: (https://lkml.org/lkml/2015/10/14/1010)
  - Minor clean up from Tomasz review comment in patch 6/6.

Changes from V1: (https://lkml.org/lkml/2015/10/13/859)
  - Rebase on top of Marc's patch to addng support for multiple MSI frames
    (https://lkml.org/lkml/2015/10/14/271)
  - Adding fwnode convenient functions (patch 3 and 4)

Suravee Suthikulpanit (4):
  acpi: pci: Setup MSI domain for ACPI based pci devices
  irqdomain: introduce is_fwnode_irqchip helper
  gicv2m: Refactor to prepare for ACPI support
  gicv2m: acpi: Introducing GICv2m ACPI support

 drivers/irqchip/irq-gic-v2m.c   | 163 ++++++++++++++++++++++++++++++++++------
 drivers/irqchip/irq-gic.c       |   8 +-
 drivers/pci/pci-acpi.c          |  42 +++++++++++
 drivers/pci/probe.c             |   2 +
 include/linux/irqchip/arm-gic.h |   3 +-
 include/linux/irqdomain.h       |  10 +++
 include/linux/pci.h             |  10 +++
 kernel/irq/irqdomain.c          |   2 +-
 8 files changed, 214 insertions(+), 26 deletions(-)

-- 
2.1.0


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

* [PATCH v7 0/4] gicv2m: acpi: Add ACPI support for GICv2m MSI
@ 2015-12-10 16:55 ` Suravee Suthikulpanit
  0 siblings, 0 replies; 42+ messages in thread
From: Suravee Suthikulpanit @ 2015-12-10 16:55 UTC (permalink / raw)
  To: linux-arm-kernel

This patch series has been forked from the following patch series since
it no longer depends on the rest of the patches.

  [PATCH v4 00/10] ACPI GIC Self-probing, GICv2m and GICv3 support
  https://lkml.org/lkml/2015/7/29/234

It has been ported to use the newly introduced device fwnode_handle 
for ACPI irqdmain introduced by Marc in the following patch series:

  [PATCH v2 00/17] Divorcing irqdomain and device_node

The following git branch contains the submitted patches along with
the pre-requsite patches (mainly for ARM64 PCI support for ACPI).

  https://github.com/ssuthiku/linux.git	v2m-multiframe-v7

This has been tested on AMD Seattle (Overdrive) RevB system. 

NOTE: I have not tested ACPI GICv2m multiframe support since
I don't have access to such system. Any helps are appreciated.

Thanks,
Suravee

Changes from V6: (https://lkml.org/lkml/2015/12/9/660)
  - Minor logic change recommended by Marc
  - Added Reviewed-by Marc for patch 4
  - Added Tested-by Duc for patch 4 

Changes from V5: (https://lkml.org/lkml/2015/12/08/763)
  - Remove previous patch 3
  - Clean up based on Marc's review (patch 1.4)
  - Add Ackedb-by and Reviewed-by (Patch 1,2,3)
  - Expose single gicv2m_init() function for both OF and ACPI
    (per Marc's suggestion)
  - Remove gicv2m name from pr_info since this is no longer useful
    (in patch 3) (per Marc's suggestion)

Changes from V4: (https://lkml.org/lkml/2015/12/08/613)
  - Fix build error when not specifying CONFIG_IRQ_DOMAIN.

Changes from V3: (https://lkml.org/lkml/2015/10/21/691)
  - Merged patch 2 into 1, and got rid off pci_msi_get_fwnode()
    since only ACPI will likely use this. (per Marc suggestion)
  - Rebased to 4.4.0-rc4

Changes from V2: (https://lkml.org/lkml/2015/10/14/1010)
  - Minor clean up from Tomasz review comment in patch 6/6.

Changes from V1: (https://lkml.org/lkml/2015/10/13/859)
  - Rebase on top of Marc's patch to addng support for multiple MSI frames
    (https://lkml.org/lkml/2015/10/14/271)
  - Adding fwnode convenient functions (patch 3 and 4)

Suravee Suthikulpanit (4):
  acpi: pci: Setup MSI domain for ACPI based pci devices
  irqdomain: introduce is_fwnode_irqchip helper
  gicv2m: Refactor to prepare for ACPI support
  gicv2m: acpi: Introducing GICv2m ACPI support

 drivers/irqchip/irq-gic-v2m.c   | 163 ++++++++++++++++++++++++++++++++++------
 drivers/irqchip/irq-gic.c       |   8 +-
 drivers/pci/pci-acpi.c          |  42 +++++++++++
 drivers/pci/probe.c             |   2 +
 include/linux/irqchip/arm-gic.h |   3 +-
 include/linux/irqdomain.h       |  10 +++
 include/linux/pci.h             |  10 +++
 kernel/irq/irqdomain.c          |   2 +-
 8 files changed, 214 insertions(+), 26 deletions(-)

-- 
2.1.0

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

* [PATCH v7 1/4] acpi: pci: Setup MSI domain for ACPI based pci devices
  2015-12-10 16:55 ` Suravee Suthikulpanit
  (?)
@ 2015-12-10 16:55   ` Suravee Suthikulpanit
  -1 siblings, 0 replies; 42+ messages in thread
From: Suravee Suthikulpanit @ 2015-12-10 16:55 UTC (permalink / raw)
  To: marc.zyngier, tglx, jason, rjw, bhelgaas
  Cc: Lorenzo Pieralisi, Will Deacon, Catalin Marinas, hanjun.guo,
	tomasz.nowicki, graeme.gregory, dhdang, linux-arm-kernel,
	linux-kernel, linux-acpi, linux-pci, Suravee Suthikulpanit

This patch introduces pci_msi_register_fwnode_provider() for irqchip
to register a callback, to provide a way to determine appropriate MSI
domain for a pci device.

It also introduces pci_host_bridge_acpi_msi_domain(), which returns
the MSI domain of the specified PCI host bridge with DOMAIN_BUS_PCI_MSI
bus token. Then, it is assigned to pci device.

Reviewed-by: Marc Zyngier <marc.zyngier@arm.com>
Cc: Bjorn Helgaas <bhelgaas@google.com>
Cc: Rafael J. Wysocki <rjw@rjwysocki.net>
Signed-off-by: Suravee Suthikulpanit <Suravee.Suthikulpanit@amd.com>
---
 drivers/pci/pci-acpi.c    | 42 ++++++++++++++++++++++++++++++++++++++++++
 drivers/pci/probe.c       |  2 ++
 include/linux/irqdomain.h |  5 +++++
 include/linux/pci.h       | 10 ++++++++++
 4 files changed, 59 insertions(+)

diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
index a32ba75..d3f32d6 100644
--- a/drivers/pci/pci-acpi.c
+++ b/drivers/pci/pci-acpi.c
@@ -9,7 +9,9 @@
 
 #include <linux/delay.h>
 #include <linux/init.h>
+#include <linux/irqdomain.h>
 #include <linux/pci.h>
+#include <linux/msi.h>
 #include <linux/pci_hotplug.h>
 #include <linux/module.h>
 #include <linux/pci-aspm.h>
@@ -689,6 +691,46 @@ static struct acpi_bus_type acpi_pci_bus = {
 	.cleanup = pci_acpi_cleanup,
 };
 
+
+static struct fwnode_handle *(*pci_msi_get_fwnode_cb)(struct device *dev);
+
+/**
+ * pci_msi_register_fwnode_provider - Register callback to retrieve fwnode
+ * @fn:       Callback matching a device to a fwnode that identifies a PCI
+ *            MSI domain.
+ *
+ * This should be called by irqchip driver, which is the parent of
+ * the MSI domain to provide callback interface to query fwnode.
+ */
+void
+pci_msi_register_fwnode_provider(struct fwnode_handle *(*fn)(struct device *))
+{
+	pci_msi_get_fwnode_cb = fn;
+}
+
+/**
+ * pci_host_bridge_acpi_msi_domain - Retrieve MSI domain of a PCI host bridge
+ * @bus:      The PCI host bridge bus.
+ *
+ * This function uses the callback function registered by
+ * pci_msi_register_fwnode_provider() to retrieve the irq_domain with
+ * type DOMAIN_BUS_PCI_MSI of the specified host bridge bus.
+ * This returns NULL on error or when the domain is not found.
+ */
+struct irq_domain *pci_host_bridge_acpi_msi_domain(struct pci_bus *bus)
+{
+	struct fwnode_handle *fwnode;
+
+	if (!pci_msi_get_fwnode_cb)
+		return NULL;
+
+	fwnode = pci_msi_get_fwnode_cb(&bus->dev);
+	if (!fwnode)
+		return NULL;
+
+	return irq_find_matching_fwnode(fwnode, DOMAIN_BUS_PCI_MSI);
+}
+
 static int __init acpi_pci_init(void)
 {
 	int ret;
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index edb1984..553a029 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -672,6 +672,8 @@ static struct irq_domain *pci_host_bridge_msi_domain(struct pci_bus *bus)
 	 * should be called from here.
 	 */
 	d = pci_host_bridge_of_msi_domain(bus);
+	if (!d)
+		d = pci_host_bridge_acpi_msi_domain(bus);
 
 	return d;
 }
diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
index d5e5c5b..a06feda 100644
--- a/include/linux/irqdomain.h
+++ b/include/linux/irqdomain.h
@@ -410,6 +410,11 @@ static inline bool irq_domain_is_hierarchy(struct irq_domain *domain)
 static inline void irq_dispose_mapping(unsigned int virq) { }
 static inline void irq_domain_activate_irq(struct irq_data *data) { }
 static inline void irq_domain_deactivate_irq(struct irq_data *data) { }
+static inline struct irq_domain *irq_find_matching_fwnode(
+	struct fwnode_handle *fwnode, enum irq_domain_bus_token bus_token)
+{
+	return NULL;
+}
 #endif /* !CONFIG_IRQ_DOMAIN */
 
 #endif /* _LINUX_IRQDOMAIN_H */
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 6ae25aa..d86378c 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -1946,6 +1946,16 @@ static inline struct irq_domain *
 pci_host_bridge_of_msi_domain(struct pci_bus *bus) { return NULL; }
 #endif  /* CONFIG_OF */
 
+#ifdef CONFIG_ACPI
+struct irq_domain *pci_host_bridge_acpi_msi_domain(struct pci_bus *bus);
+
+void
+pci_msi_register_fwnode_provider(struct fwnode_handle *(*fn)(struct device *));
+#else
+static inline struct irq_domain *
+pci_host_bridge_acpi_msi_domain(struct pci_bus *bus) { return NULL; }
+#endif
+
 #ifdef CONFIG_EEH
 static inline struct eeh_dev *pci_dev_to_eeh_dev(struct pci_dev *pdev)
 {
-- 
2.1.0

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

* [PATCH v7 1/4] acpi: pci: Setup MSI domain for ACPI based pci devices
@ 2015-12-10 16:55   ` Suravee Suthikulpanit
  0 siblings, 0 replies; 42+ messages in thread
From: Suravee Suthikulpanit @ 2015-12-10 16:55 UTC (permalink / raw)
  To: marc.zyngier, tglx, jason, rjw, bhelgaas
  Cc: Lorenzo Pieralisi, Will Deacon, Catalin Marinas, hanjun.guo,
	tomasz.nowicki, graeme.gregory, dhdang, linux-arm-kernel,
	linux-kernel, linux-acpi, linux-pci, Suravee Suthikulpanit

This patch introduces pci_msi_register_fwnode_provider() for irqchip
to register a callback, to provide a way to determine appropriate MSI
domain for a pci device.

It also introduces pci_host_bridge_acpi_msi_domain(), which returns
the MSI domain of the specified PCI host bridge with DOMAIN_BUS_PCI_MSI
bus token. Then, it is assigned to pci device.

Reviewed-by: Marc Zyngier <marc.zyngier@arm.com>
Cc: Bjorn Helgaas <bhelgaas@google.com>
Cc: Rafael J. Wysocki <rjw@rjwysocki.net>
Signed-off-by: Suravee Suthikulpanit <Suravee.Suthikulpanit@amd.com>
---
 drivers/pci/pci-acpi.c    | 42 ++++++++++++++++++++++++++++++++++++++++++
 drivers/pci/probe.c       |  2 ++
 include/linux/irqdomain.h |  5 +++++
 include/linux/pci.h       | 10 ++++++++++
 4 files changed, 59 insertions(+)

diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
index a32ba75..d3f32d6 100644
--- a/drivers/pci/pci-acpi.c
+++ b/drivers/pci/pci-acpi.c
@@ -9,7 +9,9 @@
 
 #include <linux/delay.h>
 #include <linux/init.h>
+#include <linux/irqdomain.h>
 #include <linux/pci.h>
+#include <linux/msi.h>
 #include <linux/pci_hotplug.h>
 #include <linux/module.h>
 #include <linux/pci-aspm.h>
@@ -689,6 +691,46 @@ static struct acpi_bus_type acpi_pci_bus = {
 	.cleanup = pci_acpi_cleanup,
 };
 
+
+static struct fwnode_handle *(*pci_msi_get_fwnode_cb)(struct device *dev);
+
+/**
+ * pci_msi_register_fwnode_provider - Register callback to retrieve fwnode
+ * @fn:       Callback matching a device to a fwnode that identifies a PCI
+ *            MSI domain.
+ *
+ * This should be called by irqchip driver, which is the parent of
+ * the MSI domain to provide callback interface to query fwnode.
+ */
+void
+pci_msi_register_fwnode_provider(struct fwnode_handle *(*fn)(struct device *))
+{
+	pci_msi_get_fwnode_cb = fn;
+}
+
+/**
+ * pci_host_bridge_acpi_msi_domain - Retrieve MSI domain of a PCI host bridge
+ * @bus:      The PCI host bridge bus.
+ *
+ * This function uses the callback function registered by
+ * pci_msi_register_fwnode_provider() to retrieve the irq_domain with
+ * type DOMAIN_BUS_PCI_MSI of the specified host bridge bus.
+ * This returns NULL on error or when the domain is not found.
+ */
+struct irq_domain *pci_host_bridge_acpi_msi_domain(struct pci_bus *bus)
+{
+	struct fwnode_handle *fwnode;
+
+	if (!pci_msi_get_fwnode_cb)
+		return NULL;
+
+	fwnode = pci_msi_get_fwnode_cb(&bus->dev);
+	if (!fwnode)
+		return NULL;
+
+	return irq_find_matching_fwnode(fwnode, DOMAIN_BUS_PCI_MSI);
+}
+
 static int __init acpi_pci_init(void)
 {
 	int ret;
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index edb1984..553a029 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -672,6 +672,8 @@ static struct irq_domain *pci_host_bridge_msi_domain(struct pci_bus *bus)
 	 * should be called from here.
 	 */
 	d = pci_host_bridge_of_msi_domain(bus);
+	if (!d)
+		d = pci_host_bridge_acpi_msi_domain(bus);
 
 	return d;
 }
diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
index d5e5c5b..a06feda 100644
--- a/include/linux/irqdomain.h
+++ b/include/linux/irqdomain.h
@@ -410,6 +410,11 @@ static inline bool irq_domain_is_hierarchy(struct irq_domain *domain)
 static inline void irq_dispose_mapping(unsigned int virq) { }
 static inline void irq_domain_activate_irq(struct irq_data *data) { }
 static inline void irq_domain_deactivate_irq(struct irq_data *data) { }
+static inline struct irq_domain *irq_find_matching_fwnode(
+	struct fwnode_handle *fwnode, enum irq_domain_bus_token bus_token)
+{
+	return NULL;
+}
 #endif /* !CONFIG_IRQ_DOMAIN */
 
 #endif /* _LINUX_IRQDOMAIN_H */
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 6ae25aa..d86378c 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -1946,6 +1946,16 @@ static inline struct irq_domain *
 pci_host_bridge_of_msi_domain(struct pci_bus *bus) { return NULL; }
 #endif  /* CONFIG_OF */
 
+#ifdef CONFIG_ACPI
+struct irq_domain *pci_host_bridge_acpi_msi_domain(struct pci_bus *bus);
+
+void
+pci_msi_register_fwnode_provider(struct fwnode_handle *(*fn)(struct device *));
+#else
+static inline struct irq_domain *
+pci_host_bridge_acpi_msi_domain(struct pci_bus *bus) { return NULL; }
+#endif
+
 #ifdef CONFIG_EEH
 static inline struct eeh_dev *pci_dev_to_eeh_dev(struct pci_dev *pdev)
 {
-- 
2.1.0


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

* [PATCH v7 1/4] acpi: pci: Setup MSI domain for ACPI based pci devices
@ 2015-12-10 16:55   ` Suravee Suthikulpanit
  0 siblings, 0 replies; 42+ messages in thread
From: Suravee Suthikulpanit @ 2015-12-10 16:55 UTC (permalink / raw)
  To: linux-arm-kernel

This patch introduces pci_msi_register_fwnode_provider() for irqchip
to register a callback, to provide a way to determine appropriate MSI
domain for a pci device.

It also introduces pci_host_bridge_acpi_msi_domain(), which returns
the MSI domain of the specified PCI host bridge with DOMAIN_BUS_PCI_MSI
bus token. Then, it is assigned to pci device.

Reviewed-by: Marc Zyngier <marc.zyngier@arm.com>
Cc: Bjorn Helgaas <bhelgaas@google.com>
Cc: Rafael J. Wysocki <rjw@rjwysocki.net>
Signed-off-by: Suravee Suthikulpanit <Suravee.Suthikulpanit@amd.com>
---
 drivers/pci/pci-acpi.c    | 42 ++++++++++++++++++++++++++++++++++++++++++
 drivers/pci/probe.c       |  2 ++
 include/linux/irqdomain.h |  5 +++++
 include/linux/pci.h       | 10 ++++++++++
 4 files changed, 59 insertions(+)

diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
index a32ba75..d3f32d6 100644
--- a/drivers/pci/pci-acpi.c
+++ b/drivers/pci/pci-acpi.c
@@ -9,7 +9,9 @@
 
 #include <linux/delay.h>
 #include <linux/init.h>
+#include <linux/irqdomain.h>
 #include <linux/pci.h>
+#include <linux/msi.h>
 #include <linux/pci_hotplug.h>
 #include <linux/module.h>
 #include <linux/pci-aspm.h>
@@ -689,6 +691,46 @@ static struct acpi_bus_type acpi_pci_bus = {
 	.cleanup = pci_acpi_cleanup,
 };
 
+
+static struct fwnode_handle *(*pci_msi_get_fwnode_cb)(struct device *dev);
+
+/**
+ * pci_msi_register_fwnode_provider - Register callback to retrieve fwnode
+ * @fn:       Callback matching a device to a fwnode that identifies a PCI
+ *            MSI domain.
+ *
+ * This should be called by irqchip driver, which is the parent of
+ * the MSI domain to provide callback interface to query fwnode.
+ */
+void
+pci_msi_register_fwnode_provider(struct fwnode_handle *(*fn)(struct device *))
+{
+	pci_msi_get_fwnode_cb = fn;
+}
+
+/**
+ * pci_host_bridge_acpi_msi_domain - Retrieve MSI domain of a PCI host bridge
+ * @bus:      The PCI host bridge bus.
+ *
+ * This function uses the callback function registered by
+ * pci_msi_register_fwnode_provider() to retrieve the irq_domain with
+ * type DOMAIN_BUS_PCI_MSI of the specified host bridge bus.
+ * This returns NULL on error or when the domain is not found.
+ */
+struct irq_domain *pci_host_bridge_acpi_msi_domain(struct pci_bus *bus)
+{
+	struct fwnode_handle *fwnode;
+
+	if (!pci_msi_get_fwnode_cb)
+		return NULL;
+
+	fwnode = pci_msi_get_fwnode_cb(&bus->dev);
+	if (!fwnode)
+		return NULL;
+
+	return irq_find_matching_fwnode(fwnode, DOMAIN_BUS_PCI_MSI);
+}
+
 static int __init acpi_pci_init(void)
 {
 	int ret;
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index edb1984..553a029 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -672,6 +672,8 @@ static struct irq_domain *pci_host_bridge_msi_domain(struct pci_bus *bus)
 	 * should be called from here.
 	 */
 	d = pci_host_bridge_of_msi_domain(bus);
+	if (!d)
+		d = pci_host_bridge_acpi_msi_domain(bus);
 
 	return d;
 }
diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
index d5e5c5b..a06feda 100644
--- a/include/linux/irqdomain.h
+++ b/include/linux/irqdomain.h
@@ -410,6 +410,11 @@ static inline bool irq_domain_is_hierarchy(struct irq_domain *domain)
 static inline void irq_dispose_mapping(unsigned int virq) { }
 static inline void irq_domain_activate_irq(struct irq_data *data) { }
 static inline void irq_domain_deactivate_irq(struct irq_data *data) { }
+static inline struct irq_domain *irq_find_matching_fwnode(
+	struct fwnode_handle *fwnode, enum irq_domain_bus_token bus_token)
+{
+	return NULL;
+}
 #endif /* !CONFIG_IRQ_DOMAIN */
 
 #endif /* _LINUX_IRQDOMAIN_H */
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 6ae25aa..d86378c 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -1946,6 +1946,16 @@ static inline struct irq_domain *
 pci_host_bridge_of_msi_domain(struct pci_bus *bus) { return NULL; }
 #endif  /* CONFIG_OF */
 
+#ifdef CONFIG_ACPI
+struct irq_domain *pci_host_bridge_acpi_msi_domain(struct pci_bus *bus);
+
+void
+pci_msi_register_fwnode_provider(struct fwnode_handle *(*fn)(struct device *));
+#else
+static inline struct irq_domain *
+pci_host_bridge_acpi_msi_domain(struct pci_bus *bus) { return NULL; }
+#endif
+
 #ifdef CONFIG_EEH
 static inline struct eeh_dev *pci_dev_to_eeh_dev(struct pci_dev *pdev)
 {
-- 
2.1.0

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

* [PATCH v7 2/4] irqdomain: introduce is_fwnode_irqchip helper
  2015-12-10 16:55 ` Suravee Suthikulpanit
  (?)
@ 2015-12-10 16:55   ` Suravee Suthikulpanit
  -1 siblings, 0 replies; 42+ messages in thread
From: Suravee Suthikulpanit @ 2015-12-10 16:55 UTC (permalink / raw)
  To: marc.zyngier, tglx, jason, rjw, bhelgaas
  Cc: Lorenzo Pieralisi, Will Deacon, Catalin Marinas, hanjun.guo,
	tomasz.nowicki, graeme.gregory, dhdang, linux-arm-kernel,
	linux-kernel, linux-acpi, linux-pci, Suravee Suthikulpanit

Since there will be several places checking if fwnode.type
is equal FWNODE_IRQCHIP, this patch adds a convenient function
for this purpose.

Acked-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Suravee Suthikulpanit <Suravee.Suthikulpanit@amd.com>
---
 drivers/irqchip/irq-gic.c | 2 +-
 include/linux/irqdomain.h | 5 +++++
 kernel/irq/irqdomain.c    | 2 +-
 3 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
index abf2ffa..fcd327f 100644
--- a/drivers/irqchip/irq-gic.c
+++ b/drivers/irqchip/irq-gic.c
@@ -972,7 +972,7 @@ static int gic_irq_domain_translate(struct irq_domain *d,
 		return 0;
 	}
 
-	if (fwspec->fwnode->type == FWNODE_IRQCHIP) {
+	if (is_fwnode_irqchip(fwspec->fwnode)) {
 		if(fwspec->param_count != 2)
 			return -EINVAL;
 
diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
index a06feda..d72fabc 100644
--- a/include/linux/irqdomain.h
+++ b/include/linux/irqdomain.h
@@ -211,6 +211,11 @@ static inline struct fwnode_handle *of_node_to_fwnode(struct device_node *node)
 	return node ? &node->fwnode : NULL;
 }
 
+static inline bool is_fwnode_irqchip(struct fwnode_handle *fwnode)
+{
+	return fwnode && fwnode->type == FWNODE_IRQCHIP;
+}
+
 static inline struct irq_domain *irq_find_matching_host(struct device_node *node,
 							enum irq_domain_bus_token bus_token)
 {
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index 22aa961..7f34d98 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -70,7 +70,7 @@ void irq_domain_free_fwnode(struct fwnode_handle *fwnode)
 {
 	struct irqchip_fwid *fwid;
 
-	if (WARN_ON(fwnode->type != FWNODE_IRQCHIP))
+	if (WARN_ON(!is_fwnode_irqchip(fwnode)))
 		return;
 
 	fwid = container_of(fwnode, struct irqchip_fwid, fwnode);
-- 
2.1.0

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

* [PATCH v7 2/4] irqdomain: introduce is_fwnode_irqchip helper
@ 2015-12-10 16:55   ` Suravee Suthikulpanit
  0 siblings, 0 replies; 42+ messages in thread
From: Suravee Suthikulpanit @ 2015-12-10 16:55 UTC (permalink / raw)
  To: marc.zyngier, tglx, jason, rjw, bhelgaas
  Cc: Lorenzo Pieralisi, Will Deacon, Catalin Marinas, hanjun.guo,
	tomasz.nowicki, graeme.gregory, dhdang, linux-arm-kernel,
	linux-kernel, linux-acpi, linux-pci, Suravee Suthikulpanit

Since there will be several places checking if fwnode.type
is equal FWNODE_IRQCHIP, this patch adds a convenient function
for this purpose.

Acked-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Suravee Suthikulpanit <Suravee.Suthikulpanit@amd.com>
---
 drivers/irqchip/irq-gic.c | 2 +-
 include/linux/irqdomain.h | 5 +++++
 kernel/irq/irqdomain.c    | 2 +-
 3 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
index abf2ffa..fcd327f 100644
--- a/drivers/irqchip/irq-gic.c
+++ b/drivers/irqchip/irq-gic.c
@@ -972,7 +972,7 @@ static int gic_irq_domain_translate(struct irq_domain *d,
 		return 0;
 	}
 
-	if (fwspec->fwnode->type == FWNODE_IRQCHIP) {
+	if (is_fwnode_irqchip(fwspec->fwnode)) {
 		if(fwspec->param_count != 2)
 			return -EINVAL;
 
diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
index a06feda..d72fabc 100644
--- a/include/linux/irqdomain.h
+++ b/include/linux/irqdomain.h
@@ -211,6 +211,11 @@ static inline struct fwnode_handle *of_node_to_fwnode(struct device_node *node)
 	return node ? &node->fwnode : NULL;
 }
 
+static inline bool is_fwnode_irqchip(struct fwnode_handle *fwnode)
+{
+	return fwnode && fwnode->type == FWNODE_IRQCHIP;
+}
+
 static inline struct irq_domain *irq_find_matching_host(struct device_node *node,
 							enum irq_domain_bus_token bus_token)
 {
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index 22aa961..7f34d98 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -70,7 +70,7 @@ void irq_domain_free_fwnode(struct fwnode_handle *fwnode)
 {
 	struct irqchip_fwid *fwid;
 
-	if (WARN_ON(fwnode->type != FWNODE_IRQCHIP))
+	if (WARN_ON(!is_fwnode_irqchip(fwnode)))
 		return;
 
 	fwid = container_of(fwnode, struct irqchip_fwid, fwnode);
-- 
2.1.0


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

* [PATCH v7 2/4] irqdomain: introduce is_fwnode_irqchip helper
@ 2015-12-10 16:55   ` Suravee Suthikulpanit
  0 siblings, 0 replies; 42+ messages in thread
From: Suravee Suthikulpanit @ 2015-12-10 16:55 UTC (permalink / raw)
  To: linux-arm-kernel

Since there will be several places checking if fwnode.type
is equal FWNODE_IRQCHIP, this patch adds a convenient function
for this purpose.

Acked-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Suravee Suthikulpanit <Suravee.Suthikulpanit@amd.com>
---
 drivers/irqchip/irq-gic.c | 2 +-
 include/linux/irqdomain.h | 5 +++++
 kernel/irq/irqdomain.c    | 2 +-
 3 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
index abf2ffa..fcd327f 100644
--- a/drivers/irqchip/irq-gic.c
+++ b/drivers/irqchip/irq-gic.c
@@ -972,7 +972,7 @@ static int gic_irq_domain_translate(struct irq_domain *d,
 		return 0;
 	}
 
-	if (fwspec->fwnode->type == FWNODE_IRQCHIP) {
+	if (is_fwnode_irqchip(fwspec->fwnode)) {
 		if(fwspec->param_count != 2)
 			return -EINVAL;
 
diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
index a06feda..d72fabc 100644
--- a/include/linux/irqdomain.h
+++ b/include/linux/irqdomain.h
@@ -211,6 +211,11 @@ static inline struct fwnode_handle *of_node_to_fwnode(struct device_node *node)
 	return node ? &node->fwnode : NULL;
 }
 
+static inline bool is_fwnode_irqchip(struct fwnode_handle *fwnode)
+{
+	return fwnode && fwnode->type == FWNODE_IRQCHIP;
+}
+
 static inline struct irq_domain *irq_find_matching_host(struct device_node *node,
 							enum irq_domain_bus_token bus_token)
 {
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index 22aa961..7f34d98 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -70,7 +70,7 @@ void irq_domain_free_fwnode(struct fwnode_handle *fwnode)
 {
 	struct irqchip_fwid *fwid;
 
-	if (WARN_ON(fwnode->type != FWNODE_IRQCHIP))
+	if (WARN_ON(!is_fwnode_irqchip(fwnode)))
 		return;
 
 	fwid = container_of(fwnode, struct irqchip_fwid, fwnode);
-- 
2.1.0

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

* [PATCH v7 3/4] gicv2m: Refactor to prepare for ACPI support
  2015-12-10 16:55 ` Suravee Suthikulpanit
  (?)
@ 2015-12-10 16:55   ` Suravee Suthikulpanit
  -1 siblings, 0 replies; 42+ messages in thread
From: Suravee Suthikulpanit @ 2015-12-10 16:55 UTC (permalink / raw)
  To: marc.zyngier, tglx, jason, rjw, bhelgaas
  Cc: Lorenzo Pieralisi, graeme.gregory, Catalin Marinas, dhdang,
	Will Deacon, linux-kernel, tomasz.nowicki, linux-acpi,
	hanjun.guo, Suravee Suthikulpanit, linux-pci, linux-arm-kernel

This patch replaces the struct device_node with struct fwnode_handle
since this structure is common between DT and ACPI.

It also refactors gicv2m_init_one() to prepare for ACPI support.
The only functional change is removing the node name from pr_info.

Reviewed-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Suravee Suthikulpanit <Suravee.Suthikulpanit@amd.com>
---
 drivers/irqchip/irq-gic-v2m.c | 53 ++++++++++++++++++++++++++-----------------
 1 file changed, 32 insertions(+), 21 deletions(-)

diff --git a/drivers/irqchip/irq-gic-v2m.c b/drivers/irqchip/irq-gic-v2m.c
index 87f8d10..779c390 100644
--- a/drivers/irqchip/irq-gic-v2m.c
+++ b/drivers/irqchip/irq-gic-v2m.c
@@ -55,7 +55,7 @@ static DEFINE_SPINLOCK(v2m_lock);
 
 struct v2m_data {
 	struct list_head entry;
-	struct device_node *node;
+	struct fwnode_handle *fwnode;
 	struct resource res;	/* GICv2m resource */
 	void __iomem *base;	/* GICv2m virt address */
 	u32 spi_start;		/* The SPI number that MSIs start */
@@ -254,7 +254,7 @@ static void gicv2m_teardown(void)
 		list_del(&v2m->entry);
 		kfree(v2m->bm);
 		iounmap(v2m->base);
-		of_node_put(v2m->node);
+		of_node_put(to_of_node(v2m->fwnode));
 		kfree(v2m);
 	}
 }
@@ -268,7 +268,7 @@ static int gicv2m_allocate_domains(struct irq_domain *parent)
 	if (!v2m)
 		return 0;
 
-	inner_domain = irq_domain_create_tree(of_node_to_fwnode(v2m->node),
+	inner_domain = irq_domain_create_tree(v2m->fwnode,
 					      &gicv2m_domain_ops, v2m);
 	if (!inner_domain) {
 		pr_err("Failed to create GICv2m domain\n");
@@ -277,10 +277,10 @@ static int gicv2m_allocate_domains(struct irq_domain *parent)
 
 	inner_domain->bus_token = DOMAIN_BUS_NEXUS;
 	inner_domain->parent = parent;
-	pci_domain = pci_msi_create_irq_domain(of_node_to_fwnode(v2m->node),
+	pci_domain = pci_msi_create_irq_domain(v2m->fwnode,
 					       &gicv2m_msi_domain_info,
 					       inner_domain);
-	plat_domain = platform_msi_create_irq_domain(of_node_to_fwnode(v2m->node),
+	plat_domain = platform_msi_create_irq_domain(v2m->fwnode,
 						     &gicv2m_pmsi_domain_info,
 						     inner_domain);
 	if (!pci_domain || !plat_domain) {
@@ -296,8 +296,9 @@ static int gicv2m_allocate_domains(struct irq_domain *parent)
 	return 0;
 }
 
-static int __init gicv2m_init_one(struct device_node *node,
-				  struct irq_domain *parent)
+static int __init gicv2m_init_one(struct fwnode_handle *fwnode,
+				  u32 spi_start, u32 nr_spis,
+				  struct resource *res)
 {
 	int ret;
 	struct v2m_data *v2m;
@@ -309,13 +310,9 @@ static int __init gicv2m_init_one(struct device_node *node,
 	}
 
 	INIT_LIST_HEAD(&v2m->entry);
-	v2m->node = node;
+	v2m->fwnode = fwnode;
 
-	ret = of_address_to_resource(node, 0, &v2m->res);
-	if (ret) {
-		pr_err("Failed to allocate v2m resource.\n");
-		goto err_free_v2m;
-	}
+	memcpy(&v2m->res, res, sizeof(struct resource));
 
 	v2m->base = ioremap(v2m->res.start, resource_size(&v2m->res));
 	if (!v2m->base) {
@@ -324,10 +321,9 @@ static int __init gicv2m_init_one(struct device_node *node,
 		goto err_free_v2m;
 	}
 
-	if (!of_property_read_u32(node, "arm,msi-base-spi", &v2m->spi_start) &&
-	    !of_property_read_u32(node, "arm,msi-num-spis", &v2m->nr_spis)) {
-		pr_info("Overriding V2M MSI_TYPER (base:%u, num:%u)\n",
-			v2m->spi_start, v2m->nr_spis);
+	if (spi_start && nr_spis) {
+		v2m->spi_start = spi_start;
+		v2m->nr_spis = nr_spis;
 	} else {
 		u32 typer = readl_relaxed(v2m->base + V2M_MSI_TYPER);
 
@@ -359,10 +355,10 @@ static int __init gicv2m_init_one(struct device_node *node,
 	}
 
 	list_add_tail(&v2m->entry, &v2m_nodes);
-	pr_info("Node %s: range[%#lx:%#lx], SPI[%d:%d]\n", node->name,
-		(unsigned long)v2m->res.start, (unsigned long)v2m->res.end,
-		v2m->spi_start, (v2m->spi_start + v2m->nr_spis));
 
+	pr_info("range[%#lx:%#lx], SPI[%d:%d]\n",
+		(unsigned long)res->start, (unsigned long)res->end,
+		v2m->spi_start, (v2m->spi_start + v2m->nr_spis));
 	return 0;
 
 err_iounmap:
@@ -384,10 +380,25 @@ int __init gicv2m_of_init(struct device_node *node, struct irq_domain *parent)
 
 	for (child = of_find_matching_node(node, gicv2m_device_id); child;
 	     child = of_find_matching_node(child, gicv2m_device_id)) {
+		u32 spi_start = 0, nr_spis = 0;
+		struct resource res;
+
 		if (!of_find_property(child, "msi-controller", NULL))
 			continue;
 
-		ret = gicv2m_init_one(child, parent);
+		ret = of_address_to_resource(child, 0, &res);
+		if (ret) {
+			pr_err("Failed to allocate v2m resource.\n");
+			break;
+		}
+
+		if (!of_property_read_u32(child, "arm,msi-base-spi",
+					  &spi_start) &&
+		    !of_property_read_u32(child, "arm,msi-num-spis", &nr_spis))
+			pr_info("DT overriding V2M MSI_TYPER (base:%u, num:%u)\n",
+				spi_start, nr_spis);
+
+		ret = gicv2m_init_one(&child->fwnode, spi_start, nr_spis, &res);
 		if (ret) {
 			of_node_put(node);
 			break;
-- 
2.1.0

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

* [PATCH v7 3/4] gicv2m: Refactor to prepare for ACPI support
@ 2015-12-10 16:55   ` Suravee Suthikulpanit
  0 siblings, 0 replies; 42+ messages in thread
From: Suravee Suthikulpanit @ 2015-12-10 16:55 UTC (permalink / raw)
  To: marc.zyngier, tglx, jason, rjw, bhelgaas
  Cc: Lorenzo Pieralisi, Will Deacon, Catalin Marinas, hanjun.guo,
	tomasz.nowicki, graeme.gregory, dhdang, linux-arm-kernel,
	linux-kernel, linux-acpi, linux-pci, Suravee Suthikulpanit

This patch replaces the struct device_node with struct fwnode_handle
since this structure is common between DT and ACPI.

It also refactors gicv2m_init_one() to prepare for ACPI support.
The only functional change is removing the node name from pr_info.

Reviewed-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Suravee Suthikulpanit <Suravee.Suthikulpanit@amd.com>
---
 drivers/irqchip/irq-gic-v2m.c | 53 ++++++++++++++++++++++++++-----------------
 1 file changed, 32 insertions(+), 21 deletions(-)

diff --git a/drivers/irqchip/irq-gic-v2m.c b/drivers/irqchip/irq-gic-v2m.c
index 87f8d10..779c390 100644
--- a/drivers/irqchip/irq-gic-v2m.c
+++ b/drivers/irqchip/irq-gic-v2m.c
@@ -55,7 +55,7 @@ static DEFINE_SPINLOCK(v2m_lock);
 
 struct v2m_data {
 	struct list_head entry;
-	struct device_node *node;
+	struct fwnode_handle *fwnode;
 	struct resource res;	/* GICv2m resource */
 	void __iomem *base;	/* GICv2m virt address */
 	u32 spi_start;		/* The SPI number that MSIs start */
@@ -254,7 +254,7 @@ static void gicv2m_teardown(void)
 		list_del(&v2m->entry);
 		kfree(v2m->bm);
 		iounmap(v2m->base);
-		of_node_put(v2m->node);
+		of_node_put(to_of_node(v2m->fwnode));
 		kfree(v2m);
 	}
 }
@@ -268,7 +268,7 @@ static int gicv2m_allocate_domains(struct irq_domain *parent)
 	if (!v2m)
 		return 0;
 
-	inner_domain = irq_domain_create_tree(of_node_to_fwnode(v2m->node),
+	inner_domain = irq_domain_create_tree(v2m->fwnode,
 					      &gicv2m_domain_ops, v2m);
 	if (!inner_domain) {
 		pr_err("Failed to create GICv2m domain\n");
@@ -277,10 +277,10 @@ static int gicv2m_allocate_domains(struct irq_domain *parent)
 
 	inner_domain->bus_token = DOMAIN_BUS_NEXUS;
 	inner_domain->parent = parent;
-	pci_domain = pci_msi_create_irq_domain(of_node_to_fwnode(v2m->node),
+	pci_domain = pci_msi_create_irq_domain(v2m->fwnode,
 					       &gicv2m_msi_domain_info,
 					       inner_domain);
-	plat_domain = platform_msi_create_irq_domain(of_node_to_fwnode(v2m->node),
+	plat_domain = platform_msi_create_irq_domain(v2m->fwnode,
 						     &gicv2m_pmsi_domain_info,
 						     inner_domain);
 	if (!pci_domain || !plat_domain) {
@@ -296,8 +296,9 @@ static int gicv2m_allocate_domains(struct irq_domain *parent)
 	return 0;
 }
 
-static int __init gicv2m_init_one(struct device_node *node,
-				  struct irq_domain *parent)
+static int __init gicv2m_init_one(struct fwnode_handle *fwnode,
+				  u32 spi_start, u32 nr_spis,
+				  struct resource *res)
 {
 	int ret;
 	struct v2m_data *v2m;
@@ -309,13 +310,9 @@ static int __init gicv2m_init_one(struct device_node *node,
 	}
 
 	INIT_LIST_HEAD(&v2m->entry);
-	v2m->node = node;
+	v2m->fwnode = fwnode;
 
-	ret = of_address_to_resource(node, 0, &v2m->res);
-	if (ret) {
-		pr_err("Failed to allocate v2m resource.\n");
-		goto err_free_v2m;
-	}
+	memcpy(&v2m->res, res, sizeof(struct resource));
 
 	v2m->base = ioremap(v2m->res.start, resource_size(&v2m->res));
 	if (!v2m->base) {
@@ -324,10 +321,9 @@ static int __init gicv2m_init_one(struct device_node *node,
 		goto err_free_v2m;
 	}
 
-	if (!of_property_read_u32(node, "arm,msi-base-spi", &v2m->spi_start) &&
-	    !of_property_read_u32(node, "arm,msi-num-spis", &v2m->nr_spis)) {
-		pr_info("Overriding V2M MSI_TYPER (base:%u, num:%u)\n",
-			v2m->spi_start, v2m->nr_spis);
+	if (spi_start && nr_spis) {
+		v2m->spi_start = spi_start;
+		v2m->nr_spis = nr_spis;
 	} else {
 		u32 typer = readl_relaxed(v2m->base + V2M_MSI_TYPER);
 
@@ -359,10 +355,10 @@ static int __init gicv2m_init_one(struct device_node *node,
 	}
 
 	list_add_tail(&v2m->entry, &v2m_nodes);
-	pr_info("Node %s: range[%#lx:%#lx], SPI[%d:%d]\n", node->name,
-		(unsigned long)v2m->res.start, (unsigned long)v2m->res.end,
-		v2m->spi_start, (v2m->spi_start + v2m->nr_spis));
 
+	pr_info("range[%#lx:%#lx], SPI[%d:%d]\n",
+		(unsigned long)res->start, (unsigned long)res->end,
+		v2m->spi_start, (v2m->spi_start + v2m->nr_spis));
 	return 0;
 
 err_iounmap:
@@ -384,10 +380,25 @@ int __init gicv2m_of_init(struct device_node *node, struct irq_domain *parent)
 
 	for (child = of_find_matching_node(node, gicv2m_device_id); child;
 	     child = of_find_matching_node(child, gicv2m_device_id)) {
+		u32 spi_start = 0, nr_spis = 0;
+		struct resource res;
+
 		if (!of_find_property(child, "msi-controller", NULL))
 			continue;
 
-		ret = gicv2m_init_one(child, parent);
+		ret = of_address_to_resource(child, 0, &res);
+		if (ret) {
+			pr_err("Failed to allocate v2m resource.\n");
+			break;
+		}
+
+		if (!of_property_read_u32(child, "arm,msi-base-spi",
+					  &spi_start) &&
+		    !of_property_read_u32(child, "arm,msi-num-spis", &nr_spis))
+			pr_info("DT overriding V2M MSI_TYPER (base:%u, num:%u)\n",
+				spi_start, nr_spis);
+
+		ret = gicv2m_init_one(&child->fwnode, spi_start, nr_spis, &res);
 		if (ret) {
 			of_node_put(node);
 			break;
-- 
2.1.0


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

* [PATCH v7 3/4] gicv2m: Refactor to prepare for ACPI support
@ 2015-12-10 16:55   ` Suravee Suthikulpanit
  0 siblings, 0 replies; 42+ messages in thread
From: Suravee Suthikulpanit @ 2015-12-10 16:55 UTC (permalink / raw)
  To: linux-arm-kernel

This patch replaces the struct device_node with struct fwnode_handle
since this structure is common between DT and ACPI.

It also refactors gicv2m_init_one() to prepare for ACPI support.
The only functional change is removing the node name from pr_info.

Reviewed-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Suravee Suthikulpanit <Suravee.Suthikulpanit@amd.com>
---
 drivers/irqchip/irq-gic-v2m.c | 53 ++++++++++++++++++++++++++-----------------
 1 file changed, 32 insertions(+), 21 deletions(-)

diff --git a/drivers/irqchip/irq-gic-v2m.c b/drivers/irqchip/irq-gic-v2m.c
index 87f8d10..779c390 100644
--- a/drivers/irqchip/irq-gic-v2m.c
+++ b/drivers/irqchip/irq-gic-v2m.c
@@ -55,7 +55,7 @@ static DEFINE_SPINLOCK(v2m_lock);
 
 struct v2m_data {
 	struct list_head entry;
-	struct device_node *node;
+	struct fwnode_handle *fwnode;
 	struct resource res;	/* GICv2m resource */
 	void __iomem *base;	/* GICv2m virt address */
 	u32 spi_start;		/* The SPI number that MSIs start */
@@ -254,7 +254,7 @@ static void gicv2m_teardown(void)
 		list_del(&v2m->entry);
 		kfree(v2m->bm);
 		iounmap(v2m->base);
-		of_node_put(v2m->node);
+		of_node_put(to_of_node(v2m->fwnode));
 		kfree(v2m);
 	}
 }
@@ -268,7 +268,7 @@ static int gicv2m_allocate_domains(struct irq_domain *parent)
 	if (!v2m)
 		return 0;
 
-	inner_domain = irq_domain_create_tree(of_node_to_fwnode(v2m->node),
+	inner_domain = irq_domain_create_tree(v2m->fwnode,
 					      &gicv2m_domain_ops, v2m);
 	if (!inner_domain) {
 		pr_err("Failed to create GICv2m domain\n");
@@ -277,10 +277,10 @@ static int gicv2m_allocate_domains(struct irq_domain *parent)
 
 	inner_domain->bus_token = DOMAIN_BUS_NEXUS;
 	inner_domain->parent = parent;
-	pci_domain = pci_msi_create_irq_domain(of_node_to_fwnode(v2m->node),
+	pci_domain = pci_msi_create_irq_domain(v2m->fwnode,
 					       &gicv2m_msi_domain_info,
 					       inner_domain);
-	plat_domain = platform_msi_create_irq_domain(of_node_to_fwnode(v2m->node),
+	plat_domain = platform_msi_create_irq_domain(v2m->fwnode,
 						     &gicv2m_pmsi_domain_info,
 						     inner_domain);
 	if (!pci_domain || !plat_domain) {
@@ -296,8 +296,9 @@ static int gicv2m_allocate_domains(struct irq_domain *parent)
 	return 0;
 }
 
-static int __init gicv2m_init_one(struct device_node *node,
-				  struct irq_domain *parent)
+static int __init gicv2m_init_one(struct fwnode_handle *fwnode,
+				  u32 spi_start, u32 nr_spis,
+				  struct resource *res)
 {
 	int ret;
 	struct v2m_data *v2m;
@@ -309,13 +310,9 @@ static int __init gicv2m_init_one(struct device_node *node,
 	}
 
 	INIT_LIST_HEAD(&v2m->entry);
-	v2m->node = node;
+	v2m->fwnode = fwnode;
 
-	ret = of_address_to_resource(node, 0, &v2m->res);
-	if (ret) {
-		pr_err("Failed to allocate v2m resource.\n");
-		goto err_free_v2m;
-	}
+	memcpy(&v2m->res, res, sizeof(struct resource));
 
 	v2m->base = ioremap(v2m->res.start, resource_size(&v2m->res));
 	if (!v2m->base) {
@@ -324,10 +321,9 @@ static int __init gicv2m_init_one(struct device_node *node,
 		goto err_free_v2m;
 	}
 
-	if (!of_property_read_u32(node, "arm,msi-base-spi", &v2m->spi_start) &&
-	    !of_property_read_u32(node, "arm,msi-num-spis", &v2m->nr_spis)) {
-		pr_info("Overriding V2M MSI_TYPER (base:%u, num:%u)\n",
-			v2m->spi_start, v2m->nr_spis);
+	if (spi_start && nr_spis) {
+		v2m->spi_start = spi_start;
+		v2m->nr_spis = nr_spis;
 	} else {
 		u32 typer = readl_relaxed(v2m->base + V2M_MSI_TYPER);
 
@@ -359,10 +355,10 @@ static int __init gicv2m_init_one(struct device_node *node,
 	}
 
 	list_add_tail(&v2m->entry, &v2m_nodes);
-	pr_info("Node %s: range[%#lx:%#lx], SPI[%d:%d]\n", node->name,
-		(unsigned long)v2m->res.start, (unsigned long)v2m->res.end,
-		v2m->spi_start, (v2m->spi_start + v2m->nr_spis));
 
+	pr_info("range[%#lx:%#lx], SPI[%d:%d]\n",
+		(unsigned long)res->start, (unsigned long)res->end,
+		v2m->spi_start, (v2m->spi_start + v2m->nr_spis));
 	return 0;
 
 err_iounmap:
@@ -384,10 +380,25 @@ int __init gicv2m_of_init(struct device_node *node, struct irq_domain *parent)
 
 	for (child = of_find_matching_node(node, gicv2m_device_id); child;
 	     child = of_find_matching_node(child, gicv2m_device_id)) {
+		u32 spi_start = 0, nr_spis = 0;
+		struct resource res;
+
 		if (!of_find_property(child, "msi-controller", NULL))
 			continue;
 
-		ret = gicv2m_init_one(child, parent);
+		ret = of_address_to_resource(child, 0, &res);
+		if (ret) {
+			pr_err("Failed to allocate v2m resource.\n");
+			break;
+		}
+
+		if (!of_property_read_u32(child, "arm,msi-base-spi",
+					  &spi_start) &&
+		    !of_property_read_u32(child, "arm,msi-num-spis", &nr_spis))
+			pr_info("DT overriding V2M MSI_TYPER (base:%u, num:%u)\n",
+				spi_start, nr_spis);
+
+		ret = gicv2m_init_one(&child->fwnode, spi_start, nr_spis, &res);
 		if (ret) {
 			of_node_put(node);
 			break;
-- 
2.1.0

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

* [PATCH v7 4/4] gicv2m: acpi: Introducing GICv2m ACPI support
  2015-12-10 16:55 ` Suravee Suthikulpanit
  (?)
@ 2015-12-10 16:55   ` Suravee Suthikulpanit
  -1 siblings, 0 replies; 42+ messages in thread
From: Suravee Suthikulpanit @ 2015-12-10 16:55 UTC (permalink / raw)
  To: marc.zyngier, tglx, jason, rjw, bhelgaas
  Cc: Lorenzo Pieralisi, graeme.gregory, Catalin Marinas, dhdang,
	Will Deacon, linux-kernel, tomasz.nowicki, linux-acpi,
	hanjun.guo, Suravee Suthikulpanit, linux-pci, linux-arm-kernel

This patch introduces gicv2m_acpi_init(), which uses information
in MADT GIC MSI frames structure to initialize GICv2m driver.
It also exposes gicv2m_init() function, which simplifies callers
to a single GICv2m init function.

Reviewed-by: Marc Zyngier <marc.zyngier@arm.com>
Tested-by: Duc Dang <dhdang@apm.com>
Signed-off-by: Suravee Suthikulpanit <Suravee.Suthikulpanit@amd.com>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 drivers/irqchip/irq-gic-v2m.c   | 110 +++++++++++++++++++++++++++++++++++++++-
 drivers/irqchip/irq-gic.c       |   6 ++-
 include/linux/irqchip/arm-gic.h |   3 +-
 3 files changed, 116 insertions(+), 3 deletions(-)

diff --git a/drivers/irqchip/irq-gic-v2m.c b/drivers/irqchip/irq-gic-v2m.c
index 779c390..7e2975d 100644
--- a/drivers/irqchip/irq-gic-v2m.c
+++ b/drivers/irqchip/irq-gic-v2m.c
@@ -15,9 +15,11 @@
 
 #define pr_fmt(fmt) "GICv2m: " fmt
 
+#include <linux/acpi.h>
 #include <linux/irq.h>
 #include <linux/irqdomain.h>
 #include <linux/kernel.h>
+#include <linux/msi.h>
 #include <linux/of_address.h>
 #include <linux/of_pci.h>
 #include <linux/slab.h>
@@ -138,6 +140,11 @@ static int gicv2m_irq_gic_domain_alloc(struct irq_domain *domain,
 		fwspec.param[0] = 0;
 		fwspec.param[1] = hwirq - 32;
 		fwspec.param[2] = IRQ_TYPE_EDGE_RISING;
+	} else if (is_fwnode_irqchip(domain->parent->fwnode)) {
+		fwspec.fwnode = domain->parent->fwnode;
+		fwspec.param_count = 2;
+		fwspec.param[0] = hwirq;
+		fwspec.param[1] = IRQ_TYPE_EDGE_RISING;
 	} else {
 		return -EINVAL;
 	}
@@ -255,6 +262,8 @@ static void gicv2m_teardown(void)
 		kfree(v2m->bm);
 		iounmap(v2m->base);
 		of_node_put(to_of_node(v2m->fwnode));
+		if (is_fwnode_irqchip(v2m->fwnode))
+			irq_domain_free_fwnode(v2m->fwnode);
 		kfree(v2m);
 	}
 }
@@ -373,9 +382,11 @@ static struct of_device_id gicv2m_device_id[] = {
 	{},
 };
 
-int __init gicv2m_of_init(struct device_node *node, struct irq_domain *parent)
+static int __init gicv2m_of_init(struct fwnode_handle *parent_handle,
+				 struct irq_domain *parent)
 {
 	int ret = 0;
+	struct device_node *node = to_of_node(parent_handle);
 	struct device_node *child;
 
 	for (child = of_find_matching_node(node, gicv2m_device_id); child;
@@ -411,3 +422,100 @@ int __init gicv2m_of_init(struct device_node *node, struct irq_domain *parent)
 		gicv2m_teardown();
 	return ret;
 }
+
+#ifdef CONFIG_ACPI
+static int acpi_num_msi;
+
+static struct fwnode_handle *gicv2m_get_fwnode(struct device *dev)
+{
+	struct v2m_data *data;
+
+	if (WARN_ON(acpi_num_msi <= 0))
+		return NULL;
+
+	/* We only return the fwnode of the first MSI frame. */
+	data = list_first_entry_or_null(&v2m_nodes, struct v2m_data, entry);
+	if (!data)
+		return NULL;
+
+	return data->fwnode;
+}
+
+static int __init
+acpi_parse_madt_msi(struct acpi_subtable_header *header,
+		    const unsigned long end)
+{
+	int ret;
+	struct resource res;
+	u32 spi_start = 0, nr_spis = 0;
+	struct acpi_madt_generic_msi_frame *m;
+	struct fwnode_handle *fwnode;
+
+	m = (struct acpi_madt_generic_msi_frame *)header;
+	if (BAD_MADT_ENTRY(m, end))
+		return -EINVAL;
+
+	res.start = m->base_address;
+	res.end = m->base_address + SZ_4K;
+
+	if (m->flags & ACPI_MADT_OVERRIDE_SPI_VALUES) {
+		spi_start = m->spi_base;
+		nr_spis = m->spi_count;
+
+		pr_info("ACPI overriding V2M MSI_TYPER (base:%u, num:%u)\n",
+			spi_start, nr_spis);
+	}
+
+	fwnode = irq_domain_alloc_fwnode((void *)m->base_address);
+	if (!fwnode) {
+		pr_err("Unable to allocate GICv2m domain token\n");
+		return -EINVAL;
+	}
+
+	ret = gicv2m_init_one(fwnode, spi_start, nr_spis, &res);
+	if (ret)
+		irq_domain_free_fwnode(fwnode);
+
+	return ret;
+}
+
+static int __init gicv2m_acpi_init(struct irq_domain *parent)
+{
+	int ret;
+
+	if (acpi_num_msi > 0)
+		return 0;
+
+	acpi_num_msi = acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_MSI_FRAME,
+				      acpi_parse_madt_msi, 0);
+
+	if (acpi_num_msi <= 0)
+		goto err_out;
+
+	ret = gicv2m_allocate_domains(parent);
+	if (ret)
+		goto err_out;
+
+	pci_msi_register_fwnode_provider(&gicv2m_get_fwnode);
+
+	return 0;
+
+err_out:
+	gicv2m_teardown();
+	return -EINVAL;
+}
+#else /* CONFIG_ACPI */
+static int __init gicv2m_acpi_init(struct irq_domain *parent)
+{
+	return -EINVAL;
+}
+#endif /* CONFIG_ACPI */
+
+int __init gicv2m_init(struct fwnode_handle *parent_handle,
+		       struct irq_domain *parent)
+{
+	if (is_of_node(parent_handle))
+		return gicv2m_of_init(parent_handle, parent);
+
+	return gicv2m_acpi_init(parent);
+}
diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
index fcd327f..644e8bb 100644
--- a/drivers/irqchip/irq-gic.c
+++ b/drivers/irqchip/irq-gic.c
@@ -1234,7 +1234,7 @@ gic_of_init(struct device_node *node, struct device_node *parent)
 	}
 
 	if (IS_ENABLED(CONFIG_ARM_GIC_V2M))
-		gicv2m_of_init(node, gic_data[gic_cnt].domain);
+		gicv2m_init(&node->fwnode, gic_data[gic_cnt].domain);
 
 	gic_cnt++;
 	return 0;
@@ -1359,6 +1359,10 @@ static int __init gic_v2_acpi_init(struct acpi_subtable_header *header,
 	__gic_init_bases(0, -1, dist_base, cpu_base, 0, domain_handle);
 
 	acpi_set_irq_model(ACPI_IRQ_MODEL_GIC, domain_handle);
+
+	if (IS_ENABLED(CONFIG_ARM_GIC_V2M))
+		gicv2m_init(NULL, gic_data[0].domain);
+
 	return 0;
 }
 IRQCHIP_ACPI_DECLARE(gic_v2, ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR,
diff --git a/include/linux/irqchip/arm-gic.h b/include/linux/irqchip/arm-gic.h
index bae69e5..febc6c3 100644
--- a/include/linux/irqchip/arm-gic.h
+++ b/include/linux/irqchip/arm-gic.h
@@ -106,7 +106,8 @@ int gic_cpu_if_down(unsigned int gic_nr);
 void gic_init(unsigned int nr, int start,
 	      void __iomem *dist , void __iomem *cpu);
 
-int gicv2m_of_init(struct device_node *node, struct irq_domain *parent);
+int gicv2m_init(struct fwnode_handle *parent_handle,
+		struct irq_domain *parent);
 
 void gic_send_sgi(unsigned int cpu_id, unsigned int irq);
 int gic_get_cpu_id(unsigned int cpu);
-- 
2.1.0

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

* [PATCH v7 4/4] gicv2m: acpi: Introducing GICv2m ACPI support
@ 2015-12-10 16:55   ` Suravee Suthikulpanit
  0 siblings, 0 replies; 42+ messages in thread
From: Suravee Suthikulpanit @ 2015-12-10 16:55 UTC (permalink / raw)
  To: marc.zyngier, tglx, jason, rjw, bhelgaas
  Cc: Lorenzo Pieralisi, Will Deacon, Catalin Marinas, hanjun.guo,
	tomasz.nowicki, graeme.gregory, dhdang, linux-arm-kernel,
	linux-kernel, linux-acpi, linux-pci, Suravee Suthikulpanit

This patch introduces gicv2m_acpi_init(), which uses information
in MADT GIC MSI frames structure to initialize GICv2m driver.
It also exposes gicv2m_init() function, which simplifies callers
to a single GICv2m init function.

Reviewed-by: Marc Zyngier <marc.zyngier@arm.com>
Tested-by: Duc Dang <dhdang@apm.com>
Signed-off-by: Suravee Suthikulpanit <Suravee.Suthikulpanit@amd.com>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 drivers/irqchip/irq-gic-v2m.c   | 110 +++++++++++++++++++++++++++++++++++++++-
 drivers/irqchip/irq-gic.c       |   6 ++-
 include/linux/irqchip/arm-gic.h |   3 +-
 3 files changed, 116 insertions(+), 3 deletions(-)

diff --git a/drivers/irqchip/irq-gic-v2m.c b/drivers/irqchip/irq-gic-v2m.c
index 779c390..7e2975d 100644
--- a/drivers/irqchip/irq-gic-v2m.c
+++ b/drivers/irqchip/irq-gic-v2m.c
@@ -15,9 +15,11 @@
 
 #define pr_fmt(fmt) "GICv2m: " fmt
 
+#include <linux/acpi.h>
 #include <linux/irq.h>
 #include <linux/irqdomain.h>
 #include <linux/kernel.h>
+#include <linux/msi.h>
 #include <linux/of_address.h>
 #include <linux/of_pci.h>
 #include <linux/slab.h>
@@ -138,6 +140,11 @@ static int gicv2m_irq_gic_domain_alloc(struct irq_domain *domain,
 		fwspec.param[0] = 0;
 		fwspec.param[1] = hwirq - 32;
 		fwspec.param[2] = IRQ_TYPE_EDGE_RISING;
+	} else if (is_fwnode_irqchip(domain->parent->fwnode)) {
+		fwspec.fwnode = domain->parent->fwnode;
+		fwspec.param_count = 2;
+		fwspec.param[0] = hwirq;
+		fwspec.param[1] = IRQ_TYPE_EDGE_RISING;
 	} else {
 		return -EINVAL;
 	}
@@ -255,6 +262,8 @@ static void gicv2m_teardown(void)
 		kfree(v2m->bm);
 		iounmap(v2m->base);
 		of_node_put(to_of_node(v2m->fwnode));
+		if (is_fwnode_irqchip(v2m->fwnode))
+			irq_domain_free_fwnode(v2m->fwnode);
 		kfree(v2m);
 	}
 }
@@ -373,9 +382,11 @@ static struct of_device_id gicv2m_device_id[] = {
 	{},
 };
 
-int __init gicv2m_of_init(struct device_node *node, struct irq_domain *parent)
+static int __init gicv2m_of_init(struct fwnode_handle *parent_handle,
+				 struct irq_domain *parent)
 {
 	int ret = 0;
+	struct device_node *node = to_of_node(parent_handle);
 	struct device_node *child;
 
 	for (child = of_find_matching_node(node, gicv2m_device_id); child;
@@ -411,3 +422,100 @@ int __init gicv2m_of_init(struct device_node *node, struct irq_domain *parent)
 		gicv2m_teardown();
 	return ret;
 }
+
+#ifdef CONFIG_ACPI
+static int acpi_num_msi;
+
+static struct fwnode_handle *gicv2m_get_fwnode(struct device *dev)
+{
+	struct v2m_data *data;
+
+	if (WARN_ON(acpi_num_msi <= 0))
+		return NULL;
+
+	/* We only return the fwnode of the first MSI frame. */
+	data = list_first_entry_or_null(&v2m_nodes, struct v2m_data, entry);
+	if (!data)
+		return NULL;
+
+	return data->fwnode;
+}
+
+static int __init
+acpi_parse_madt_msi(struct acpi_subtable_header *header,
+		    const unsigned long end)
+{
+	int ret;
+	struct resource res;
+	u32 spi_start = 0, nr_spis = 0;
+	struct acpi_madt_generic_msi_frame *m;
+	struct fwnode_handle *fwnode;
+
+	m = (struct acpi_madt_generic_msi_frame *)header;
+	if (BAD_MADT_ENTRY(m, end))
+		return -EINVAL;
+
+	res.start = m->base_address;
+	res.end = m->base_address + SZ_4K;
+
+	if (m->flags & ACPI_MADT_OVERRIDE_SPI_VALUES) {
+		spi_start = m->spi_base;
+		nr_spis = m->spi_count;
+
+		pr_info("ACPI overriding V2M MSI_TYPER (base:%u, num:%u)\n",
+			spi_start, nr_spis);
+	}
+
+	fwnode = irq_domain_alloc_fwnode((void *)m->base_address);
+	if (!fwnode) {
+		pr_err("Unable to allocate GICv2m domain token\n");
+		return -EINVAL;
+	}
+
+	ret = gicv2m_init_one(fwnode, spi_start, nr_spis, &res);
+	if (ret)
+		irq_domain_free_fwnode(fwnode);
+
+	return ret;
+}
+
+static int __init gicv2m_acpi_init(struct irq_domain *parent)
+{
+	int ret;
+
+	if (acpi_num_msi > 0)
+		return 0;
+
+	acpi_num_msi = acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_MSI_FRAME,
+				      acpi_parse_madt_msi, 0);
+
+	if (acpi_num_msi <= 0)
+		goto err_out;
+
+	ret = gicv2m_allocate_domains(parent);
+	if (ret)
+		goto err_out;
+
+	pci_msi_register_fwnode_provider(&gicv2m_get_fwnode);
+
+	return 0;
+
+err_out:
+	gicv2m_teardown();
+	return -EINVAL;
+}
+#else /* CONFIG_ACPI */
+static int __init gicv2m_acpi_init(struct irq_domain *parent)
+{
+	return -EINVAL;
+}
+#endif /* CONFIG_ACPI */
+
+int __init gicv2m_init(struct fwnode_handle *parent_handle,
+		       struct irq_domain *parent)
+{
+	if (is_of_node(parent_handle))
+		return gicv2m_of_init(parent_handle, parent);
+
+	return gicv2m_acpi_init(parent);
+}
diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
index fcd327f..644e8bb 100644
--- a/drivers/irqchip/irq-gic.c
+++ b/drivers/irqchip/irq-gic.c
@@ -1234,7 +1234,7 @@ gic_of_init(struct device_node *node, struct device_node *parent)
 	}
 
 	if (IS_ENABLED(CONFIG_ARM_GIC_V2M))
-		gicv2m_of_init(node, gic_data[gic_cnt].domain);
+		gicv2m_init(&node->fwnode, gic_data[gic_cnt].domain);
 
 	gic_cnt++;
 	return 0;
@@ -1359,6 +1359,10 @@ static int __init gic_v2_acpi_init(struct acpi_subtable_header *header,
 	__gic_init_bases(0, -1, dist_base, cpu_base, 0, domain_handle);
 
 	acpi_set_irq_model(ACPI_IRQ_MODEL_GIC, domain_handle);
+
+	if (IS_ENABLED(CONFIG_ARM_GIC_V2M))
+		gicv2m_init(NULL, gic_data[0].domain);
+
 	return 0;
 }
 IRQCHIP_ACPI_DECLARE(gic_v2, ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR,
diff --git a/include/linux/irqchip/arm-gic.h b/include/linux/irqchip/arm-gic.h
index bae69e5..febc6c3 100644
--- a/include/linux/irqchip/arm-gic.h
+++ b/include/linux/irqchip/arm-gic.h
@@ -106,7 +106,8 @@ int gic_cpu_if_down(unsigned int gic_nr);
 void gic_init(unsigned int nr, int start,
 	      void __iomem *dist , void __iomem *cpu);
 
-int gicv2m_of_init(struct device_node *node, struct irq_domain *parent);
+int gicv2m_init(struct fwnode_handle *parent_handle,
+		struct irq_domain *parent);
 
 void gic_send_sgi(unsigned int cpu_id, unsigned int irq);
 int gic_get_cpu_id(unsigned int cpu);
-- 
2.1.0


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

* [PATCH v7 4/4] gicv2m: acpi: Introducing GICv2m ACPI support
@ 2015-12-10 16:55   ` Suravee Suthikulpanit
  0 siblings, 0 replies; 42+ messages in thread
From: Suravee Suthikulpanit @ 2015-12-10 16:55 UTC (permalink / raw)
  To: linux-arm-kernel

This patch introduces gicv2m_acpi_init(), which uses information
in MADT GIC MSI frames structure to initialize GICv2m driver.
It also exposes gicv2m_init() function, which simplifies callers
to a single GICv2m init function.

Reviewed-by: Marc Zyngier <marc.zyngier@arm.com>
Tested-by: Duc Dang <dhdang@apm.com>
Signed-off-by: Suravee Suthikulpanit <Suravee.Suthikulpanit@amd.com>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 drivers/irqchip/irq-gic-v2m.c   | 110 +++++++++++++++++++++++++++++++++++++++-
 drivers/irqchip/irq-gic.c       |   6 ++-
 include/linux/irqchip/arm-gic.h |   3 +-
 3 files changed, 116 insertions(+), 3 deletions(-)

diff --git a/drivers/irqchip/irq-gic-v2m.c b/drivers/irqchip/irq-gic-v2m.c
index 779c390..7e2975d 100644
--- a/drivers/irqchip/irq-gic-v2m.c
+++ b/drivers/irqchip/irq-gic-v2m.c
@@ -15,9 +15,11 @@
 
 #define pr_fmt(fmt) "GICv2m: " fmt
 
+#include <linux/acpi.h>
 #include <linux/irq.h>
 #include <linux/irqdomain.h>
 #include <linux/kernel.h>
+#include <linux/msi.h>
 #include <linux/of_address.h>
 #include <linux/of_pci.h>
 #include <linux/slab.h>
@@ -138,6 +140,11 @@ static int gicv2m_irq_gic_domain_alloc(struct irq_domain *domain,
 		fwspec.param[0] = 0;
 		fwspec.param[1] = hwirq - 32;
 		fwspec.param[2] = IRQ_TYPE_EDGE_RISING;
+	} else if (is_fwnode_irqchip(domain->parent->fwnode)) {
+		fwspec.fwnode = domain->parent->fwnode;
+		fwspec.param_count = 2;
+		fwspec.param[0] = hwirq;
+		fwspec.param[1] = IRQ_TYPE_EDGE_RISING;
 	} else {
 		return -EINVAL;
 	}
@@ -255,6 +262,8 @@ static void gicv2m_teardown(void)
 		kfree(v2m->bm);
 		iounmap(v2m->base);
 		of_node_put(to_of_node(v2m->fwnode));
+		if (is_fwnode_irqchip(v2m->fwnode))
+			irq_domain_free_fwnode(v2m->fwnode);
 		kfree(v2m);
 	}
 }
@@ -373,9 +382,11 @@ static struct of_device_id gicv2m_device_id[] = {
 	{},
 };
 
-int __init gicv2m_of_init(struct device_node *node, struct irq_domain *parent)
+static int __init gicv2m_of_init(struct fwnode_handle *parent_handle,
+				 struct irq_domain *parent)
 {
 	int ret = 0;
+	struct device_node *node = to_of_node(parent_handle);
 	struct device_node *child;
 
 	for (child = of_find_matching_node(node, gicv2m_device_id); child;
@@ -411,3 +422,100 @@ int __init gicv2m_of_init(struct device_node *node, struct irq_domain *parent)
 		gicv2m_teardown();
 	return ret;
 }
+
+#ifdef CONFIG_ACPI
+static int acpi_num_msi;
+
+static struct fwnode_handle *gicv2m_get_fwnode(struct device *dev)
+{
+	struct v2m_data *data;
+
+	if (WARN_ON(acpi_num_msi <= 0))
+		return NULL;
+
+	/* We only return the fwnode of the first MSI frame. */
+	data = list_first_entry_or_null(&v2m_nodes, struct v2m_data, entry);
+	if (!data)
+		return NULL;
+
+	return data->fwnode;
+}
+
+static int __init
+acpi_parse_madt_msi(struct acpi_subtable_header *header,
+		    const unsigned long end)
+{
+	int ret;
+	struct resource res;
+	u32 spi_start = 0, nr_spis = 0;
+	struct acpi_madt_generic_msi_frame *m;
+	struct fwnode_handle *fwnode;
+
+	m = (struct acpi_madt_generic_msi_frame *)header;
+	if (BAD_MADT_ENTRY(m, end))
+		return -EINVAL;
+
+	res.start = m->base_address;
+	res.end = m->base_address + SZ_4K;
+
+	if (m->flags & ACPI_MADT_OVERRIDE_SPI_VALUES) {
+		spi_start = m->spi_base;
+		nr_spis = m->spi_count;
+
+		pr_info("ACPI overriding V2M MSI_TYPER (base:%u, num:%u)\n",
+			spi_start, nr_spis);
+	}
+
+	fwnode = irq_domain_alloc_fwnode((void *)m->base_address);
+	if (!fwnode) {
+		pr_err("Unable to allocate GICv2m domain token\n");
+		return -EINVAL;
+	}
+
+	ret = gicv2m_init_one(fwnode, spi_start, nr_spis, &res);
+	if (ret)
+		irq_domain_free_fwnode(fwnode);
+
+	return ret;
+}
+
+static int __init gicv2m_acpi_init(struct irq_domain *parent)
+{
+	int ret;
+
+	if (acpi_num_msi > 0)
+		return 0;
+
+	acpi_num_msi = acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_MSI_FRAME,
+				      acpi_parse_madt_msi, 0);
+
+	if (acpi_num_msi <= 0)
+		goto err_out;
+
+	ret = gicv2m_allocate_domains(parent);
+	if (ret)
+		goto err_out;
+
+	pci_msi_register_fwnode_provider(&gicv2m_get_fwnode);
+
+	return 0;
+
+err_out:
+	gicv2m_teardown();
+	return -EINVAL;
+}
+#else /* CONFIG_ACPI */
+static int __init gicv2m_acpi_init(struct irq_domain *parent)
+{
+	return -EINVAL;
+}
+#endif /* CONFIG_ACPI */
+
+int __init gicv2m_init(struct fwnode_handle *parent_handle,
+		       struct irq_domain *parent)
+{
+	if (is_of_node(parent_handle))
+		return gicv2m_of_init(parent_handle, parent);
+
+	return gicv2m_acpi_init(parent);
+}
diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
index fcd327f..644e8bb 100644
--- a/drivers/irqchip/irq-gic.c
+++ b/drivers/irqchip/irq-gic.c
@@ -1234,7 +1234,7 @@ gic_of_init(struct device_node *node, struct device_node *parent)
 	}
 
 	if (IS_ENABLED(CONFIG_ARM_GIC_V2M))
-		gicv2m_of_init(node, gic_data[gic_cnt].domain);
+		gicv2m_init(&node->fwnode, gic_data[gic_cnt].domain);
 
 	gic_cnt++;
 	return 0;
@@ -1359,6 +1359,10 @@ static int __init gic_v2_acpi_init(struct acpi_subtable_header *header,
 	__gic_init_bases(0, -1, dist_base, cpu_base, 0, domain_handle);
 
 	acpi_set_irq_model(ACPI_IRQ_MODEL_GIC, domain_handle);
+
+	if (IS_ENABLED(CONFIG_ARM_GIC_V2M))
+		gicv2m_init(NULL, gic_data[0].domain);
+
 	return 0;
 }
 IRQCHIP_ACPI_DECLARE(gic_v2, ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR,
diff --git a/include/linux/irqchip/arm-gic.h b/include/linux/irqchip/arm-gic.h
index bae69e5..febc6c3 100644
--- a/include/linux/irqchip/arm-gic.h
+++ b/include/linux/irqchip/arm-gic.h
@@ -106,7 +106,8 @@ int gic_cpu_if_down(unsigned int gic_nr);
 void gic_init(unsigned int nr, int start,
 	      void __iomem *dist , void __iomem *cpu);
 
-int gicv2m_of_init(struct device_node *node, struct irq_domain *parent);
+int gicv2m_init(struct fwnode_handle *parent_handle,
+		struct irq_domain *parent);
 
 void gic_send_sgi(unsigned int cpu_id, unsigned int irq);
 int gic_get_cpu_id(unsigned int cpu);
-- 
2.1.0

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

* Re: [PATCH v7 0/4] gicv2m: acpi: Add ACPI support for GICv2m MSI
  2015-12-10 16:55 ` Suravee Suthikulpanit
@ 2015-12-10 17:28   ` Hanjun Guo
  -1 siblings, 0 replies; 42+ messages in thread
From: Hanjun Guo @ 2015-12-10 17:28 UTC (permalink / raw)
  To: Suravee Suthikulpanit, marc.zyngier, tglx, jason, rjw, bhelgaas
  Cc: Lorenzo Pieralisi, Will Deacon, Catalin Marinas, tomasz.nowicki,
	graeme.gregory, dhdang, linux-arm-kernel, linux-kernel,
	linux-acpi, linux-pci

On 12/11/2015 12:55 AM, Suravee Suthikulpanit wrote:
> This patch series has been forked from the following patch series since
> it no longer depends on the rest of the patches.
>
>    [PATCH v4 00/10] ACPI GIC Self-probing, GICv2m and GICv3 support
>    https://lkml.org/lkml/2015/7/29/234
>
> It has been ported to use the newly introduced device fwnode_handle
> for ACPI irqdmain introduced by Marc in the following patch series:
>
>    [PATCH v2 00/17] Divorcing irqdomain and device_node
>
> The following git branch contains the submitted patches along with
> the pre-requsite patches (mainly for ARM64 PCI support for ACPI).
>
>    https://github.com/ssuthiku/linux.git	v2m-multiframe-v7
>
> This has been tested on AMD Seattle (Overdrive) RevB system.
>
> NOTE: I have not tested ACPI GICv2m multiframe support since
> I don't have access to such system. Any helps are appreciated.
>
> Thanks,
> Suravee
>
> Changes from V6: (https://lkml.org/lkml/2015/12/9/660)
>    - Minor logic change recommended by Marc
>    - Added Reviewed-by Marc for patch 4
>    - Added Tested-by Duc for patch 4
>
> Changes from V5: (https://lkml.org/lkml/2015/12/08/763)
>    - Remove previous patch 3
>    - Clean up based on Marc's review (patch 1.4)
>    - Add Ackedb-by and Reviewed-by (Patch 1,2,3)
>    - Expose single gicv2m_init() function for both OF and ACPI
>      (per Marc's suggestion)
>    - Remove gicv2m name from pr_info since this is no longer useful
>      (in patch 3) (per Marc's suggestion)
>
> Changes from V4: (https://lkml.org/lkml/2015/12/08/613)
>    - Fix build error when not specifying CONFIG_IRQ_DOMAIN.
>
> Changes from V3: (https://lkml.org/lkml/2015/10/21/691)
>    - Merged patch 2 into 1, and got rid off pci_msi_get_fwnode()
>      since only ACPI will likely use this. (per Marc suggestion)
>    - Rebased to 4.4.0-rc4
>
> Changes from V2: (https://lkml.org/lkml/2015/10/14/1010)
>    - Minor clean up from Tomasz review comment in patch 6/6.
>
> Changes from V1: (https://lkml.org/lkml/2015/10/13/859)
>    - Rebase on top of Marc's patch to addng support for multiple MSI frames
>      (https://lkml.org/lkml/2015/10/14/271)
>    - Adding fwnode convenient functions (patch 3 and 4)
>
> Suravee Suthikulpanit (4):
>    acpi: pci: Setup MSI domain for ACPI based pci devices
>    irqdomain: introduce is_fwnode_irqchip helper
>    gicv2m: Refactor to prepare for ACPI support
>    gicv2m: acpi: Introducing GICv2m ACPI support
>
>   drivers/irqchip/irq-gic-v2m.c   | 163 ++++++++++++++++++++++++++++++++++------
>   drivers/irqchip/irq-gic.c       |   8 +-
>   drivers/pci/pci-acpi.c          |  42 +++++++++++
>   drivers/pci/probe.c             |   2 +
>   include/linux/irqchip/arm-gic.h |   3 +-
>   include/linux/irqdomain.h       |  10 +++
>   include/linux/pci.h             |  10 +++
>   kernel/irq/irqdomain.c          |   2 +-
>   8 files changed, 214 insertions(+), 26 deletions(-)

You are moving very fast :), for this patch set,

Reviewed-by: Hanjun Guo <hanjun.guo@linaro.org>

Thanks
Hanjun

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

* [PATCH v7 0/4] gicv2m: acpi: Add ACPI support for GICv2m MSI
@ 2015-12-10 17:28   ` Hanjun Guo
  0 siblings, 0 replies; 42+ messages in thread
From: Hanjun Guo @ 2015-12-10 17:28 UTC (permalink / raw)
  To: linux-arm-kernel

On 12/11/2015 12:55 AM, Suravee Suthikulpanit wrote:
> This patch series has been forked from the following patch series since
> it no longer depends on the rest of the patches.
>
>    [PATCH v4 00/10] ACPI GIC Self-probing, GICv2m and GICv3 support
>    https://lkml.org/lkml/2015/7/29/234
>
> It has been ported to use the newly introduced device fwnode_handle
> for ACPI irqdmain introduced by Marc in the following patch series:
>
>    [PATCH v2 00/17] Divorcing irqdomain and device_node
>
> The following git branch contains the submitted patches along with
> the pre-requsite patches (mainly for ARM64 PCI support for ACPI).
>
>    https://github.com/ssuthiku/linux.git	v2m-multiframe-v7
>
> This has been tested on AMD Seattle (Overdrive) RevB system.
>
> NOTE: I have not tested ACPI GICv2m multiframe support since
> I don't have access to such system. Any helps are appreciated.
>
> Thanks,
> Suravee
>
> Changes from V6: (https://lkml.org/lkml/2015/12/9/660)
>    - Minor logic change recommended by Marc
>    - Added Reviewed-by Marc for patch 4
>    - Added Tested-by Duc for patch 4
>
> Changes from V5: (https://lkml.org/lkml/2015/12/08/763)
>    - Remove previous patch 3
>    - Clean up based on Marc's review (patch 1.4)
>    - Add Ackedb-by and Reviewed-by (Patch 1,2,3)
>    - Expose single gicv2m_init() function for both OF and ACPI
>      (per Marc's suggestion)
>    - Remove gicv2m name from pr_info since this is no longer useful
>      (in patch 3) (per Marc's suggestion)
>
> Changes from V4: (https://lkml.org/lkml/2015/12/08/613)
>    - Fix build error when not specifying CONFIG_IRQ_DOMAIN.
>
> Changes from V3: (https://lkml.org/lkml/2015/10/21/691)
>    - Merged patch 2 into 1, and got rid off pci_msi_get_fwnode()
>      since only ACPI will likely use this. (per Marc suggestion)
>    - Rebased to 4.4.0-rc4
>
> Changes from V2: (https://lkml.org/lkml/2015/10/14/1010)
>    - Minor clean up from Tomasz review comment in patch 6/6.
>
> Changes from V1: (https://lkml.org/lkml/2015/10/13/859)
>    - Rebase on top of Marc's patch to addng support for multiple MSI frames
>      (https://lkml.org/lkml/2015/10/14/271)
>    - Adding fwnode convenient functions (patch 3 and 4)
>
> Suravee Suthikulpanit (4):
>    acpi: pci: Setup MSI domain for ACPI based pci devices
>    irqdomain: introduce is_fwnode_irqchip helper
>    gicv2m: Refactor to prepare for ACPI support
>    gicv2m: acpi: Introducing GICv2m ACPI support
>
>   drivers/irqchip/irq-gic-v2m.c   | 163 ++++++++++++++++++++++++++++++++++------
>   drivers/irqchip/irq-gic.c       |   8 +-
>   drivers/pci/pci-acpi.c          |  42 +++++++++++
>   drivers/pci/probe.c             |   2 +
>   include/linux/irqchip/arm-gic.h |   3 +-
>   include/linux/irqdomain.h       |  10 +++
>   include/linux/pci.h             |  10 +++
>   kernel/irq/irqdomain.c          |   2 +-
>   8 files changed, 214 insertions(+), 26 deletions(-)

You are moving very fast :), for this patch set,

Reviewed-by: Hanjun Guo <hanjun.guo@linaro.org>

Thanks
Hanjun

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

* Re: [PATCH v7 1/4] acpi: pci: Setup MSI domain for ACPI based pci devices
  2015-12-10 16:55   ` Suravee Suthikulpanit
@ 2015-12-14 15:13     ` Marc Zyngier
  -1 siblings, 0 replies; 42+ messages in thread
From: Marc Zyngier @ 2015-12-14 15:13 UTC (permalink / raw)
  To: Suravee Suthikulpanit, tglx, jason, rjw, bhelgaas
  Cc: Lorenzo Pieralisi, Will Deacon, Catalin Marinas, hanjun.guo,
	tomasz.nowicki, graeme.gregory, dhdang, linux-arm-kernel,
	linux-kernel, linux-acpi, linux-pci

On 10/12/15 16:55, Suravee Suthikulpanit wrote:
> This patch introduces pci_msi_register_fwnode_provider() for irqchip
> to register a callback, to provide a way to determine appropriate MSI
> domain for a pci device.
> 
> It also introduces pci_host_bridge_acpi_msi_domain(), which returns
> the MSI domain of the specified PCI host bridge with DOMAIN_BUS_PCI_MSI
> bus token. Then, it is assigned to pci device.
> 
> Reviewed-by: Marc Zyngier <marc.zyngier@arm.com>
> Cc: Bjorn Helgaas <bhelgaas@google.com>
> Cc: Rafael J. Wysocki <rjw@rjwysocki.net>
> Signed-off-by: Suravee Suthikulpanit <Suravee.Suthikulpanit@amd.com>

Bjorn, Rafael,

Do you have any comment on this?

I was hoping to queue this work (and the 3 patches that depend on it)
for 4.5, but if you don't have the bandwidth to review it, I'll postpone
it to the following merge window.

Thanks,

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

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

* [PATCH v7 1/4] acpi: pci: Setup MSI domain for ACPI based pci devices
@ 2015-12-14 15:13     ` Marc Zyngier
  0 siblings, 0 replies; 42+ messages in thread
From: Marc Zyngier @ 2015-12-14 15:13 UTC (permalink / raw)
  To: linux-arm-kernel

On 10/12/15 16:55, Suravee Suthikulpanit wrote:
> This patch introduces pci_msi_register_fwnode_provider() for irqchip
> to register a callback, to provide a way to determine appropriate MSI
> domain for a pci device.
> 
> It also introduces pci_host_bridge_acpi_msi_domain(), which returns
> the MSI domain of the specified PCI host bridge with DOMAIN_BUS_PCI_MSI
> bus token. Then, it is assigned to pci device.
> 
> Reviewed-by: Marc Zyngier <marc.zyngier@arm.com>
> Cc: Bjorn Helgaas <bhelgaas@google.com>
> Cc: Rafael J. Wysocki <rjw@rjwysocki.net>
> Signed-off-by: Suravee Suthikulpanit <Suravee.Suthikulpanit@amd.com>

Bjorn, Rafael,

Do you have any comment on this?

I was hoping to queue this work (and the 3 patches that depend on it)
for 4.5, but if you don't have the bandwidth to review it, I'll postpone
it to the following merge window.

Thanks,

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

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

* Re: [PATCH v7 1/4] acpi: pci: Setup MSI domain for ACPI based pci devices
  2015-12-14 15:13     ` Marc Zyngier
@ 2015-12-14 21:29       ` Rafael J. Wysocki
  -1 siblings, 0 replies; 42+ messages in thread
From: Rafael J. Wysocki @ 2015-12-14 21:29 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: Suravee Suthikulpanit, tglx, jason, bhelgaas, Lorenzo Pieralisi,
	Will Deacon, Catalin Marinas, hanjun.guo, tomasz.nowicki,
	graeme.gregory, dhdang, linux-arm-kernel, linux-kernel,
	linux-acpi, linux-pci

On Monday, December 14, 2015 03:13:48 PM Marc Zyngier wrote:
> On 10/12/15 16:55, Suravee Suthikulpanit wrote:
> > This patch introduces pci_msi_register_fwnode_provider() for irqchip
> > to register a callback, to provide a way to determine appropriate MSI
> > domain for a pci device.
> > 
> > It also introduces pci_host_bridge_acpi_msi_domain(), which returns
> > the MSI domain of the specified PCI host bridge with DOMAIN_BUS_PCI_MSI
> > bus token. Then, it is assigned to pci device.
> > 
> > Reviewed-by: Marc Zyngier <marc.zyngier@arm.com>
> > Cc: Bjorn Helgaas <bhelgaas@google.com>
> > Cc: Rafael J. Wysocki <rjw@rjwysocki.net>
> > Signed-off-by: Suravee Suthikulpanit <Suravee.Suthikulpanit@amd.com>
> 
> Bjorn, Rafael,
> 
> Do you have any comment on this?
> 
> I was hoping to queue this work (and the 3 patches that depend on it)
> for 4.5, but if you don't have the bandwidth to review it, I'll postpone
> it to the following merge window.

How much time do we have to look at it before it is postponed?

Thanks,
Rafael

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

* [PATCH v7 1/4] acpi: pci: Setup MSI domain for ACPI based pci devices
@ 2015-12-14 21:29       ` Rafael J. Wysocki
  0 siblings, 0 replies; 42+ messages in thread
From: Rafael J. Wysocki @ 2015-12-14 21:29 UTC (permalink / raw)
  To: linux-arm-kernel

On Monday, December 14, 2015 03:13:48 PM Marc Zyngier wrote:
> On 10/12/15 16:55, Suravee Suthikulpanit wrote:
> > This patch introduces pci_msi_register_fwnode_provider() for irqchip
> > to register a callback, to provide a way to determine appropriate MSI
> > domain for a pci device.
> > 
> > It also introduces pci_host_bridge_acpi_msi_domain(), which returns
> > the MSI domain of the specified PCI host bridge with DOMAIN_BUS_PCI_MSI
> > bus token. Then, it is assigned to pci device.
> > 
> > Reviewed-by: Marc Zyngier <marc.zyngier@arm.com>
> > Cc: Bjorn Helgaas <bhelgaas@google.com>
> > Cc: Rafael J. Wysocki <rjw@rjwysocki.net>
> > Signed-off-by: Suravee Suthikulpanit <Suravee.Suthikulpanit@amd.com>
> 
> Bjorn, Rafael,
> 
> Do you have any comment on this?
> 
> I was hoping to queue this work (and the 3 patches that depend on it)
> for 4.5, but if you don't have the bandwidth to review it, I'll postpone
> it to the following merge window.

How much time do we have to look at it before it is postponed?

Thanks,
Rafael

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

* Re: [PATCH v7 1/4] acpi: pci: Setup MSI domain for ACPI based pci devices
  2015-12-14 21:29       ` Rafael J. Wysocki
@ 2015-12-15  9:52         ` Marc Zyngier
  -1 siblings, 0 replies; 42+ messages in thread
From: Marc Zyngier @ 2015-12-15  9:52 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Suravee Suthikulpanit, tglx, jason, bhelgaas, Lorenzo Pieralisi,
	Will Deacon, Catalin Marinas, hanjun.guo, tomasz.nowicki,
	graeme.gregory, dhdang, linux-arm-kernel, linux-kernel,
	linux-acpi, linux-pci

On 14/12/15 21:29, Rafael J. Wysocki wrote:
> On Monday, December 14, 2015 03:13:48 PM Marc Zyngier wrote:
>> On 10/12/15 16:55, Suravee Suthikulpanit wrote:
>>> This patch introduces pci_msi_register_fwnode_provider() for irqchip
>>> to register a callback, to provide a way to determine appropriate MSI
>>> domain for a pci device.
>>>
>>> It also introduces pci_host_bridge_acpi_msi_domain(), which returns
>>> the MSI domain of the specified PCI host bridge with DOMAIN_BUS_PCI_MSI
>>> bus token. Then, it is assigned to pci device.
>>>
>>> Reviewed-by: Marc Zyngier <marc.zyngier@arm.com>
>>> Cc: Bjorn Helgaas <bhelgaas@google.com>
>>> Cc: Rafael J. Wysocki <rjw@rjwysocki.net>
>>> Signed-off-by: Suravee Suthikulpanit <Suravee.Suthikulpanit@amd.com>
>>
>> Bjorn, Rafael,
>>
>> Do you have any comment on this?
>>
>> I was hoping to queue this work (and the 3 patches that depend on it)
>> for 4.5, but if you don't have the bandwidth to review it, I'll postpone
>> it to the following merge window.
> 
> How much time do we have to look at it before it is postponed?

Realistically, I'm going to stop queuing stuff Wednesday next week (I'll
be travelling, and without access to enough HW to follow up on potential
regressions), and I'd expect Thomas to stop pulling stuff even earlier
than that.

So we basically have a week to decide whether or not we want this for
the next merge window. I appreciate this is a busy time for everyone and
that this series took a long time to reach that stage, so any way is
fine by me.

Thanks,

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

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

* [PATCH v7 1/4] acpi: pci: Setup MSI domain for ACPI based pci devices
@ 2015-12-15  9:52         ` Marc Zyngier
  0 siblings, 0 replies; 42+ messages in thread
From: Marc Zyngier @ 2015-12-15  9:52 UTC (permalink / raw)
  To: linux-arm-kernel

On 14/12/15 21:29, Rafael J. Wysocki wrote:
> On Monday, December 14, 2015 03:13:48 PM Marc Zyngier wrote:
>> On 10/12/15 16:55, Suravee Suthikulpanit wrote:
>>> This patch introduces pci_msi_register_fwnode_provider() for irqchip
>>> to register a callback, to provide a way to determine appropriate MSI
>>> domain for a pci device.
>>>
>>> It also introduces pci_host_bridge_acpi_msi_domain(), which returns
>>> the MSI domain of the specified PCI host bridge with DOMAIN_BUS_PCI_MSI
>>> bus token. Then, it is assigned to pci device.
>>>
>>> Reviewed-by: Marc Zyngier <marc.zyngier@arm.com>
>>> Cc: Bjorn Helgaas <bhelgaas@google.com>
>>> Cc: Rafael J. Wysocki <rjw@rjwysocki.net>
>>> Signed-off-by: Suravee Suthikulpanit <Suravee.Suthikulpanit@amd.com>
>>
>> Bjorn, Rafael,
>>
>> Do you have any comment on this?
>>
>> I was hoping to queue this work (and the 3 patches that depend on it)
>> for 4.5, but if you don't have the bandwidth to review it, I'll postpone
>> it to the following merge window.
> 
> How much time do we have to look at it before it is postponed?

Realistically, I'm going to stop queuing stuff Wednesday next week (I'll
be travelling, and without access to enough HW to follow up on potential
regressions), and I'd expect Thomas to stop pulling stuff even earlier
than that.

So we basically have a week to decide whether or not we want this for
the next merge window. I appreciate this is a busy time for everyone and
that this series took a long time to reach that stage, so any way is
fine by me.

Thanks,

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

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

* Re: [PATCH v7 3/4] gicv2m: Refactor to prepare for ACPI support
  2015-12-10 16:55   ` Suravee Suthikulpanit
@ 2015-12-16 22:12     ` Bjorn Helgaas
  -1 siblings, 0 replies; 42+ messages in thread
From: Bjorn Helgaas @ 2015-12-16 22:12 UTC (permalink / raw)
  To: Suravee Suthikulpanit
  Cc: marc.zyngier, tglx, jason, rjw, bhelgaas, Lorenzo Pieralisi,
	Will Deacon, Catalin Marinas, hanjun.guo, tomasz.nowicki,
	graeme.gregory, dhdang, linux-arm-kernel, linux-kernel,
	linux-acpi, linux-pci

On Thu, Dec 10, 2015 at 08:55:29AM -0800, Suravee Suthikulpanit wrote:
> This patch replaces the struct device_node with struct fwnode_handle
> since this structure is common between DT and ACPI.
> 
> It also refactors gicv2m_init_one() to prepare for ACPI support.
> The only functional change is removing the node name from pr_info.
> 
> Reviewed-by: Marc Zyngier <marc.zyngier@arm.com>
> Signed-off-by: Suravee Suthikulpanit <Suravee.Suthikulpanit@amd.com>

> @@ -359,10 +355,10 @@ static int __init gicv2m_init_one(struct device_node *node,
>  	}
>  
>  	list_add_tail(&v2m->entry, &v2m_nodes);
> -	pr_info("Node %s: range[%#lx:%#lx], SPI[%d:%d]\n", node->name,
> -		(unsigned long)v2m->res.start, (unsigned long)v2m->res.end,
> -		v2m->spi_start, (v2m->spi_start + v2m->nr_spis));
>  
> +	pr_info("range[%#lx:%#lx], SPI[%d:%d]\n",
> +		(unsigned long)res->start, (unsigned long)res->end,
> +		v2m->spi_start, (v2m->spi_start + v2m->nr_spis));

You didn't change this, but I don't think this message has enough
context.  It's pretty cryptic all by itself.  It'd be nice if it could
at least include a device name, e.g., if you could use dev_info().

If that's possible, I guess a separate patch would be appropriate,
since there are other similar things in this file.

Bjorn

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

* [PATCH v7 3/4] gicv2m: Refactor to prepare for ACPI support
@ 2015-12-16 22:12     ` Bjorn Helgaas
  0 siblings, 0 replies; 42+ messages in thread
From: Bjorn Helgaas @ 2015-12-16 22:12 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Dec 10, 2015 at 08:55:29AM -0800, Suravee Suthikulpanit wrote:
> This patch replaces the struct device_node with struct fwnode_handle
> since this structure is common between DT and ACPI.
> 
> It also refactors gicv2m_init_one() to prepare for ACPI support.
> The only functional change is removing the node name from pr_info.
> 
> Reviewed-by: Marc Zyngier <marc.zyngier@arm.com>
> Signed-off-by: Suravee Suthikulpanit <Suravee.Suthikulpanit@amd.com>

> @@ -359,10 +355,10 @@ static int __init gicv2m_init_one(struct device_node *node,
>  	}
>  
>  	list_add_tail(&v2m->entry, &v2m_nodes);
> -	pr_info("Node %s: range[%#lx:%#lx], SPI[%d:%d]\n", node->name,
> -		(unsigned long)v2m->res.start, (unsigned long)v2m->res.end,
> -		v2m->spi_start, (v2m->spi_start + v2m->nr_spis));
>  
> +	pr_info("range[%#lx:%#lx], SPI[%d:%d]\n",
> +		(unsigned long)res->start, (unsigned long)res->end,
> +		v2m->spi_start, (v2m->spi_start + v2m->nr_spis));

You didn't change this, but I don't think this message has enough
context.  It's pretty cryptic all by itself.  It'd be nice if it could
at least include a device name, e.g., if you could use dev_info().

If that's possible, I guess a separate patch would be appropriate,
since there are other similar things in this file.

Bjorn

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

* Re: [PATCH v7 1/4] acpi: pci: Setup MSI domain for ACPI based pci devices
  2015-12-10 16:55   ` Suravee Suthikulpanit
@ 2015-12-16 22:15     ` Bjorn Helgaas
  -1 siblings, 0 replies; 42+ messages in thread
From: Bjorn Helgaas @ 2015-12-16 22:15 UTC (permalink / raw)
  To: Suravee Suthikulpanit
  Cc: marc.zyngier, tglx, jason, rjw, bhelgaas, Lorenzo Pieralisi,
	Will Deacon, Catalin Marinas, hanjun.guo, tomasz.nowicki,
	graeme.gregory, dhdang, linux-arm-kernel, linux-kernel,
	linux-acpi, linux-pci

On Thu, Dec 10, 2015 at 08:55:27AM -0800, Suravee Suthikulpanit wrote:
> This patch introduces pci_msi_register_fwnode_provider() for irqchip
> to register a callback, to provide a way to determine appropriate MSI
> domain for a pci device.
> 
> It also introduces pci_host_bridge_acpi_msi_domain(), which returns
> the MSI domain of the specified PCI host bridge with DOMAIN_BUS_PCI_MSI
> bus token. Then, it is assigned to pci device.
> 
> Reviewed-by: Marc Zyngier <marc.zyngier@arm.com>
> Cc: Bjorn Helgaas <bhelgaas@google.com>
> Cc: Rafael J. Wysocki <rjw@rjwysocki.net>
> Signed-off-by: Suravee Suthikulpanit <Suravee.Suthikulpanit@amd.com>

Acked-by: Bjorn Helgaas <bhelgaas@google.com>

I assume the whole series will be queued via a non-PCI tree.

> ---
>  drivers/pci/pci-acpi.c    | 42 ++++++++++++++++++++++++++++++++++++++++++
>  drivers/pci/probe.c       |  2 ++
>  include/linux/irqdomain.h |  5 +++++
>  include/linux/pci.h       | 10 ++++++++++
>  4 files changed, 59 insertions(+)
> 
> diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
> index a32ba75..d3f32d6 100644
> --- a/drivers/pci/pci-acpi.c
> +++ b/drivers/pci/pci-acpi.c
> @@ -9,7 +9,9 @@
>  
>  #include <linux/delay.h>
>  #include <linux/init.h>
> +#include <linux/irqdomain.h>
>  #include <linux/pci.h>
> +#include <linux/msi.h>
>  #include <linux/pci_hotplug.h>
>  #include <linux/module.h>
>  #include <linux/pci-aspm.h>
> @@ -689,6 +691,46 @@ static struct acpi_bus_type acpi_pci_bus = {
>  	.cleanup = pci_acpi_cleanup,
>  };
>  
> +
> +static struct fwnode_handle *(*pci_msi_get_fwnode_cb)(struct device *dev);
> +
> +/**
> + * pci_msi_register_fwnode_provider - Register callback to retrieve fwnode
> + * @fn:       Callback matching a device to a fwnode that identifies a PCI
> + *            MSI domain.
> + *
> + * This should be called by irqchip driver, which is the parent of
> + * the MSI domain to provide callback interface to query fwnode.
> + */
> +void
> +pci_msi_register_fwnode_provider(struct fwnode_handle *(*fn)(struct device *))
> +{
> +	pci_msi_get_fwnode_cb = fn;
> +}
> +
> +/**
> + * pci_host_bridge_acpi_msi_domain - Retrieve MSI domain of a PCI host bridge
> + * @bus:      The PCI host bridge bus.
> + *
> + * This function uses the callback function registered by
> + * pci_msi_register_fwnode_provider() to retrieve the irq_domain with
> + * type DOMAIN_BUS_PCI_MSI of the specified host bridge bus.
> + * This returns NULL on error or when the domain is not found.
> + */
> +struct irq_domain *pci_host_bridge_acpi_msi_domain(struct pci_bus *bus)
> +{
> +	struct fwnode_handle *fwnode;
> +
> +	if (!pci_msi_get_fwnode_cb)
> +		return NULL;
> +
> +	fwnode = pci_msi_get_fwnode_cb(&bus->dev);
> +	if (!fwnode)
> +		return NULL;
> +
> +	return irq_find_matching_fwnode(fwnode, DOMAIN_BUS_PCI_MSI);
> +}
> +
>  static int __init acpi_pci_init(void)
>  {
>  	int ret;
> diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
> index edb1984..553a029 100644
> --- a/drivers/pci/probe.c
> +++ b/drivers/pci/probe.c
> @@ -672,6 +672,8 @@ static struct irq_domain *pci_host_bridge_msi_domain(struct pci_bus *bus)
>  	 * should be called from here.
>  	 */
>  	d = pci_host_bridge_of_msi_domain(bus);
> +	if (!d)
> +		d = pci_host_bridge_acpi_msi_domain(bus);
>  
>  	return d;
>  }
> diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
> index d5e5c5b..a06feda 100644
> --- a/include/linux/irqdomain.h
> +++ b/include/linux/irqdomain.h
> @@ -410,6 +410,11 @@ static inline bool irq_domain_is_hierarchy(struct irq_domain *domain)
>  static inline void irq_dispose_mapping(unsigned int virq) { }
>  static inline void irq_domain_activate_irq(struct irq_data *data) { }
>  static inline void irq_domain_deactivate_irq(struct irq_data *data) { }
> +static inline struct irq_domain *irq_find_matching_fwnode(
> +	struct fwnode_handle *fwnode, enum irq_domain_bus_token bus_token)
> +{
> +	return NULL;
> +}
>  #endif /* !CONFIG_IRQ_DOMAIN */
>  
>  #endif /* _LINUX_IRQDOMAIN_H */
> diff --git a/include/linux/pci.h b/include/linux/pci.h
> index 6ae25aa..d86378c 100644
> --- a/include/linux/pci.h
> +++ b/include/linux/pci.h
> @@ -1946,6 +1946,16 @@ static inline struct irq_domain *
>  pci_host_bridge_of_msi_domain(struct pci_bus *bus) { return NULL; }
>  #endif  /* CONFIG_OF */
>  
> +#ifdef CONFIG_ACPI
> +struct irq_domain *pci_host_bridge_acpi_msi_domain(struct pci_bus *bus);
> +
> +void
> +pci_msi_register_fwnode_provider(struct fwnode_handle *(*fn)(struct device *));
> +#else
> +static inline struct irq_domain *
> +pci_host_bridge_acpi_msi_domain(struct pci_bus *bus) { return NULL; }
> +#endif
> +
>  #ifdef CONFIG_EEH
>  static inline struct eeh_dev *pci_dev_to_eeh_dev(struct pci_dev *pdev)
>  {
> -- 
> 2.1.0
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-pci" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH v7 1/4] acpi: pci: Setup MSI domain for ACPI based pci devices
@ 2015-12-16 22:15     ` Bjorn Helgaas
  0 siblings, 0 replies; 42+ messages in thread
From: Bjorn Helgaas @ 2015-12-16 22:15 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Dec 10, 2015 at 08:55:27AM -0800, Suravee Suthikulpanit wrote:
> This patch introduces pci_msi_register_fwnode_provider() for irqchip
> to register a callback, to provide a way to determine appropriate MSI
> domain for a pci device.
> 
> It also introduces pci_host_bridge_acpi_msi_domain(), which returns
> the MSI domain of the specified PCI host bridge with DOMAIN_BUS_PCI_MSI
> bus token. Then, it is assigned to pci device.
> 
> Reviewed-by: Marc Zyngier <marc.zyngier@arm.com>
> Cc: Bjorn Helgaas <bhelgaas@google.com>
> Cc: Rafael J. Wysocki <rjw@rjwysocki.net>
> Signed-off-by: Suravee Suthikulpanit <Suravee.Suthikulpanit@amd.com>

Acked-by: Bjorn Helgaas <bhelgaas@google.com>

I assume the whole series will be queued via a non-PCI tree.

> ---
>  drivers/pci/pci-acpi.c    | 42 ++++++++++++++++++++++++++++++++++++++++++
>  drivers/pci/probe.c       |  2 ++
>  include/linux/irqdomain.h |  5 +++++
>  include/linux/pci.h       | 10 ++++++++++
>  4 files changed, 59 insertions(+)
> 
> diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
> index a32ba75..d3f32d6 100644
> --- a/drivers/pci/pci-acpi.c
> +++ b/drivers/pci/pci-acpi.c
> @@ -9,7 +9,9 @@
>  
>  #include <linux/delay.h>
>  #include <linux/init.h>
> +#include <linux/irqdomain.h>
>  #include <linux/pci.h>
> +#include <linux/msi.h>
>  #include <linux/pci_hotplug.h>
>  #include <linux/module.h>
>  #include <linux/pci-aspm.h>
> @@ -689,6 +691,46 @@ static struct acpi_bus_type acpi_pci_bus = {
>  	.cleanup = pci_acpi_cleanup,
>  };
>  
> +
> +static struct fwnode_handle *(*pci_msi_get_fwnode_cb)(struct device *dev);
> +
> +/**
> + * pci_msi_register_fwnode_provider - Register callback to retrieve fwnode
> + * @fn:       Callback matching a device to a fwnode that identifies a PCI
> + *            MSI domain.
> + *
> + * This should be called by irqchip driver, which is the parent of
> + * the MSI domain to provide callback interface to query fwnode.
> + */
> +void
> +pci_msi_register_fwnode_provider(struct fwnode_handle *(*fn)(struct device *))
> +{
> +	pci_msi_get_fwnode_cb = fn;
> +}
> +
> +/**
> + * pci_host_bridge_acpi_msi_domain - Retrieve MSI domain of a PCI host bridge
> + * @bus:      The PCI host bridge bus.
> + *
> + * This function uses the callback function registered by
> + * pci_msi_register_fwnode_provider() to retrieve the irq_domain with
> + * type DOMAIN_BUS_PCI_MSI of the specified host bridge bus.
> + * This returns NULL on error or when the domain is not found.
> + */
> +struct irq_domain *pci_host_bridge_acpi_msi_domain(struct pci_bus *bus)
> +{
> +	struct fwnode_handle *fwnode;
> +
> +	if (!pci_msi_get_fwnode_cb)
> +		return NULL;
> +
> +	fwnode = pci_msi_get_fwnode_cb(&bus->dev);
> +	if (!fwnode)
> +		return NULL;
> +
> +	return irq_find_matching_fwnode(fwnode, DOMAIN_BUS_PCI_MSI);
> +}
> +
>  static int __init acpi_pci_init(void)
>  {
>  	int ret;
> diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
> index edb1984..553a029 100644
> --- a/drivers/pci/probe.c
> +++ b/drivers/pci/probe.c
> @@ -672,6 +672,8 @@ static struct irq_domain *pci_host_bridge_msi_domain(struct pci_bus *bus)
>  	 * should be called from here.
>  	 */
>  	d = pci_host_bridge_of_msi_domain(bus);
> +	if (!d)
> +		d = pci_host_bridge_acpi_msi_domain(bus);
>  
>  	return d;
>  }
> diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
> index d5e5c5b..a06feda 100644
> --- a/include/linux/irqdomain.h
> +++ b/include/linux/irqdomain.h
> @@ -410,6 +410,11 @@ static inline bool irq_domain_is_hierarchy(struct irq_domain *domain)
>  static inline void irq_dispose_mapping(unsigned int virq) { }
>  static inline void irq_domain_activate_irq(struct irq_data *data) { }
>  static inline void irq_domain_deactivate_irq(struct irq_data *data) { }
> +static inline struct irq_domain *irq_find_matching_fwnode(
> +	struct fwnode_handle *fwnode, enum irq_domain_bus_token bus_token)
> +{
> +	return NULL;
> +}
>  #endif /* !CONFIG_IRQ_DOMAIN */
>  
>  #endif /* _LINUX_IRQDOMAIN_H */
> diff --git a/include/linux/pci.h b/include/linux/pci.h
> index 6ae25aa..d86378c 100644
> --- a/include/linux/pci.h
> +++ b/include/linux/pci.h
> @@ -1946,6 +1946,16 @@ static inline struct irq_domain *
>  pci_host_bridge_of_msi_domain(struct pci_bus *bus) { return NULL; }
>  #endif  /* CONFIG_OF */
>  
> +#ifdef CONFIG_ACPI
> +struct irq_domain *pci_host_bridge_acpi_msi_domain(struct pci_bus *bus);
> +
> +void
> +pci_msi_register_fwnode_provider(struct fwnode_handle *(*fn)(struct device *));
> +#else
> +static inline struct irq_domain *
> +pci_host_bridge_acpi_msi_domain(struct pci_bus *bus) { return NULL; }
> +#endif
> +
>  #ifdef CONFIG_EEH
>  static inline struct eeh_dev *pci_dev_to_eeh_dev(struct pci_dev *pdev)
>  {
> -- 
> 2.1.0
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-pci" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCH v7 3/4] gicv2m: Refactor to prepare for ACPI support
  2015-12-16 22:12     ` Bjorn Helgaas
  (?)
@ 2015-12-17  0:23       ` Suravee Suthikulanit
  -1 siblings, 0 replies; 42+ messages in thread
From: Suravee Suthikulanit @ 2015-12-17  0:23 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: marc.zyngier, tglx, jason, rjw, bhelgaas, Lorenzo Pieralisi,
	Will Deacon, Catalin Marinas, hanjun.guo, tomasz.nowicki,
	graeme.gregory, dhdang, linux-arm-kernel, linux-kernel,
	linux-acpi, linux-pci

Hi Bjorn,

Thanks for your review. Please see my comments below.

On 12/16/2015 4:12 PM, Bjorn Helgaas wrote:
> On Thu, Dec 10, 2015 at 08:55:29AM -0800, Suravee Suthikulpanit wrote:
>> This patch replaces the struct device_node with struct fwnode_handle
>> since this structure is common between DT and ACPI.
>>
>> It also refactors gicv2m_init_one() to prepare for ACPI support.
>> The only functional change is removing the node name from pr_info.
>>
>> Reviewed-by: Marc Zyngier <marc.zyngier@arm.com>
>> Signed-off-by: Suravee Suthikulpanit <Suravee.Suthikulpanit@amd.com>
>
>> @@ -359,10 +355,10 @@ static int __init gicv2m_init_one(struct device_node *node,
>>   	}
>>
>>   	list_add_tail(&v2m->entry, &v2m_nodes);
>> -	pr_info("Node %s: range[%#lx:%#lx], SPI[%d:%d]\n", node->name,
>> -		(unsigned long)v2m->res.start, (unsigned long)v2m->res.end,
>> -		v2m->spi_start, (v2m->spi_start + v2m->nr_spis));
>>
>> +	pr_info("range[%#lx:%#lx], SPI[%d:%d]\n",
>> +		(unsigned long)res->start, (unsigned long)res->end,
>> +		v2m->spi_start, (v2m->spi_start + v2m->nr_spis));
>
> You didn't change this, but I don't think this message has enough
> context.  It's pretty cryptic all by itself.  It'd be nice if it could
> at least include a device name, e.g., if you could use dev_info().

Here is the example of the information printed:
[    0.000000] GICv2m: range[0xe1180000:0xe1181000], SPI[64:320]

Basically, the v2m is just an extension of the GIC. Here, we are 
printing the memory range that it is covering, which can be used to 
identify different V2m frame and the associate interrupt range (SPI). 
The node name is not really providing any values. So, we are removing it.

Thanks,
Suravee

> If that's possible, I guess a separate patch would be appropriate,
> since there are other similar things in this file.
> j
> Bjorn




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

* Re: [PATCH v7 3/4] gicv2m: Refactor to prepare for ACPI support
@ 2015-12-17  0:23       ` Suravee Suthikulanit
  0 siblings, 0 replies; 42+ messages in thread
From: Suravee Suthikulanit @ 2015-12-17  0:23 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: marc.zyngier, tglx, jason, rjw, bhelgaas, Lorenzo Pieralisi,
	Will Deacon, Catalin Marinas, hanjun.guo, tomasz.nowicki,
	graeme.gregory, dhdang, linux-arm-kernel, linux-kernel,
	linux-acpi, linux-pci

Hi Bjorn,

Thanks for your review. Please see my comments below.

On 12/16/2015 4:12 PM, Bjorn Helgaas wrote:
> On Thu, Dec 10, 2015 at 08:55:29AM -0800, Suravee Suthikulpanit wrote:
>> This patch replaces the struct device_node with struct fwnode_handle
>> since this structure is common between DT and ACPI.
>>
>> It also refactors gicv2m_init_one() to prepare for ACPI support.
>> The only functional change is removing the node name from pr_info.
>>
>> Reviewed-by: Marc Zyngier <marc.zyngier@arm.com>
>> Signed-off-by: Suravee Suthikulpanit <Suravee.Suthikulpanit@amd.com>
>
>> @@ -359,10 +355,10 @@ static int __init gicv2m_init_one(struct device_node *node,
>>   	}
>>
>>   	list_add_tail(&v2m->entry, &v2m_nodes);
>> -	pr_info("Node %s: range[%#lx:%#lx], SPI[%d:%d]\n", node->name,
>> -		(unsigned long)v2m->res.start, (unsigned long)v2m->res.end,
>> -		v2m->spi_start, (v2m->spi_start + v2m->nr_spis));
>>
>> +	pr_info("range[%#lx:%#lx], SPI[%d:%d]\n",
>> +		(unsigned long)res->start, (unsigned long)res->end,
>> +		v2m->spi_start, (v2m->spi_start + v2m->nr_spis));
>
> You didn't change this, but I don't think this message has enough
> context.  It's pretty cryptic all by itself.  It'd be nice if it could
> at least include a device name, e.g., if you could use dev_info().

Here is the example of the information printed:
[    0.000000] GICv2m: range[0xe1180000:0xe1181000], SPI[64:320]

Basically, the v2m is just an extension of the GIC. Here, we are 
printing the memory range that it is covering, which can be used to 
identify different V2m frame and the associate interrupt range (SPI). 
The node name is not really providing any values. So, we are removing it.

Thanks,
Suravee

> If that's possible, I guess a separate patch would be appropriate,
> since there are other similar things in this file.
> j
> Bjorn




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

* [PATCH v7 3/4] gicv2m: Refactor to prepare for ACPI support
@ 2015-12-17  0:23       ` Suravee Suthikulanit
  0 siblings, 0 replies; 42+ messages in thread
From: Suravee Suthikulanit @ 2015-12-17  0:23 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Bjorn,

Thanks for your review. Please see my comments below.

On 12/16/2015 4:12 PM, Bjorn Helgaas wrote:
> On Thu, Dec 10, 2015 at 08:55:29AM -0800, Suravee Suthikulpanit wrote:
>> This patch replaces the struct device_node with struct fwnode_handle
>> since this structure is common between DT and ACPI.
>>
>> It also refactors gicv2m_init_one() to prepare for ACPI support.
>> The only functional change is removing the node name from pr_info.
>>
>> Reviewed-by: Marc Zyngier <marc.zyngier@arm.com>
>> Signed-off-by: Suravee Suthikulpanit <Suravee.Suthikulpanit@amd.com>
>
>> @@ -359,10 +355,10 @@ static int __init gicv2m_init_one(struct device_node *node,
>>   	}
>>
>>   	list_add_tail(&v2m->entry, &v2m_nodes);
>> -	pr_info("Node %s: range[%#lx:%#lx], SPI[%d:%d]\n", node->name,
>> -		(unsigned long)v2m->res.start, (unsigned long)v2m->res.end,
>> -		v2m->spi_start, (v2m->spi_start + v2m->nr_spis));
>>
>> +	pr_info("range[%#lx:%#lx], SPI[%d:%d]\n",
>> +		(unsigned long)res->start, (unsigned long)res->end,
>> +		v2m->spi_start, (v2m->spi_start + v2m->nr_spis));
>
> You didn't change this, but I don't think this message has enough
> context.  It's pretty cryptic all by itself.  It'd be nice if it could
> at least include a device name, e.g., if you could use dev_info().

Here is the example of the information printed:
[    0.000000] GICv2m: range[0xe1180000:0xe1181000], SPI[64:320]

Basically, the v2m is just an extension of the GIC. Here, we are 
printing the memory range that it is covering, which can be used to 
identify different V2m frame and the associate interrupt range (SPI). 
The node name is not really providing any values. So, we are removing it.

Thanks,
Suravee

> If that's possible, I guess a separate patch would be appropriate,
> since there are other similar things in this file.
> j
> Bjorn

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

* Re: [PATCH v7 1/4] acpi: pci: Setup MSI domain for ACPI based pci devices
  2015-12-16 22:15     ` Bjorn Helgaas
  (?)
@ 2015-12-17  0:25       ` Suravee Suthikulanit
  -1 siblings, 0 replies; 42+ messages in thread
From: Suravee Suthikulanit @ 2015-12-17  0:25 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: marc.zyngier, tglx, jason, rjw, bhelgaas, Lorenzo Pieralisi,
	Will Deacon, Catalin Marinas, hanjun.guo, tomasz.nowicki,
	graeme.gregory, dhdang, linux-arm-kernel, linux-kernel,
	linux-acpi, linux-pci

On 12/16/2015 4:15 PM, Bjorn Helgaas wrote:
> On Thu, Dec 10, 2015 at 08:55:27AM -0800, Suravee Suthikulpanit wrote:
>> >This patch introduces pci_msi_register_fwnode_provider() for irqchip
>> >to register a callback, to provide a way to determine appropriate MSI
>> >domain for a pci device.
>> >
>> >It also introduces pci_host_bridge_acpi_msi_domain(), which returns
>> >the MSI domain of the specified PCI host bridge with DOMAIN_BUS_PCI_MSI
>> >bus token. Then, it is assigned to pci device.
>> >
>> >Reviewed-by: Marc Zyngier<marc.zyngier@arm.com>
>> >Cc: Bjorn Helgaas<bhelgaas@google.com>
>> >Cc: Rafael J. Wysocki<rjw@rjwysocki.net>
>> >Signed-off-by: Suravee Suthikulpanit<Suravee.Suthikulpanit@amd.com>
> Acked-by: Bjorn Helgaas<bhelgaas@google.com>
>
> I assume the whole series will be queued via a non-PCI tree.
>

Thank you, Bjorn. I think Marc is planning to pull this in once all 
parties have acked the patch series.

Suravee

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

* Re: [PATCH v7 1/4] acpi: pci: Setup MSI domain for ACPI based pci devices
@ 2015-12-17  0:25       ` Suravee Suthikulanit
  0 siblings, 0 replies; 42+ messages in thread
From: Suravee Suthikulanit @ 2015-12-17  0:25 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: marc.zyngier, tglx, jason, rjw, bhelgaas, Lorenzo Pieralisi,
	Will Deacon, Catalin Marinas, hanjun.guo, tomasz.nowicki,
	graeme.gregory, dhdang, linux-arm-kernel, linux-kernel,
	linux-acpi, linux-pci

On 12/16/2015 4:15 PM, Bjorn Helgaas wrote:
> On Thu, Dec 10, 2015 at 08:55:27AM -0800, Suravee Suthikulpanit wrote:
>> >This patch introduces pci_msi_register_fwnode_provider() for irqchip
>> >to register a callback, to provide a way to determine appropriate MSI
>> >domain for a pci device.
>> >
>> >It also introduces pci_host_bridge_acpi_msi_domain(), which returns
>> >the MSI domain of the specified PCI host bridge with DOMAIN_BUS_PCI_MSI
>> >bus token. Then, it is assigned to pci device.
>> >
>> >Reviewed-by: Marc Zyngier<marc.zyngier@arm.com>
>> >Cc: Bjorn Helgaas<bhelgaas@google.com>
>> >Cc: Rafael J. Wysocki<rjw@rjwysocki.net>
>> >Signed-off-by: Suravee Suthikulpanit<Suravee.Suthikulpanit@amd.com>
> Acked-by: Bjorn Helgaas<bhelgaas@google.com>
>
> I assume the whole series will be queued via a non-PCI tree.
>

Thank you, Bjorn. I think Marc is planning to pull this in once all 
parties have acked the patch series.

Suravee

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

* [PATCH v7 1/4] acpi: pci: Setup MSI domain for ACPI based pci devices
@ 2015-12-17  0:25       ` Suravee Suthikulanit
  0 siblings, 0 replies; 42+ messages in thread
From: Suravee Suthikulanit @ 2015-12-17  0:25 UTC (permalink / raw)
  To: linux-arm-kernel

On 12/16/2015 4:15 PM, Bjorn Helgaas wrote:
> On Thu, Dec 10, 2015 at 08:55:27AM -0800, Suravee Suthikulpanit wrote:
>> >This patch introduces pci_msi_register_fwnode_provider() for irqchip
>> >to register a callback, to provide a way to determine appropriate MSI
>> >domain for a pci device.
>> >
>> >It also introduces pci_host_bridge_acpi_msi_domain(), which returns
>> >the MSI domain of the specified PCI host bridge with DOMAIN_BUS_PCI_MSI
>> >bus token. Then, it is assigned to pci device.
>> >
>> >Reviewed-by: Marc Zyngier<marc.zyngier@arm.com>
>> >Cc: Bjorn Helgaas<bhelgaas@google.com>
>> >Cc: Rafael J. Wysocki<rjw@rjwysocki.net>
>> >Signed-off-by: Suravee Suthikulpanit<Suravee.Suthikulpanit@amd.com>
> Acked-by: Bjorn Helgaas<bhelgaas@google.com>
>
> I assume the whole series will be queued via a non-PCI tree.
>

Thank you, Bjorn. I think Marc is planning to pull this in once all 
parties have acked the patch series.

Suravee

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

* Re: [PATCH v7 3/4] gicv2m: Refactor to prepare for ACPI support
  2015-12-17  0:23       ` Suravee Suthikulanit
@ 2015-12-17 16:57         ` Bjorn Helgaas
  -1 siblings, 0 replies; 42+ messages in thread
From: Bjorn Helgaas @ 2015-12-17 16:57 UTC (permalink / raw)
  To: Suravee Suthikulanit
  Cc: marc.zyngier, tglx, jason, rjw, bhelgaas, Lorenzo Pieralisi,
	Will Deacon, Catalin Marinas, hanjun.guo, tomasz.nowicki,
	graeme.gregory, dhdang, linux-arm-kernel, linux-kernel,
	linux-acpi, linux-pci

On Wed, Dec 16, 2015 at 06:23:49PM -0600, Suravee Suthikulanit wrote:
> Hi Bjorn,
> 
> Thanks for your review. Please see my comments below.
> 
> On 12/16/2015 4:12 PM, Bjorn Helgaas wrote:
> >On Thu, Dec 10, 2015 at 08:55:29AM -0800, Suravee Suthikulpanit wrote:
> >>This patch replaces the struct device_node with struct fwnode_handle
> >>since this structure is common between DT and ACPI.
> >>
> >>It also refactors gicv2m_init_one() to prepare for ACPI support.
> >>The only functional change is removing the node name from pr_info.
> >>
> >>Reviewed-by: Marc Zyngier <marc.zyngier@arm.com>
> >>Signed-off-by: Suravee Suthikulpanit <Suravee.Suthikulpanit@amd.com>
> >
> >>@@ -359,10 +355,10 @@ static int __init gicv2m_init_one(struct device_node *node,
> >>  	}
> >>
> >>  	list_add_tail(&v2m->entry, &v2m_nodes);
> >>-	pr_info("Node %s: range[%#lx:%#lx], SPI[%d:%d]\n", node->name,
> >>-		(unsigned long)v2m->res.start, (unsigned long)v2m->res.end,
> >>-		v2m->spi_start, (v2m->spi_start + v2m->nr_spis));
> >>
> >>+	pr_info("range[%#lx:%#lx], SPI[%d:%d]\n",
> >>+		(unsigned long)res->start, (unsigned long)res->end,
> >>+		v2m->spi_start, (v2m->spi_start + v2m->nr_spis));
> >
> >You didn't change this, but I don't think this message has enough
> >context.  It's pretty cryptic all by itself.  It'd be nice if it could
> >at least include a device name, e.g., if you could use dev_info().
> 
> Here is the example of the information printed:
> [    0.000000] GICv2m: range[0xe1180000:0xe1181000], SPI[64:320]
> 
> Basically, the v2m is just an extension of the GIC. Here, we are
> printing the memory range that it is covering, which can be used to
> identify different V2m frame and the associate interrupt range
> (SPI). The node name is not really providing any values. So, we are
> removing it.

I noticed the pr_fmt definition later; that adds some useful context I
didn't know about.  I guess there's no struct device for the GIC?  I
don't see one in struct device_node.  Seems like this piece of
hardware that apparently responds to a memory range *could* have a
struct device, but I'm a little fuzzy on how we handle ACPI and OF
device descriptions in that regard.

I hadn't noticed the memory range part; maybe you could use %pR there?

Just to double-check, there's no off-by-one error in the SPI range, is
there?  The pattern I usually expect is "start, start + nr_items - 1".

I'm just kibbitzing here; this isn't PCI code, and you don't need my
ack, so just consider these as random observations.

Bjorn

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

* [PATCH v7 3/4] gicv2m: Refactor to prepare for ACPI support
@ 2015-12-17 16:57         ` Bjorn Helgaas
  0 siblings, 0 replies; 42+ messages in thread
From: Bjorn Helgaas @ 2015-12-17 16:57 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Dec 16, 2015 at 06:23:49PM -0600, Suravee Suthikulanit wrote:
> Hi Bjorn,
> 
> Thanks for your review. Please see my comments below.
> 
> On 12/16/2015 4:12 PM, Bjorn Helgaas wrote:
> >On Thu, Dec 10, 2015 at 08:55:29AM -0800, Suravee Suthikulpanit wrote:
> >>This patch replaces the struct device_node with struct fwnode_handle
> >>since this structure is common between DT and ACPI.
> >>
> >>It also refactors gicv2m_init_one() to prepare for ACPI support.
> >>The only functional change is removing the node name from pr_info.
> >>
> >>Reviewed-by: Marc Zyngier <marc.zyngier@arm.com>
> >>Signed-off-by: Suravee Suthikulpanit <Suravee.Suthikulpanit@amd.com>
> >
> >>@@ -359,10 +355,10 @@ static int __init gicv2m_init_one(struct device_node *node,
> >>  	}
> >>
> >>  	list_add_tail(&v2m->entry, &v2m_nodes);
> >>-	pr_info("Node %s: range[%#lx:%#lx], SPI[%d:%d]\n", node->name,
> >>-		(unsigned long)v2m->res.start, (unsigned long)v2m->res.end,
> >>-		v2m->spi_start, (v2m->spi_start + v2m->nr_spis));
> >>
> >>+	pr_info("range[%#lx:%#lx], SPI[%d:%d]\n",
> >>+		(unsigned long)res->start, (unsigned long)res->end,
> >>+		v2m->spi_start, (v2m->spi_start + v2m->nr_spis));
> >
> >You didn't change this, but I don't think this message has enough
> >context.  It's pretty cryptic all by itself.  It'd be nice if it could
> >at least include a device name, e.g., if you could use dev_info().
> 
> Here is the example of the information printed:
> [    0.000000] GICv2m: range[0xe1180000:0xe1181000], SPI[64:320]
> 
> Basically, the v2m is just an extension of the GIC. Here, we are
> printing the memory range that it is covering, which can be used to
> identify different V2m frame and the associate interrupt range
> (SPI). The node name is not really providing any values. So, we are
> removing it.

I noticed the pr_fmt definition later; that adds some useful context I
didn't know about.  I guess there's no struct device for the GIC?  I
don't see one in struct device_node.  Seems like this piece of
hardware that apparently responds to a memory range *could* have a
struct device, but I'm a little fuzzy on how we handle ACPI and OF
device descriptions in that regard.

I hadn't noticed the memory range part; maybe you could use %pR there?

Just to double-check, there's no off-by-one error in the SPI range, is
there?  The pattern I usually expect is "start, start + nr_items - 1".

I'm just kibbitzing here; this isn't PCI code, and you don't need my
ack, so just consider these as random observations.

Bjorn

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

* Re: [PATCH v7 1/4] acpi: pci: Setup MSI domain for ACPI based pci devices
  2015-12-10 16:55   ` Suravee Suthikulpanit
@ 2015-12-21  3:02     ` Rafael J. Wysocki
  -1 siblings, 0 replies; 42+ messages in thread
From: Rafael J. Wysocki @ 2015-12-21  3:02 UTC (permalink / raw)
  To: Suravee Suthikulpanit
  Cc: marc.zyngier, tglx, jason, bhelgaas, Lorenzo Pieralisi,
	Will Deacon, Catalin Marinas, hanjun.guo, tomasz.nowicki,
	graeme.gregory, dhdang, linux-arm-kernel, linux-kernel,
	linux-acpi, linux-pci

On Thursday, December 10, 2015 08:55:27 AM Suravee Suthikulpanit wrote:
> This patch introduces pci_msi_register_fwnode_provider() for irqchip
> to register a callback, to provide a way to determine appropriate MSI
> domain for a pci device.
> 
> It also introduces pci_host_bridge_acpi_msi_domain(), which returns
> the MSI domain of the specified PCI host bridge with DOMAIN_BUS_PCI_MSI
> bus token. Then, it is assigned to pci device.
> 
> Reviewed-by: Marc Zyngier <marc.zyngier@arm.com>
> Cc: Bjorn Helgaas <bhelgaas@google.com>
> Cc: Rafael J. Wysocki <rjw@rjwysocki.net>
> Signed-off-by: Suravee Suthikulpanit <Suravee.Suthikulpanit@amd.com>

Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

> ---
>  drivers/pci/pci-acpi.c    | 42 ++++++++++++++++++++++++++++++++++++++++++
>  drivers/pci/probe.c       |  2 ++
>  include/linux/irqdomain.h |  5 +++++
>  include/linux/pci.h       | 10 ++++++++++
>  4 files changed, 59 insertions(+)
> 
> diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
> index a32ba75..d3f32d6 100644
> --- a/drivers/pci/pci-acpi.c
> +++ b/drivers/pci/pci-acpi.c
> @@ -9,7 +9,9 @@
>  
>  #include <linux/delay.h>
>  #include <linux/init.h>
> +#include <linux/irqdomain.h>
>  #include <linux/pci.h>
> +#include <linux/msi.h>
>  #include <linux/pci_hotplug.h>
>  #include <linux/module.h>
>  #include <linux/pci-aspm.h>
> @@ -689,6 +691,46 @@ static struct acpi_bus_type acpi_pci_bus = {
>  	.cleanup = pci_acpi_cleanup,
>  };
>  
> +
> +static struct fwnode_handle *(*pci_msi_get_fwnode_cb)(struct device *dev);
> +
> +/**
> + * pci_msi_register_fwnode_provider - Register callback to retrieve fwnode
> + * @fn:       Callback matching a device to a fwnode that identifies a PCI
> + *            MSI domain.
> + *
> + * This should be called by irqchip driver, which is the parent of
> + * the MSI domain to provide callback interface to query fwnode.
> + */
> +void
> +pci_msi_register_fwnode_provider(struct fwnode_handle *(*fn)(struct device *))
> +{
> +	pci_msi_get_fwnode_cb = fn;
> +}
> +
> +/**
> + * pci_host_bridge_acpi_msi_domain - Retrieve MSI domain of a PCI host bridge
> + * @bus:      The PCI host bridge bus.
> + *
> + * This function uses the callback function registered by
> + * pci_msi_register_fwnode_provider() to retrieve the irq_domain with
> + * type DOMAIN_BUS_PCI_MSI of the specified host bridge bus.
> + * This returns NULL on error or when the domain is not found.
> + */
> +struct irq_domain *pci_host_bridge_acpi_msi_domain(struct pci_bus *bus)
> +{
> +	struct fwnode_handle *fwnode;
> +
> +	if (!pci_msi_get_fwnode_cb)
> +		return NULL;
> +
> +	fwnode = pci_msi_get_fwnode_cb(&bus->dev);
> +	if (!fwnode)
> +		return NULL;
> +
> +	return irq_find_matching_fwnode(fwnode, DOMAIN_BUS_PCI_MSI);
> +}
> +
>  static int __init acpi_pci_init(void)
>  {
>  	int ret;
> diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
> index edb1984..553a029 100644
> --- a/drivers/pci/probe.c
> +++ b/drivers/pci/probe.c
> @@ -672,6 +672,8 @@ static struct irq_domain *pci_host_bridge_msi_domain(struct pci_bus *bus)
>  	 * should be called from here.
>  	 */
>  	d = pci_host_bridge_of_msi_domain(bus);
> +	if (!d)
> +		d = pci_host_bridge_acpi_msi_domain(bus);
>  
>  	return d;
>  }
> diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
> index d5e5c5b..a06feda 100644
> --- a/include/linux/irqdomain.h
> +++ b/include/linux/irqdomain.h
> @@ -410,6 +410,11 @@ static inline bool irq_domain_is_hierarchy(struct irq_domain *domain)
>  static inline void irq_dispose_mapping(unsigned int virq) { }
>  static inline void irq_domain_activate_irq(struct irq_data *data) { }
>  static inline void irq_domain_deactivate_irq(struct irq_data *data) { }
> +static inline struct irq_domain *irq_find_matching_fwnode(
> +	struct fwnode_handle *fwnode, enum irq_domain_bus_token bus_token)
> +{
> +	return NULL;
> +}
>  #endif /* !CONFIG_IRQ_DOMAIN */
>  
>  #endif /* _LINUX_IRQDOMAIN_H */
> diff --git a/include/linux/pci.h b/include/linux/pci.h
> index 6ae25aa..d86378c 100644
> --- a/include/linux/pci.h
> +++ b/include/linux/pci.h
> @@ -1946,6 +1946,16 @@ static inline struct irq_domain *
>  pci_host_bridge_of_msi_domain(struct pci_bus *bus) { return NULL; }
>  #endif  /* CONFIG_OF */
>  
> +#ifdef CONFIG_ACPI
> +struct irq_domain *pci_host_bridge_acpi_msi_domain(struct pci_bus *bus);
> +
> +void
> +pci_msi_register_fwnode_provider(struct fwnode_handle *(*fn)(struct device *));
> +#else
> +static inline struct irq_domain *
> +pci_host_bridge_acpi_msi_domain(struct pci_bus *bus) { return NULL; }
> +#endif
> +
>  #ifdef CONFIG_EEH
>  static inline struct eeh_dev *pci_dev_to_eeh_dev(struct pci_dev *pdev)
>  {
> 

-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

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

* [PATCH v7 1/4] acpi: pci: Setup MSI domain for ACPI based pci devices
@ 2015-12-21  3:02     ` Rafael J. Wysocki
  0 siblings, 0 replies; 42+ messages in thread
From: Rafael J. Wysocki @ 2015-12-21  3:02 UTC (permalink / raw)
  To: linux-arm-kernel

On Thursday, December 10, 2015 08:55:27 AM Suravee Suthikulpanit wrote:
> This patch introduces pci_msi_register_fwnode_provider() for irqchip
> to register a callback, to provide a way to determine appropriate MSI
> domain for a pci device.
> 
> It also introduces pci_host_bridge_acpi_msi_domain(), which returns
> the MSI domain of the specified PCI host bridge with DOMAIN_BUS_PCI_MSI
> bus token. Then, it is assigned to pci device.
> 
> Reviewed-by: Marc Zyngier <marc.zyngier@arm.com>
> Cc: Bjorn Helgaas <bhelgaas@google.com>
> Cc: Rafael J. Wysocki <rjw@rjwysocki.net>
> Signed-off-by: Suravee Suthikulpanit <Suravee.Suthikulpanit@amd.com>

Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

> ---
>  drivers/pci/pci-acpi.c    | 42 ++++++++++++++++++++++++++++++++++++++++++
>  drivers/pci/probe.c       |  2 ++
>  include/linux/irqdomain.h |  5 +++++
>  include/linux/pci.h       | 10 ++++++++++
>  4 files changed, 59 insertions(+)
> 
> diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
> index a32ba75..d3f32d6 100644
> --- a/drivers/pci/pci-acpi.c
> +++ b/drivers/pci/pci-acpi.c
> @@ -9,7 +9,9 @@
>  
>  #include <linux/delay.h>
>  #include <linux/init.h>
> +#include <linux/irqdomain.h>
>  #include <linux/pci.h>
> +#include <linux/msi.h>
>  #include <linux/pci_hotplug.h>
>  #include <linux/module.h>
>  #include <linux/pci-aspm.h>
> @@ -689,6 +691,46 @@ static struct acpi_bus_type acpi_pci_bus = {
>  	.cleanup = pci_acpi_cleanup,
>  };
>  
> +
> +static struct fwnode_handle *(*pci_msi_get_fwnode_cb)(struct device *dev);
> +
> +/**
> + * pci_msi_register_fwnode_provider - Register callback to retrieve fwnode
> + * @fn:       Callback matching a device to a fwnode that identifies a PCI
> + *            MSI domain.
> + *
> + * This should be called by irqchip driver, which is the parent of
> + * the MSI domain to provide callback interface to query fwnode.
> + */
> +void
> +pci_msi_register_fwnode_provider(struct fwnode_handle *(*fn)(struct device *))
> +{
> +	pci_msi_get_fwnode_cb = fn;
> +}
> +
> +/**
> + * pci_host_bridge_acpi_msi_domain - Retrieve MSI domain of a PCI host bridge
> + * @bus:      The PCI host bridge bus.
> + *
> + * This function uses the callback function registered by
> + * pci_msi_register_fwnode_provider() to retrieve the irq_domain with
> + * type DOMAIN_BUS_PCI_MSI of the specified host bridge bus.
> + * This returns NULL on error or when the domain is not found.
> + */
> +struct irq_domain *pci_host_bridge_acpi_msi_domain(struct pci_bus *bus)
> +{
> +	struct fwnode_handle *fwnode;
> +
> +	if (!pci_msi_get_fwnode_cb)
> +		return NULL;
> +
> +	fwnode = pci_msi_get_fwnode_cb(&bus->dev);
> +	if (!fwnode)
> +		return NULL;
> +
> +	return irq_find_matching_fwnode(fwnode, DOMAIN_BUS_PCI_MSI);
> +}
> +
>  static int __init acpi_pci_init(void)
>  {
>  	int ret;
> diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
> index edb1984..553a029 100644
> --- a/drivers/pci/probe.c
> +++ b/drivers/pci/probe.c
> @@ -672,6 +672,8 @@ static struct irq_domain *pci_host_bridge_msi_domain(struct pci_bus *bus)
>  	 * should be called from here.
>  	 */
>  	d = pci_host_bridge_of_msi_domain(bus);
> +	if (!d)
> +		d = pci_host_bridge_acpi_msi_domain(bus);
>  
>  	return d;
>  }
> diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
> index d5e5c5b..a06feda 100644
> --- a/include/linux/irqdomain.h
> +++ b/include/linux/irqdomain.h
> @@ -410,6 +410,11 @@ static inline bool irq_domain_is_hierarchy(struct irq_domain *domain)
>  static inline void irq_dispose_mapping(unsigned int virq) { }
>  static inline void irq_domain_activate_irq(struct irq_data *data) { }
>  static inline void irq_domain_deactivate_irq(struct irq_data *data) { }
> +static inline struct irq_domain *irq_find_matching_fwnode(
> +	struct fwnode_handle *fwnode, enum irq_domain_bus_token bus_token)
> +{
> +	return NULL;
> +}
>  #endif /* !CONFIG_IRQ_DOMAIN */
>  
>  #endif /* _LINUX_IRQDOMAIN_H */
> diff --git a/include/linux/pci.h b/include/linux/pci.h
> index 6ae25aa..d86378c 100644
> --- a/include/linux/pci.h
> +++ b/include/linux/pci.h
> @@ -1946,6 +1946,16 @@ static inline struct irq_domain *
>  pci_host_bridge_of_msi_domain(struct pci_bus *bus) { return NULL; }
>  #endif  /* CONFIG_OF */
>  
> +#ifdef CONFIG_ACPI
> +struct irq_domain *pci_host_bridge_acpi_msi_domain(struct pci_bus *bus);
> +
> +void
> +pci_msi_register_fwnode_provider(struct fwnode_handle *(*fn)(struct device *));
> +#else
> +static inline struct irq_domain *
> +pci_host_bridge_acpi_msi_domain(struct pci_bus *bus) { return NULL; }
> +#endif
> +
>  #ifdef CONFIG_EEH
>  static inline struct eeh_dev *pci_dev_to_eeh_dev(struct pci_dev *pdev)
>  {
> 

-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

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

* Re: [PATCH v7 4/4] gicv2m: acpi: Introducing GICv2m ACPI support
  2015-12-10 16:55   ` Suravee Suthikulpanit
@ 2015-12-21  3:04     ` Rafael J. Wysocki
  -1 siblings, 0 replies; 42+ messages in thread
From: Rafael J. Wysocki @ 2015-12-21  3:04 UTC (permalink / raw)
  To: Suravee Suthikulpanit
  Cc: marc.zyngier, tglx, jason, bhelgaas, Lorenzo Pieralisi,
	Will Deacon, Catalin Marinas, hanjun.guo, tomasz.nowicki,
	graeme.gregory, dhdang, linux-arm-kernel, linux-kernel,
	linux-acpi, linux-pci

On Thursday, December 10, 2015 08:55:30 AM Suravee Suthikulpanit wrote:
> This patch introduces gicv2m_acpi_init(), which uses information
> in MADT GIC MSI frames structure to initialize GICv2m driver.
> It also exposes gicv2m_init() function, which simplifies callers
> to a single GICv2m init function.
> 
> Reviewed-by: Marc Zyngier <marc.zyngier@arm.com>
> Tested-by: Duc Dang <dhdang@apm.com>
> Signed-off-by: Suravee Suthikulpanit <Suravee.Suthikulpanit@amd.com>
> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>

I don't see anything objectionable here, so please feel free to add my ACK
for the ACPI part to this.

> ---
>  drivers/irqchip/irq-gic-v2m.c   | 110 +++++++++++++++++++++++++++++++++++++++-
>  drivers/irqchip/irq-gic.c       |   6 ++-
>  include/linux/irqchip/arm-gic.h |   3 +-
>  3 files changed, 116 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/irqchip/irq-gic-v2m.c b/drivers/irqchip/irq-gic-v2m.c
> index 779c390..7e2975d 100644
> --- a/drivers/irqchip/irq-gic-v2m.c
> +++ b/drivers/irqchip/irq-gic-v2m.c
> @@ -15,9 +15,11 @@
>  
>  #define pr_fmt(fmt) "GICv2m: " fmt
>  
> +#include <linux/acpi.h>
>  #include <linux/irq.h>
>  #include <linux/irqdomain.h>
>  #include <linux/kernel.h>
> +#include <linux/msi.h>
>  #include <linux/of_address.h>
>  #include <linux/of_pci.h>
>  #include <linux/slab.h>
> @@ -138,6 +140,11 @@ static int gicv2m_irq_gic_domain_alloc(struct irq_domain *domain,
>  		fwspec.param[0] = 0;
>  		fwspec.param[1] = hwirq - 32;
>  		fwspec.param[2] = IRQ_TYPE_EDGE_RISING;
> +	} else if (is_fwnode_irqchip(domain->parent->fwnode)) {
> +		fwspec.fwnode = domain->parent->fwnode;
> +		fwspec.param_count = 2;
> +		fwspec.param[0] = hwirq;
> +		fwspec.param[1] = IRQ_TYPE_EDGE_RISING;
>  	} else {
>  		return -EINVAL;
>  	}
> @@ -255,6 +262,8 @@ static void gicv2m_teardown(void)
>  		kfree(v2m->bm);
>  		iounmap(v2m->base);
>  		of_node_put(to_of_node(v2m->fwnode));
> +		if (is_fwnode_irqchip(v2m->fwnode))
> +			irq_domain_free_fwnode(v2m->fwnode);
>  		kfree(v2m);
>  	}
>  }
> @@ -373,9 +382,11 @@ static struct of_device_id gicv2m_device_id[] = {
>  	{},
>  };
>  
> -int __init gicv2m_of_init(struct device_node *node, struct irq_domain *parent)
> +static int __init gicv2m_of_init(struct fwnode_handle *parent_handle,
> +				 struct irq_domain *parent)
>  {
>  	int ret = 0;
> +	struct device_node *node = to_of_node(parent_handle);
>  	struct device_node *child;
>  
>  	for (child = of_find_matching_node(node, gicv2m_device_id); child;
> @@ -411,3 +422,100 @@ int __init gicv2m_of_init(struct device_node *node, struct irq_domain *parent)
>  		gicv2m_teardown();
>  	return ret;
>  }
> +
> +#ifdef CONFIG_ACPI
> +static int acpi_num_msi;
> +
> +static struct fwnode_handle *gicv2m_get_fwnode(struct device *dev)
> +{
> +	struct v2m_data *data;
> +
> +	if (WARN_ON(acpi_num_msi <= 0))
> +		return NULL;
> +
> +	/* We only return the fwnode of the first MSI frame. */
> +	data = list_first_entry_or_null(&v2m_nodes, struct v2m_data, entry);
> +	if (!data)
> +		return NULL;
> +
> +	return data->fwnode;
> +}
> +
> +static int __init
> +acpi_parse_madt_msi(struct acpi_subtable_header *header,
> +		    const unsigned long end)
> +{
> +	int ret;
> +	struct resource res;
> +	u32 spi_start = 0, nr_spis = 0;
> +	struct acpi_madt_generic_msi_frame *m;
> +	struct fwnode_handle *fwnode;
> +
> +	m = (struct acpi_madt_generic_msi_frame *)header;
> +	if (BAD_MADT_ENTRY(m, end))
> +		return -EINVAL;
> +
> +	res.start = m->base_address;
> +	res.end = m->base_address + SZ_4K;
> +
> +	if (m->flags & ACPI_MADT_OVERRIDE_SPI_VALUES) {
> +		spi_start = m->spi_base;
> +		nr_spis = m->spi_count;
> +
> +		pr_info("ACPI overriding V2M MSI_TYPER (base:%u, num:%u)\n",
> +			spi_start, nr_spis);
> +	}
> +
> +	fwnode = irq_domain_alloc_fwnode((void *)m->base_address);
> +	if (!fwnode) {
> +		pr_err("Unable to allocate GICv2m domain token\n");
> +		return -EINVAL;
> +	}
> +
> +	ret = gicv2m_init_one(fwnode, spi_start, nr_spis, &res);
> +	if (ret)
> +		irq_domain_free_fwnode(fwnode);
> +
> +	return ret;
> +}
> +
> +static int __init gicv2m_acpi_init(struct irq_domain *parent)
> +{
> +	int ret;
> +
> +	if (acpi_num_msi > 0)
> +		return 0;
> +
> +	acpi_num_msi = acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_MSI_FRAME,
> +				      acpi_parse_madt_msi, 0);
> +
> +	if (acpi_num_msi <= 0)
> +		goto err_out;
> +
> +	ret = gicv2m_allocate_domains(parent);
> +	if (ret)
> +		goto err_out;
> +
> +	pci_msi_register_fwnode_provider(&gicv2m_get_fwnode);
> +
> +	return 0;
> +
> +err_out:
> +	gicv2m_teardown();
> +	return -EINVAL;
> +}
> +#else /* CONFIG_ACPI */
> +static int __init gicv2m_acpi_init(struct irq_domain *parent)
> +{
> +	return -EINVAL;
> +}
> +#endif /* CONFIG_ACPI */
> +
> +int __init gicv2m_init(struct fwnode_handle *parent_handle,
> +		       struct irq_domain *parent)
> +{
> +	if (is_of_node(parent_handle))
> +		return gicv2m_of_init(parent_handle, parent);
> +
> +	return gicv2m_acpi_init(parent);
> +}
> diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
> index fcd327f..644e8bb 100644
> --- a/drivers/irqchip/irq-gic.c
> +++ b/drivers/irqchip/irq-gic.c
> @@ -1234,7 +1234,7 @@ gic_of_init(struct device_node *node, struct device_node *parent)
>  	}
>  
>  	if (IS_ENABLED(CONFIG_ARM_GIC_V2M))
> -		gicv2m_of_init(node, gic_data[gic_cnt].domain);
> +		gicv2m_init(&node->fwnode, gic_data[gic_cnt].domain);
>  
>  	gic_cnt++;
>  	return 0;
> @@ -1359,6 +1359,10 @@ static int __init gic_v2_acpi_init(struct acpi_subtable_header *header,
>  	__gic_init_bases(0, -1, dist_base, cpu_base, 0, domain_handle);
>  
>  	acpi_set_irq_model(ACPI_IRQ_MODEL_GIC, domain_handle);
> +
> +	if (IS_ENABLED(CONFIG_ARM_GIC_V2M))
> +		gicv2m_init(NULL, gic_data[0].domain);
> +
>  	return 0;
>  }
>  IRQCHIP_ACPI_DECLARE(gic_v2, ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR,
> diff --git a/include/linux/irqchip/arm-gic.h b/include/linux/irqchip/arm-gic.h
> index bae69e5..febc6c3 100644
> --- a/include/linux/irqchip/arm-gic.h
> +++ b/include/linux/irqchip/arm-gic.h
> @@ -106,7 +106,8 @@ int gic_cpu_if_down(unsigned int gic_nr);
>  void gic_init(unsigned int nr, int start,
>  	      void __iomem *dist , void __iomem *cpu);
>  
> -int gicv2m_of_init(struct device_node *node, struct irq_domain *parent);
> +int gicv2m_init(struct fwnode_handle *parent_handle,
> +		struct irq_domain *parent);
>  
>  void gic_send_sgi(unsigned int cpu_id, unsigned int irq);
>  int gic_get_cpu_id(unsigned int cpu);
> 

-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

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

* [PATCH v7 4/4] gicv2m: acpi: Introducing GICv2m ACPI support
@ 2015-12-21  3:04     ` Rafael J. Wysocki
  0 siblings, 0 replies; 42+ messages in thread
From: Rafael J. Wysocki @ 2015-12-21  3:04 UTC (permalink / raw)
  To: linux-arm-kernel

On Thursday, December 10, 2015 08:55:30 AM Suravee Suthikulpanit wrote:
> This patch introduces gicv2m_acpi_init(), which uses information
> in MADT GIC MSI frames structure to initialize GICv2m driver.
> It also exposes gicv2m_init() function, which simplifies callers
> to a single GICv2m init function.
> 
> Reviewed-by: Marc Zyngier <marc.zyngier@arm.com>
> Tested-by: Duc Dang <dhdang@apm.com>
> Signed-off-by: Suravee Suthikulpanit <Suravee.Suthikulpanit@amd.com>
> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>

I don't see anything objectionable here, so please feel free to add my ACK
for the ACPI part to this.

> ---
>  drivers/irqchip/irq-gic-v2m.c   | 110 +++++++++++++++++++++++++++++++++++++++-
>  drivers/irqchip/irq-gic.c       |   6 ++-
>  include/linux/irqchip/arm-gic.h |   3 +-
>  3 files changed, 116 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/irqchip/irq-gic-v2m.c b/drivers/irqchip/irq-gic-v2m.c
> index 779c390..7e2975d 100644
> --- a/drivers/irqchip/irq-gic-v2m.c
> +++ b/drivers/irqchip/irq-gic-v2m.c
> @@ -15,9 +15,11 @@
>  
>  #define pr_fmt(fmt) "GICv2m: " fmt
>  
> +#include <linux/acpi.h>
>  #include <linux/irq.h>
>  #include <linux/irqdomain.h>
>  #include <linux/kernel.h>
> +#include <linux/msi.h>
>  #include <linux/of_address.h>
>  #include <linux/of_pci.h>
>  #include <linux/slab.h>
> @@ -138,6 +140,11 @@ static int gicv2m_irq_gic_domain_alloc(struct irq_domain *domain,
>  		fwspec.param[0] = 0;
>  		fwspec.param[1] = hwirq - 32;
>  		fwspec.param[2] = IRQ_TYPE_EDGE_RISING;
> +	} else if (is_fwnode_irqchip(domain->parent->fwnode)) {
> +		fwspec.fwnode = domain->parent->fwnode;
> +		fwspec.param_count = 2;
> +		fwspec.param[0] = hwirq;
> +		fwspec.param[1] = IRQ_TYPE_EDGE_RISING;
>  	} else {
>  		return -EINVAL;
>  	}
> @@ -255,6 +262,8 @@ static void gicv2m_teardown(void)
>  		kfree(v2m->bm);
>  		iounmap(v2m->base);
>  		of_node_put(to_of_node(v2m->fwnode));
> +		if (is_fwnode_irqchip(v2m->fwnode))
> +			irq_domain_free_fwnode(v2m->fwnode);
>  		kfree(v2m);
>  	}
>  }
> @@ -373,9 +382,11 @@ static struct of_device_id gicv2m_device_id[] = {
>  	{},
>  };
>  
> -int __init gicv2m_of_init(struct device_node *node, struct irq_domain *parent)
> +static int __init gicv2m_of_init(struct fwnode_handle *parent_handle,
> +				 struct irq_domain *parent)
>  {
>  	int ret = 0;
> +	struct device_node *node = to_of_node(parent_handle);
>  	struct device_node *child;
>  
>  	for (child = of_find_matching_node(node, gicv2m_device_id); child;
> @@ -411,3 +422,100 @@ int __init gicv2m_of_init(struct device_node *node, struct irq_domain *parent)
>  		gicv2m_teardown();
>  	return ret;
>  }
> +
> +#ifdef CONFIG_ACPI
> +static int acpi_num_msi;
> +
> +static struct fwnode_handle *gicv2m_get_fwnode(struct device *dev)
> +{
> +	struct v2m_data *data;
> +
> +	if (WARN_ON(acpi_num_msi <= 0))
> +		return NULL;
> +
> +	/* We only return the fwnode of the first MSI frame. */
> +	data = list_first_entry_or_null(&v2m_nodes, struct v2m_data, entry);
> +	if (!data)
> +		return NULL;
> +
> +	return data->fwnode;
> +}
> +
> +static int __init
> +acpi_parse_madt_msi(struct acpi_subtable_header *header,
> +		    const unsigned long end)
> +{
> +	int ret;
> +	struct resource res;
> +	u32 spi_start = 0, nr_spis = 0;
> +	struct acpi_madt_generic_msi_frame *m;
> +	struct fwnode_handle *fwnode;
> +
> +	m = (struct acpi_madt_generic_msi_frame *)header;
> +	if (BAD_MADT_ENTRY(m, end))
> +		return -EINVAL;
> +
> +	res.start = m->base_address;
> +	res.end = m->base_address + SZ_4K;
> +
> +	if (m->flags & ACPI_MADT_OVERRIDE_SPI_VALUES) {
> +		spi_start = m->spi_base;
> +		nr_spis = m->spi_count;
> +
> +		pr_info("ACPI overriding V2M MSI_TYPER (base:%u, num:%u)\n",
> +			spi_start, nr_spis);
> +	}
> +
> +	fwnode = irq_domain_alloc_fwnode((void *)m->base_address);
> +	if (!fwnode) {
> +		pr_err("Unable to allocate GICv2m domain token\n");
> +		return -EINVAL;
> +	}
> +
> +	ret = gicv2m_init_one(fwnode, spi_start, nr_spis, &res);
> +	if (ret)
> +		irq_domain_free_fwnode(fwnode);
> +
> +	return ret;
> +}
> +
> +static int __init gicv2m_acpi_init(struct irq_domain *parent)
> +{
> +	int ret;
> +
> +	if (acpi_num_msi > 0)
> +		return 0;
> +
> +	acpi_num_msi = acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_MSI_FRAME,
> +				      acpi_parse_madt_msi, 0);
> +
> +	if (acpi_num_msi <= 0)
> +		goto err_out;
> +
> +	ret = gicv2m_allocate_domains(parent);
> +	if (ret)
> +		goto err_out;
> +
> +	pci_msi_register_fwnode_provider(&gicv2m_get_fwnode);
> +
> +	return 0;
> +
> +err_out:
> +	gicv2m_teardown();
> +	return -EINVAL;
> +}
> +#else /* CONFIG_ACPI */
> +static int __init gicv2m_acpi_init(struct irq_domain *parent)
> +{
> +	return -EINVAL;
> +}
> +#endif /* CONFIG_ACPI */
> +
> +int __init gicv2m_init(struct fwnode_handle *parent_handle,
> +		       struct irq_domain *parent)
> +{
> +	if (is_of_node(parent_handle))
> +		return gicv2m_of_init(parent_handle, parent);
> +
> +	return gicv2m_acpi_init(parent);
> +}
> diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
> index fcd327f..644e8bb 100644
> --- a/drivers/irqchip/irq-gic.c
> +++ b/drivers/irqchip/irq-gic.c
> @@ -1234,7 +1234,7 @@ gic_of_init(struct device_node *node, struct device_node *parent)
>  	}
>  
>  	if (IS_ENABLED(CONFIG_ARM_GIC_V2M))
> -		gicv2m_of_init(node, gic_data[gic_cnt].domain);
> +		gicv2m_init(&node->fwnode, gic_data[gic_cnt].domain);
>  
>  	gic_cnt++;
>  	return 0;
> @@ -1359,6 +1359,10 @@ static int __init gic_v2_acpi_init(struct acpi_subtable_header *header,
>  	__gic_init_bases(0, -1, dist_base, cpu_base, 0, domain_handle);
>  
>  	acpi_set_irq_model(ACPI_IRQ_MODEL_GIC, domain_handle);
> +
> +	if (IS_ENABLED(CONFIG_ARM_GIC_V2M))
> +		gicv2m_init(NULL, gic_data[0].domain);
> +
>  	return 0;
>  }
>  IRQCHIP_ACPI_DECLARE(gic_v2, ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR,
> diff --git a/include/linux/irqchip/arm-gic.h b/include/linux/irqchip/arm-gic.h
> index bae69e5..febc6c3 100644
> --- a/include/linux/irqchip/arm-gic.h
> +++ b/include/linux/irqchip/arm-gic.h
> @@ -106,7 +106,8 @@ int gic_cpu_if_down(unsigned int gic_nr);
>  void gic_init(unsigned int nr, int start,
>  	      void __iomem *dist , void __iomem *cpu);
>  
> -int gicv2m_of_init(struct device_node *node, struct irq_domain *parent);
> +int gicv2m_init(struct fwnode_handle *parent_handle,
> +		struct irq_domain *parent);
>  
>  void gic_send_sgi(unsigned int cpu_id, unsigned int irq);
>  int gic_get_cpu_id(unsigned int cpu);
> 

-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

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

* Re: [PATCH v7 3/4] gicv2m: Refactor to prepare for ACPI support
  2015-12-17 16:57         ` Bjorn Helgaas
  (?)
@ 2015-12-22 23:04           ` Suravee Suthikulanit
  -1 siblings, 0 replies; 42+ messages in thread
From: Suravee Suthikulanit @ 2015-12-22 23:04 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: marc.zyngier, tglx, jason, rjw, bhelgaas, Lorenzo Pieralisi,
	Will Deacon, Catalin Marinas, hanjun.guo, tomasz.nowicki,
	graeme.gregory, dhdang, linux-arm-kernel, linux-kernel,
	linux-acpi, linux-pci

On 12/17/2015 10:57 AM, Bjorn Helgaas wrote:
> On Wed, Dec 16, 2015 at 06:23:49PM -0600, Suravee Suthikulanit wrote:
>> Hi Bjorn,
>>
>> Thanks for your review. Please see my comments below.
>>
>> On 12/16/2015 4:12 PM, Bjorn Helgaas wrote:
>>> On Thu, Dec 10, 2015 at 08:55:29AM -0800, Suravee Suthikulpanit wrote:
>>>> This patch replaces the struct device_node with struct fwnode_handle
>>>> since this structure is common between DT and ACPI.
>>>>
>>>> It also refactors gicv2m_init_one() to prepare for ACPI support.
>>>> The only functional change is removing the node name from pr_info.
>>>>
>>>> Reviewed-by: Marc Zyngier <marc.zyngier@arm.com>
>>>> Signed-off-by: Suravee Suthikulpanit <Suravee.Suthikulpanit@amd.com>
>>>
>>>> @@ -359,10 +355,10 @@ static int __init gicv2m_init_one(struct device_node *node,
>>>>   	}
>>>>
>>>>   	list_add_tail(&v2m->entry, &v2m_nodes);
>>>> -	pr_info("Node %s: range[%#lx:%#lx], SPI[%d:%d]\n", node->name,
>>>> -		(unsigned long)v2m->res.start, (unsigned long)v2m->res.end,
>>>> -		v2m->spi_start, (v2m->spi_start + v2m->nr_spis));
>>>>
>>>> +	pr_info("range[%#lx:%#lx], SPI[%d:%d]\n",
>>>> +		(unsigned long)res->start, (unsigned long)res->end,
>>>> +		v2m->spi_start, (v2m->spi_start + v2m->nr_spis));
>>>
>>> You didn't change this, but I don't think this message has enough
>>> context.  It's pretty cryptic all by itself.  It'd be nice if it could
>>> at least include a device name, e.g., if you could use dev_info().
>>
>> Here is the example of the information printed:
>> [    0.000000] GICv2m: range[0xe1180000:0xe1181000], SPI[64:320]
>>
>> Basically, the v2m is just an extension of the GIC. Here, we are
>> printing the memory range that it is covering, which can be used to
>> identify different V2m frame and the associate interrupt range
>> (SPI). The node name is not really providing any values. So, we are
>> removing it.
>
> I noticed the pr_fmt definition later; that adds some useful context I
> didn't know about.  I guess there's no struct device for the GIC?  I
> don't see one in struct device_node.  Seems like this piece of
> hardware that apparently responds to a memory range *could* have a
> struct device,but I'm a little fuzzy on how we handle ACPI and OF
> device descriptions in that regard.

For DT, v2m is advertised as a sub-node inside GIC. So, both of them has 
the struct device_node references. IIUC, GIC node is match as irqchip, 
and not as a traditional platform bus device.

Similarly, for ACPI, v2m is advertised as a sub-table inside MADT, and 
we are using the fwnode_handle to reference to.

> I hadn't noticed the memory range part; maybe you could use %pR there?

I guess we could have :) I can send a separate patch to clean this up.

> Just to double-check, there's no off-by-one error in the SPI range, is
> there?  The pattern I usually expect is "start, start + nr_items - 1".

In that case, this should have been [64:319]. I'll send a small patch to 
clean this up.

> I'm just kibbitzing here; this isn't PCI code, and you don't need my
> ack, so just consider these as random observations.
>
> Bjorn
>

Thanks for sharing your observation. It's always been good ones :)

Suravee

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

* Re: [PATCH v7 3/4] gicv2m: Refactor to prepare for ACPI support
@ 2015-12-22 23:04           ` Suravee Suthikulanit
  0 siblings, 0 replies; 42+ messages in thread
From: Suravee Suthikulanit @ 2015-12-22 23:04 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: marc.zyngier, tglx, jason, rjw, bhelgaas, Lorenzo Pieralisi,
	Will Deacon, Catalin Marinas, hanjun.guo, tomasz.nowicki,
	graeme.gregory, dhdang, linux-arm-kernel, linux-kernel,
	linux-acpi, linux-pci

On 12/17/2015 10:57 AM, Bjorn Helgaas wrote:
> On Wed, Dec 16, 2015 at 06:23:49PM -0600, Suravee Suthikulanit wrote:
>> Hi Bjorn,
>>
>> Thanks for your review. Please see my comments below.
>>
>> On 12/16/2015 4:12 PM, Bjorn Helgaas wrote:
>>> On Thu, Dec 10, 2015 at 08:55:29AM -0800, Suravee Suthikulpanit wrote:
>>>> This patch replaces the struct device_node with struct fwnode_handle
>>>> since this structure is common between DT and ACPI.
>>>>
>>>> It also refactors gicv2m_init_one() to prepare for ACPI support.
>>>> The only functional change is removing the node name from pr_info.
>>>>
>>>> Reviewed-by: Marc Zyngier <marc.zyngier@arm.com>
>>>> Signed-off-by: Suravee Suthikulpanit <Suravee.Suthikulpanit@amd.com>
>>>
>>>> @@ -359,10 +355,10 @@ static int __init gicv2m_init_one(struct device_node *node,
>>>>   	}
>>>>
>>>>   	list_add_tail(&v2m->entry, &v2m_nodes);
>>>> -	pr_info("Node %s: range[%#lx:%#lx], SPI[%d:%d]\n", node->name,
>>>> -		(unsigned long)v2m->res.start, (unsigned long)v2m->res.end,
>>>> -		v2m->spi_start, (v2m->spi_start + v2m->nr_spis));
>>>>
>>>> +	pr_info("range[%#lx:%#lx], SPI[%d:%d]\n",
>>>> +		(unsigned long)res->start, (unsigned long)res->end,
>>>> +		v2m->spi_start, (v2m->spi_start + v2m->nr_spis));
>>>
>>> You didn't change this, but I don't think this message has enough
>>> context.  It's pretty cryptic all by itself.  It'd be nice if it could
>>> at least include a device name, e.g., if you could use dev_info().
>>
>> Here is the example of the information printed:
>> [    0.000000] GICv2m: range[0xe1180000:0xe1181000], SPI[64:320]
>>
>> Basically, the v2m is just an extension of the GIC. Here, we are
>> printing the memory range that it is covering, which can be used to
>> identify different V2m frame and the associate interrupt range
>> (SPI). The node name is not really providing any values. So, we are
>> removing it.
>
> I noticed the pr_fmt definition later; that adds some useful context I
> didn't know about.  I guess there's no struct device for the GIC?  I
> don't see one in struct device_node.  Seems like this piece of
> hardware that apparently responds to a memory range *could* have a
> struct device,but I'm a little fuzzy on how we handle ACPI and OF
> device descriptions in that regard.

For DT, v2m is advertised as a sub-node inside GIC. So, both of them has 
the struct device_node references. IIUC, GIC node is match as irqchip, 
and not as a traditional platform bus device.

Similarly, for ACPI, v2m is advertised as a sub-table inside MADT, and 
we are using the fwnode_handle to reference to.

> I hadn't noticed the memory range part; maybe you could use %pR there?

I guess we could have :) I can send a separate patch to clean this up.

> Just to double-check, there's no off-by-one error in the SPI range, is
> there?  The pattern I usually expect is "start, start + nr_items - 1".

In that case, this should have been [64:319]. I'll send a small patch to 
clean this up.

> I'm just kibbitzing here; this isn't PCI code, and you don't need my
> ack, so just consider these as random observations.
>
> Bjorn
>

Thanks for sharing your observation. It's always been good ones :)

Suravee

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

* [PATCH v7 3/4] gicv2m: Refactor to prepare for ACPI support
@ 2015-12-22 23:04           ` Suravee Suthikulanit
  0 siblings, 0 replies; 42+ messages in thread
From: Suravee Suthikulanit @ 2015-12-22 23:04 UTC (permalink / raw)
  To: linux-arm-kernel

On 12/17/2015 10:57 AM, Bjorn Helgaas wrote:
> On Wed, Dec 16, 2015 at 06:23:49PM -0600, Suravee Suthikulanit wrote:
>> Hi Bjorn,
>>
>> Thanks for your review. Please see my comments below.
>>
>> On 12/16/2015 4:12 PM, Bjorn Helgaas wrote:
>>> On Thu, Dec 10, 2015 at 08:55:29AM -0800, Suravee Suthikulpanit wrote:
>>>> This patch replaces the struct device_node with struct fwnode_handle
>>>> since this structure is common between DT and ACPI.
>>>>
>>>> It also refactors gicv2m_init_one() to prepare for ACPI support.
>>>> The only functional change is removing the node name from pr_info.
>>>>
>>>> Reviewed-by: Marc Zyngier <marc.zyngier@arm.com>
>>>> Signed-off-by: Suravee Suthikulpanit <Suravee.Suthikulpanit@amd.com>
>>>
>>>> @@ -359,10 +355,10 @@ static int __init gicv2m_init_one(struct device_node *node,
>>>>   	}
>>>>
>>>>   	list_add_tail(&v2m->entry, &v2m_nodes);
>>>> -	pr_info("Node %s: range[%#lx:%#lx], SPI[%d:%d]\n", node->name,
>>>> -		(unsigned long)v2m->res.start, (unsigned long)v2m->res.end,
>>>> -		v2m->spi_start, (v2m->spi_start + v2m->nr_spis));
>>>>
>>>> +	pr_info("range[%#lx:%#lx], SPI[%d:%d]\n",
>>>> +		(unsigned long)res->start, (unsigned long)res->end,
>>>> +		v2m->spi_start, (v2m->spi_start + v2m->nr_spis));
>>>
>>> You didn't change this, but I don't think this message has enough
>>> context.  It's pretty cryptic all by itself.  It'd be nice if it could
>>> at least include a device name, e.g., if you could use dev_info().
>>
>> Here is the example of the information printed:
>> [    0.000000] GICv2m: range[0xe1180000:0xe1181000], SPI[64:320]
>>
>> Basically, the v2m is just an extension of the GIC. Here, we are
>> printing the memory range that it is covering, which can be used to
>> identify different V2m frame and the associate interrupt range
>> (SPI). The node name is not really providing any values. So, we are
>> removing it.
>
> I noticed the pr_fmt definition later; that adds some useful context I
> didn't know about.  I guess there's no struct device for the GIC?  I
> don't see one in struct device_node.  Seems like this piece of
> hardware that apparently responds to a memory range *could* have a
> struct device,but I'm a little fuzzy on how we handle ACPI and OF
> device descriptions in that regard.

For DT, v2m is advertised as a sub-node inside GIC. So, both of them has 
the struct device_node references. IIUC, GIC node is match as irqchip, 
and not as a traditional platform bus device.

Similarly, for ACPI, v2m is advertised as a sub-table inside MADT, and 
we are using the fwnode_handle to reference to.

> I hadn't noticed the memory range part; maybe you could use %pR there?

I guess we could have :) I can send a separate patch to clean this up.

> Just to double-check, there's no off-by-one error in the SPI range, is
> there?  The pattern I usually expect is "start, start + nr_items - 1".

In that case, this should have been [64:319]. I'll send a small patch to 
clean this up.

> I'm just kibbitzing here; this isn't PCI code, and you don't need my
> ack, so just consider these as random observations.
>
> Bjorn
>

Thanks for sharing your observation. It's always been good ones :)

Suravee

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

end of thread, other threads:[~2015-12-22 23:04 UTC | newest]

Thread overview: 42+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-12-10 16:55 [PATCH v7 0/4] gicv2m: acpi: Add ACPI support for GICv2m MSI Suravee Suthikulpanit
2015-12-10 16:55 ` Suravee Suthikulpanit
2015-12-10 16:55 ` Suravee Suthikulpanit
2015-12-10 16:55 ` [PATCH v7 1/4] acpi: pci: Setup MSI domain for ACPI based pci devices Suravee Suthikulpanit
2015-12-10 16:55   ` Suravee Suthikulpanit
2015-12-10 16:55   ` Suravee Suthikulpanit
2015-12-14 15:13   ` Marc Zyngier
2015-12-14 15:13     ` Marc Zyngier
2015-12-14 21:29     ` Rafael J. Wysocki
2015-12-14 21:29       ` Rafael J. Wysocki
2015-12-15  9:52       ` Marc Zyngier
2015-12-15  9:52         ` Marc Zyngier
2015-12-16 22:15   ` Bjorn Helgaas
2015-12-16 22:15     ` Bjorn Helgaas
2015-12-17  0:25     ` Suravee Suthikulanit
2015-12-17  0:25       ` Suravee Suthikulanit
2015-12-17  0:25       ` Suravee Suthikulanit
2015-12-21  3:02   ` Rafael J. Wysocki
2015-12-21  3:02     ` Rafael J. Wysocki
2015-12-10 16:55 ` [PATCH v7 2/4] irqdomain: introduce is_fwnode_irqchip helper Suravee Suthikulpanit
2015-12-10 16:55   ` Suravee Suthikulpanit
2015-12-10 16:55   ` Suravee Suthikulpanit
2015-12-10 16:55 ` [PATCH v7 3/4] gicv2m: Refactor to prepare for ACPI support Suravee Suthikulpanit
2015-12-10 16:55   ` Suravee Suthikulpanit
2015-12-10 16:55   ` Suravee Suthikulpanit
2015-12-16 22:12   ` Bjorn Helgaas
2015-12-16 22:12     ` Bjorn Helgaas
2015-12-17  0:23     ` Suravee Suthikulanit
2015-12-17  0:23       ` Suravee Suthikulanit
2015-12-17  0:23       ` Suravee Suthikulanit
2015-12-17 16:57       ` Bjorn Helgaas
2015-12-17 16:57         ` Bjorn Helgaas
2015-12-22 23:04         ` Suravee Suthikulanit
2015-12-22 23:04           ` Suravee Suthikulanit
2015-12-22 23:04           ` Suravee Suthikulanit
2015-12-10 16:55 ` [PATCH v7 4/4] gicv2m: acpi: Introducing GICv2m " Suravee Suthikulpanit
2015-12-10 16:55   ` Suravee Suthikulpanit
2015-12-10 16:55   ` Suravee Suthikulpanit
2015-12-21  3:04   ` Rafael J. Wysocki
2015-12-21  3:04     ` Rafael J. Wysocki
2015-12-10 17:28 ` [PATCH v7 0/4] gicv2m: acpi: Add ACPI support for GICv2m MSI Hanjun Guo
2015-12-10 17:28   ` Hanjun Guo

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.