All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC PATCH v2 00/11] ACPI platform MSI, interrupt producer/consumer and its example mbi-gen
@ 2016-09-14 14:21 ` Hanjun Guo
  0 siblings, 0 replies; 58+ messages in thread
From: Hanjun Guo @ 2016-09-14 14:21 UTC (permalink / raw)
  To: Rafael J. Wysocki, Marc Zyngier, Lorenzo Pieralisi
  Cc: linux-acpi, linux-arm-kernel, linux-kernel, Thomas Gleixner,
	Bjorn Helgaas, Greg KH, Tomasz Nowicki, Ma Jun, Kefeng Wang,
	Charles Garcia-Tobin, linuxarm, Hanjun Guo

From: Hanjun Guo <hanjun.guo@linaro.org>

With platform msi support landed in the kernel, and the introduction
of IORT for GICv3 ITS (PCI MSI) [1], the framework for platform msi
is ready, this patch set add few patches to enable the ACPI platform
msi support.

For platform device connecting to ITS on arm platform, we have IORT
table with the named componant node to describe the mappings of paltform
device and ITS, so we can retrieve the dev id and find its parent
irqdomain (ITS) from IORT table (simlar with the ACPI ITS support).

With acpi platform msi supported, we add the ACPI support for irqchip
mbi-gen, which use this framework to form its stacked irqdomain, below
is the mbi-gen's topology in the system:


  | ---------------|                  |------------------|
  |                |       MSI        |                  |     wired interrupt(s)
  |       ITS      |<-----------------|   MBI-GEN        |<----------------------------- IO device(s)
  |                |                  |                  |<----------------------------- IO device(s)
  ------------------                  -------------------

So with ACPI platform MSI support, we can build the stacked domain for
mbi-gen which represented its mappings with the named componant in IORT,
but we still missing the connectings of devices to mbi-gen as in ACPI
world devices connect to main interrupt controller in MADT in default.

In ACPI 6.1, section 19.6.62, Interrupt Resource Descriptor Macro,

    Interrupt (ResourceUsage, EdgeLevel, ActiveLevel, Shared,
    ResourceSourceIndex, ResourceSource, DescriptorName)
    { InterruptList } => Buffer
    
For the arguement ResourceUsage and DescriptorName, which means:
    
ResourceUsage describes whether the device consumes the specified
interrupt ( ResourceConsumer ) or produces it for use by a child
device ( ResourceProducer ).
If nothing is specified, then ResourceConsumer is assumed.
    
DescriptorName evaluates to a name string which refers to the
entire resource descriptor.
    
So it can be used for devices connecting to a specific interrupt
prodcucer instead of the main interrupt controller in MADT, we can
define:

Interrupt(ResourceConsumer,..., "\_SB.IRQP") {12,14,....},

then get the interrupt producer with the full path name "\_SB.IRQP".


v2:
  - Fix the bug of if multi Interrupt() resoures in single _PRS,
    we need to calculate all the irq numbers (I missed it in previous
    version);

  - Rebased on Marc's irq/irqchip-4.9 branch and Lorenzo's v5
    SMMu patches (also Robin's SMMu patches)

  - Add patch irqchip: mbigen: promote mbigen init.

This is the RFC version 2 and we still needs to address:
  -  we need to deal with the device topology as:
     NC (named componant) -> SMMU -> ITS.

Comments are warmly welcomed!

Thanks
Hanjun


Hanjun Guo (9):
  irqchip: gicv3-its: platform-msi: refactor its_pmsi_prepare()
  ACPI: platform-msi: retrieve dev id from IORT
  irqchip: gicv3-its: platform-msi: refactor its_pmsi_init() to prepare
    for ACPI
  irqchip: gicv3-its: platform-msi: scan MADT to create platform msi
    domain
  ACPI: platform: setup MSI domain for ACPI based platform device
  msi: platform: make platform_msi_create_device_domain() ACPI aware
  ACPI: irq: introduce interrupt producer
  irqchip: mbigen: Add ACPI support
  irqchip: mbigen: promote mbigen init

Kefeng Wang (2):
  irqchip: mbigen: drop module owner
  irqchip: mbigen: introduce mbigen_of_create_domain()

 drivers/acpi/arm64/iort.c                     |  31 ++++++-
 drivers/acpi/gsi.c                            |  10 ++-
 drivers/acpi/resource.c                       |  85 +++++++++++++------
 drivers/base/platform-msi.c                   |  20 ++++-
 drivers/base/platform.c                       |   2 +
 drivers/irqchip/irq-gic-v3-its-platform-msi.c | 107 ++++++++++++++++++------
 drivers/irqchip/irq-mbigen.c                  | 115 ++++++++++++++++++++++----
 include/acpi/acpi_bus.h                       |   1 +
 include/linux/acpi_iort.h                     |   8 ++
 include/linux/msi.h                           |   1 +
 10 files changed, 305 insertions(+), 75 deletions(-)

-- 
1.7.12.4

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

* [RFC PATCH v2 00/11] ACPI platform MSI, interrupt producer/consumer and its example mbi-gen
@ 2016-09-14 14:21 ` Hanjun Guo
  0 siblings, 0 replies; 58+ messages in thread
From: Hanjun Guo @ 2016-09-14 14:21 UTC (permalink / raw)
  To: Rafael J. Wysocki, Marc Zyngier, Lorenzo Pieralisi
  Cc: linux-acpi, linux-arm-kernel, linux-kernel, Thomas Gleixner,
	Bjorn Helgaas, Greg KH, Tomasz Nowicki, Ma Jun, Kefeng Wang,
	Charles Garcia-Tobin, linuxarm, Hanjun Guo

From: Hanjun Guo <hanjun.guo@linaro.org>

With platform msi support landed in the kernel, and the introduction
of IORT for GICv3 ITS (PCI MSI) [1], the framework for platform msi
is ready, this patch set add few patches to enable the ACPI platform
msi support.

For platform device connecting to ITS on arm platform, we have IORT
table with the named componant node to describe the mappings of paltform
device and ITS, so we can retrieve the dev id and find its parent
irqdomain (ITS) from IORT table (simlar with the ACPI ITS support).

With acpi platform msi supported, we add the ACPI support for irqchip
mbi-gen, which use this framework to form its stacked irqdomain, below
is the mbi-gen's topology in the system:


  | ---------------|                  |------------------|
  |                |       MSI        |                  |     wired interrupt(s)
  |       ITS      |<-----------------|   MBI-GEN        |<----------------------------- IO device(s)
  |                |                  |                  |<----------------------------- IO device(s)
  ------------------                  -------------------

So with ACPI platform MSI support, we can build the stacked domain for
mbi-gen which represented its mappings with the named componant in IORT,
but we still missing the connectings of devices to mbi-gen as in ACPI
world devices connect to main interrupt controller in MADT in default.

In ACPI 6.1, section 19.6.62, Interrupt Resource Descriptor Macro,

    Interrupt (ResourceUsage, EdgeLevel, ActiveLevel, Shared,
    ResourceSourceIndex, ResourceSource, DescriptorName)
    { InterruptList } => Buffer
    
For the arguement ResourceUsage and DescriptorName, which means:
    
ResourceUsage describes whether the device consumes the specified
interrupt ( ResourceConsumer ) or produces it for use by a child
device ( ResourceProducer ).
If nothing is specified, then ResourceConsumer is assumed.
    
DescriptorName evaluates to a name string which refers to the
entire resource descriptor.
    
So it can be used for devices connecting to a specific interrupt
prodcucer instead of the main interrupt controller in MADT, we can
define:

Interrupt(ResourceConsumer,..., "\_SB.IRQP") {12,14,....},

then get the interrupt producer with the full path name "\_SB.IRQP".


v2:
  - Fix the bug of if multi Interrupt() resoures in single _PRS,
    we need to calculate all the irq numbers (I missed it in previous
    version);

  - Rebased on Marc's irq/irqchip-4.9 branch and Lorenzo's v5
    SMMu patches (also Robin's SMMu patches)

  - Add patch irqchip: mbigen: promote mbigen init.

This is the RFC version 2 and we still needs to address:
  -  we need to deal with the device topology as:
     NC (named componant) -> SMMU -> ITS.

Comments are warmly welcomed!

Thanks
Hanjun


Hanjun Guo (9):
  irqchip: gicv3-its: platform-msi: refactor its_pmsi_prepare()
  ACPI: platform-msi: retrieve dev id from IORT
  irqchip: gicv3-its: platform-msi: refactor its_pmsi_init() to prepare
    for ACPI
  irqchip: gicv3-its: platform-msi: scan MADT to create platform msi
    domain
  ACPI: platform: setup MSI domain for ACPI based platform device
  msi: platform: make platform_msi_create_device_domain() ACPI aware
  ACPI: irq: introduce interrupt producer
  irqchip: mbigen: Add ACPI support
  irqchip: mbigen: promote mbigen init

Kefeng Wang (2):
  irqchip: mbigen: drop module owner
  irqchip: mbigen: introduce mbigen_of_create_domain()

 drivers/acpi/arm64/iort.c                     |  31 ++++++-
 drivers/acpi/gsi.c                            |  10 ++-
 drivers/acpi/resource.c                       |  85 +++++++++++++------
 drivers/base/platform-msi.c                   |  20 ++++-
 drivers/base/platform.c                       |   2 +
 drivers/irqchip/irq-gic-v3-its-platform-msi.c | 107 ++++++++++++++++++------
 drivers/irqchip/irq-mbigen.c                  | 115 ++++++++++++++++++++++----
 include/acpi/acpi_bus.h                       |   1 +
 include/linux/acpi_iort.h                     |   8 ++
 include/linux/msi.h                           |   1 +
 10 files changed, 305 insertions(+), 75 deletions(-)

-- 
1.7.12.4

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

* [RFC PATCH v2 00/11] ACPI platform MSI, interrupt producer/consumer and its example mbi-gen
@ 2016-09-14 14:21 ` Hanjun Guo
  0 siblings, 0 replies; 58+ messages in thread
From: Hanjun Guo @ 2016-09-14 14:21 UTC (permalink / raw)
  To: linux-arm-kernel

From: Hanjun Guo <hanjun.guo@linaro.org>

With platform msi support landed in the kernel, and the introduction
of IORT for GICv3 ITS (PCI MSI) [1], the framework for platform msi
is ready, this patch set add few patches to enable the ACPI platform
msi support.

For platform device connecting to ITS on arm platform, we have IORT
table with the named componant node to describe the mappings of paltform
device and ITS, so we can retrieve the dev id and find its parent
irqdomain (ITS) from IORT table (simlar with the ACPI ITS support).

With acpi platform msi supported, we add the ACPI support for irqchip
mbi-gen, which use this framework to form its stacked irqdomain, below
is the mbi-gen's topology in the system:


  | ---------------|                  |------------------|
  |                |       MSI        |                  |     wired interrupt(s)
  |       ITS      |<-----------------|   MBI-GEN        |<----------------------------- IO device(s)
  |                |                  |                  |<----------------------------- IO device(s)
  ------------------                  -------------------

So with ACPI platform MSI support, we can build the stacked domain for
mbi-gen which represented its mappings with the named componant in IORT,
but we still missing the connectings of devices to mbi-gen as in ACPI
world devices connect to main interrupt controller in MADT in default.

In ACPI 6.1, section 19.6.62, Interrupt Resource Descriptor Macro,

    Interrupt (ResourceUsage, EdgeLevel, ActiveLevel, Shared,
    ResourceSourceIndex, ResourceSource, DescriptorName)
    { InterruptList } => Buffer
    
For the arguement ResourceUsage and DescriptorName, which means:
    
ResourceUsage describes whether the device consumes the specified
interrupt ( ResourceConsumer ) or produces it for use by a child
device ( ResourceProducer ).
If nothing is specified, then ResourceConsumer is assumed.
    
DescriptorName evaluates to a name string which refers to the
entire resource descriptor.
    
So it can be used for devices connecting to a specific interrupt
prodcucer instead of the main interrupt controller in MADT, we can
define:

Interrupt(ResourceConsumer,..., "\_SB.IRQP") {12,14,....},

then get the interrupt producer with the full path name "\_SB.IRQP".


v2:
  - Fix the bug of if multi Interrupt() resoures in single _PRS,
    we need to calculate all the irq numbers (I missed it in previous
    version);

  - Rebased on Marc's irq/irqchip-4.9 branch and Lorenzo's v5
    SMMu patches (also Robin's SMMu patches)

  - Add patch irqchip: mbigen: promote mbigen init.

This is the RFC version 2 and we still needs to address:
  -  we need to deal with the device topology as:
     NC (named componant) -> SMMU -> ITS.

Comments are warmly welcomed!

Thanks
Hanjun


Hanjun Guo (9):
  irqchip: gicv3-its: platform-msi: refactor its_pmsi_prepare()
  ACPI: platform-msi: retrieve dev id from IORT
  irqchip: gicv3-its: platform-msi: refactor its_pmsi_init() to prepare
    for ACPI
  irqchip: gicv3-its: platform-msi: scan MADT to create platform msi
    domain
  ACPI: platform: setup MSI domain for ACPI based platform device
  msi: platform: make platform_msi_create_device_domain() ACPI aware
  ACPI: irq: introduce interrupt producer
  irqchip: mbigen: Add ACPI support
  irqchip: mbigen: promote mbigen init

Kefeng Wang (2):
  irqchip: mbigen: drop module owner
  irqchip: mbigen: introduce mbigen_of_create_domain()

 drivers/acpi/arm64/iort.c                     |  31 ++++++-
 drivers/acpi/gsi.c                            |  10 ++-
 drivers/acpi/resource.c                       |  85 +++++++++++++------
 drivers/base/platform-msi.c                   |  20 ++++-
 drivers/base/platform.c                       |   2 +
 drivers/irqchip/irq-gic-v3-its-platform-msi.c | 107 ++++++++++++++++++------
 drivers/irqchip/irq-mbigen.c                  | 115 ++++++++++++++++++++++----
 include/acpi/acpi_bus.h                       |   1 +
 include/linux/acpi_iort.h                     |   8 ++
 include/linux/msi.h                           |   1 +
 10 files changed, 305 insertions(+), 75 deletions(-)

-- 
1.7.12.4

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

* [RFC PATCH v2 01/11] irqchip: gicv3-its: platform-msi: refactor its_pmsi_prepare()
  2016-09-14 14:21 ` Hanjun Guo
  (?)
@ 2016-09-14 14:21   ` Hanjun Guo
  -1 siblings, 0 replies; 58+ messages in thread
From: Hanjun Guo @ 2016-09-14 14:21 UTC (permalink / raw)
  To: Rafael J. Wysocki, Marc Zyngier, Lorenzo Pieralisi
  Cc: linux-acpi, linux-arm-kernel, linux-kernel, Thomas Gleixner,
	Bjorn Helgaas, Greg KH, Tomasz Nowicki, Ma Jun, Kefeng Wang,
	Charles Garcia-Tobin, linuxarm, Hanjun Guo

From: Hanjun Guo <hanjun.guo@linaro.org>

Adding ACPI support for platform MSI, we need to retrieve the
dev id in ACPI way instead of device tree, we already have
a well formed function its_pmsi_prepare() to get the dev id
but it's OF dependent, so collect OF related code and put them
into a single function to make its_pmsi_prepare() more friendly
to ACPI later.

Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: Tomasz Nowicki <tn@semihalf.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 drivers/irqchip/irq-gic-v3-its-platform-msi.c | 23 ++++++++++++++++-------
 1 file changed, 16 insertions(+), 7 deletions(-)

diff --git a/drivers/irqchip/irq-gic-v3-its-platform-msi.c b/drivers/irqchip/irq-gic-v3-its-platform-msi.c
index 470b4aa..3c94278 100644
--- a/drivers/irqchip/irq-gic-v3-its-platform-msi.c
+++ b/drivers/irqchip/irq-gic-v3-its-platform-msi.c
@@ -24,15 +24,11 @@ static struct irq_chip its_pmsi_irq_chip = {
 	.name			= "ITS-pMSI",
 };
 
-static int its_pmsi_prepare(struct irq_domain *domain, struct device *dev,
-			    int nvec, msi_alloc_info_t *info)
+static int of_pmsi_get_dev_id(struct irq_domain *domain, struct device *dev,
+				  u32 *dev_id)
 {
-	struct msi_domain_info *msi_info;
-	u32 dev_id;
 	int ret, index = 0;
 
-	msi_info = msi_get_domain_info(domain->parent);
-
 	/* Suck the DeviceID out of the msi-parent property */
 	do {
 		struct of_phandle_args args;
@@ -43,11 +39,24 @@ static int its_pmsi_prepare(struct irq_domain *domain, struct device *dev,
 		if (args.np == irq_domain_get_of_node(domain)) {
 			if (WARN_ON(args.args_count != 1))
 				return -EINVAL;
-			dev_id = args.args[0];
+			*dev_id = args.args[0];
 			break;
 		}
 	} while (!ret);
 
+	return ret;
+}
+
+static int its_pmsi_prepare(struct irq_domain *domain, struct device *dev,
+			    int nvec, msi_alloc_info_t *info)
+{
+	struct msi_domain_info *msi_info;
+	u32 dev_id;
+	int ret;
+
+	msi_info = msi_get_domain_info(domain->parent);
+
+	ret = of_pmsi_get_dev_id(domain, dev, &dev_id);
 	if (ret)
 		return ret;
 
-- 
1.7.12.4


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

* [RFC PATCH v2 01/11] irqchip: gicv3-its: platform-msi: refactor its_pmsi_prepare()
@ 2016-09-14 14:21   ` Hanjun Guo
  0 siblings, 0 replies; 58+ messages in thread
From: Hanjun Guo @ 2016-09-14 14:21 UTC (permalink / raw)
  To: Rafael J. Wysocki, Marc Zyngier, Lorenzo Pieralisi
  Cc: linux-acpi, linux-arm-kernel, linux-kernel, Thomas Gleixner,
	Bjorn Helgaas, Greg KH, Tomasz Nowicki, Ma Jun, Kefeng Wang,
	Charles Garcia-Tobin, linuxarm, Hanjun Guo

From: Hanjun Guo <hanjun.guo@linaro.org>

Adding ACPI support for platform MSI, we need to retrieve the
dev id in ACPI way instead of device tree, we already have
a well formed function its_pmsi_prepare() to get the dev id
but it's OF dependent, so collect OF related code and put them
into a single function to make its_pmsi_prepare() more friendly
to ACPI later.

Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: Tomasz Nowicki <tn@semihalf.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 drivers/irqchip/irq-gic-v3-its-platform-msi.c | 23 ++++++++++++++++-------
 1 file changed, 16 insertions(+), 7 deletions(-)

diff --git a/drivers/irqchip/irq-gic-v3-its-platform-msi.c b/drivers/irqchip/irq-gic-v3-its-platform-msi.c
index 470b4aa..3c94278 100644
--- a/drivers/irqchip/irq-gic-v3-its-platform-msi.c
+++ b/drivers/irqchip/irq-gic-v3-its-platform-msi.c
@@ -24,15 +24,11 @@ static struct irq_chip its_pmsi_irq_chip = {
 	.name			= "ITS-pMSI",
 };
 
-static int its_pmsi_prepare(struct irq_domain *domain, struct device *dev,
-			    int nvec, msi_alloc_info_t *info)
+static int of_pmsi_get_dev_id(struct irq_domain *domain, struct device *dev,
+				  u32 *dev_id)
 {
-	struct msi_domain_info *msi_info;
-	u32 dev_id;
 	int ret, index = 0;
 
-	msi_info = msi_get_domain_info(domain->parent);
-
 	/* Suck the DeviceID out of the msi-parent property */
 	do {
 		struct of_phandle_args args;
@@ -43,11 +39,24 @@ static int its_pmsi_prepare(struct irq_domain *domain, struct device *dev,
 		if (args.np == irq_domain_get_of_node(domain)) {
 			if (WARN_ON(args.args_count != 1))
 				return -EINVAL;
-			dev_id = args.args[0];
+			*dev_id = args.args[0];
 			break;
 		}
 	} while (!ret);
 
+	return ret;
+}
+
+static int its_pmsi_prepare(struct irq_domain *domain, struct device *dev,
+			    int nvec, msi_alloc_info_t *info)
+{
+	struct msi_domain_info *msi_info;
+	u32 dev_id;
+	int ret;
+
+	msi_info = msi_get_domain_info(domain->parent);
+
+	ret = of_pmsi_get_dev_id(domain, dev, &dev_id);
 	if (ret)
 		return ret;
 
-- 
1.7.12.4

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

* [RFC PATCH v2 01/11] irqchip: gicv3-its: platform-msi: refactor its_pmsi_prepare()
@ 2016-09-14 14:21   ` Hanjun Guo
  0 siblings, 0 replies; 58+ messages in thread
From: Hanjun Guo @ 2016-09-14 14:21 UTC (permalink / raw)
  To: linux-arm-kernel

From: Hanjun Guo <hanjun.guo@linaro.org>

Adding ACPI support for platform MSI, we need to retrieve the
dev id in ACPI way instead of device tree, we already have
a well formed function its_pmsi_prepare() to get the dev id
but it's OF dependent, so collect OF related code and put them
into a single function to make its_pmsi_prepare() more friendly
to ACPI later.

Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: Tomasz Nowicki <tn@semihalf.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 drivers/irqchip/irq-gic-v3-its-platform-msi.c | 23 ++++++++++++++++-------
 1 file changed, 16 insertions(+), 7 deletions(-)

diff --git a/drivers/irqchip/irq-gic-v3-its-platform-msi.c b/drivers/irqchip/irq-gic-v3-its-platform-msi.c
index 470b4aa..3c94278 100644
--- a/drivers/irqchip/irq-gic-v3-its-platform-msi.c
+++ b/drivers/irqchip/irq-gic-v3-its-platform-msi.c
@@ -24,15 +24,11 @@ static struct irq_chip its_pmsi_irq_chip = {
 	.name			= "ITS-pMSI",
 };
 
-static int its_pmsi_prepare(struct irq_domain *domain, struct device *dev,
-			    int nvec, msi_alloc_info_t *info)
+static int of_pmsi_get_dev_id(struct irq_domain *domain, struct device *dev,
+				  u32 *dev_id)
 {
-	struct msi_domain_info *msi_info;
-	u32 dev_id;
 	int ret, index = 0;
 
-	msi_info = msi_get_domain_info(domain->parent);
-
 	/* Suck the DeviceID out of the msi-parent property */
 	do {
 		struct of_phandle_args args;
@@ -43,11 +39,24 @@ static int its_pmsi_prepare(struct irq_domain *domain, struct device *dev,
 		if (args.np == irq_domain_get_of_node(domain)) {
 			if (WARN_ON(args.args_count != 1))
 				return -EINVAL;
-			dev_id = args.args[0];
+			*dev_id = args.args[0];
 			break;
 		}
 	} while (!ret);
 
+	return ret;
+}
+
+static int its_pmsi_prepare(struct irq_domain *domain, struct device *dev,
+			    int nvec, msi_alloc_info_t *info)
+{
+	struct msi_domain_info *msi_info;
+	u32 dev_id;
+	int ret;
+
+	msi_info = msi_get_domain_info(domain->parent);
+
+	ret = of_pmsi_get_dev_id(domain, dev, &dev_id);
 	if (ret)
 		return ret;
 
-- 
1.7.12.4

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

* [RFC PATCH v2 02/11] ACPI: platform-msi: retrieve dev id from IORT
  2016-09-14 14:21 ` Hanjun Guo
  (?)
@ 2016-09-14 14:21   ` Hanjun Guo
  -1 siblings, 0 replies; 58+ messages in thread
From: Hanjun Guo @ 2016-09-14 14:21 UTC (permalink / raw)
  To: Rafael J. Wysocki, Marc Zyngier, Lorenzo Pieralisi
  Cc: linux-acpi, linux-arm-kernel, linux-kernel, Thomas Gleixner,
	Bjorn Helgaas, Greg KH, Tomasz Nowicki, Ma Jun, Kefeng Wang,
	Charles Garcia-Tobin, linuxarm, Hanjun Guo

From: Hanjun Guo <hanjun.guo@linaro.org>

For devices connecting to ITS, it needs dev id to identify
itself, and this dev id is represented in the IORT table in
named componant node [1] for platform devices, so in this
patch we will scan the IORT to retrieve device's dev id.

Introduce iort_pmsi_get_dev_id() with pointer dev passed
in for that purpose.

[1]: https://static.docs.arm.com/den0049/b/DEN0049B_IO_Remapping_Table.pdf

Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: Tomasz Nowicki <tn@semihalf.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 drivers/acpi/arm64/iort.c                     | 26 ++++++++++++++++++++++++++
 drivers/irqchip/irq-gic-v3-its-platform-msi.c |  4 +++-
 include/linux/acpi_iort.h                     |  8 ++++++++
 3 files changed, 37 insertions(+), 1 deletion(-)

diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
index cee82d4..13a1905 100644
--- a/drivers/acpi/arm64/iort.c
+++ b/drivers/acpi/arm64/iort.c
@@ -408,6 +408,32 @@ u32 iort_msi_map_rid(struct device *dev, u32 req_id)
 }
 
 /**
+ * iort_pmsi_get_dev_id() - Get the device id for a device
+ * @dev: The device for which the mapping is to be done.
+ * @dev_id: The device ID found.
+ *
+ * Returns: 0 for successful find a dev id, errors otherwise
+ */
+int iort_pmsi_get_dev_id(struct device *dev, u32 *dev_id)
+{
+	struct acpi_iort_node *node;
+
+	if (!iort_table)
+		return -ENODEV;
+
+	node = iort_find_dev_node(dev);
+	if (!node) {
+		dev_err(dev, "can't find related IORT node\n");
+		return -ENODEV;
+	}
+
+	if( !iort_node_get_id(node, dev_id, IORT_MSI_TYPE, 0))
+		return -ENODEV;
+
+	return 0;
+}
+
+/**
  * iort_dev_find_its_id() - Find the ITS identifier for a device
  * @dev: The device.
  * @idx: Index of the ITS identifier list.
diff --git a/drivers/irqchip/irq-gic-v3-its-platform-msi.c b/drivers/irqchip/irq-gic-v3-its-platform-msi.c
index 3c94278..3646c23 100644
--- a/drivers/irqchip/irq-gic-v3-its-platform-msi.c
+++ b/drivers/irqchip/irq-gic-v3-its-platform-msi.c
@@ -16,6 +16,7 @@
  */
 
 #include <linux/device.h>
+#include <linux/acpi_iort.h>
 #include <linux/msi.h>
 #include <linux/of.h>
 #include <linux/of_irq.h>
@@ -56,7 +57,8 @@ static int its_pmsi_prepare(struct irq_domain *domain, struct device *dev,
 
 	msi_info = msi_get_domain_info(domain->parent);
 
-	ret = of_pmsi_get_dev_id(domain, dev, &dev_id);
+	ret = dev->of_node ? of_pmsi_get_dev_id(domain, dev, &dev_id) :
+		iort_pmsi_get_dev_id(dev, &dev_id);
 	if (ret)
 		return ret;
 
diff --git a/include/linux/acpi_iort.h b/include/linux/acpi_iort.h
index 167649a..bfaf75f 100644
--- a/include/linux/acpi_iort.h
+++ b/include/linux/acpi_iort.h
@@ -32,6 +32,7 @@ struct fwnode_handle *iort_find_domain_token(int trans_id);
 #ifdef CONFIG_ACPI_IORT
 void acpi_iort_init(void);
 u32 iort_msi_map_rid(struct device *dev, u32 req_id);
+int iort_pmsi_get_dev_id(struct device *dev, u32 *dev_id);
 struct irq_domain *iort_get_device_domain(struct device *dev, u32 req_id);
 int iort_set_fwnode(struct acpi_iort_node *iort_node,
 		    struct fwnode_handle *fwnode);
@@ -42,9 +43,16 @@ const struct iommu_ops *iort_iommu_configure(struct device *dev);
 static inline void acpi_iort_init(void) { }
 static inline u32 iort_msi_map_rid(struct device *dev, u32 req_id)
 { return req_id; }
+
 static inline struct irq_domain *iort_get_device_domain(struct device *dev,
 							u32 req_id)
 { return NULL; }
+
+static inline int iort_pmsi_get_dev_id(struct device *dev, u32 *dev_id)
+{
+	return -ENODEV;
+}
+
 static inline int iort_set_fwnode(struct acpi_iort_node *iort_node,
 				  struct fwnode_handle *fwnode)
 { return -ENODEV; }
-- 
1.7.12.4

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

* [RFC PATCH v2 02/11] ACPI: platform-msi: retrieve dev id from IORT
@ 2016-09-14 14:21   ` Hanjun Guo
  0 siblings, 0 replies; 58+ messages in thread
From: Hanjun Guo @ 2016-09-14 14:21 UTC (permalink / raw)
  To: Rafael J. Wysocki, Marc Zyngier, Lorenzo Pieralisi
  Cc: linux-acpi, linux-arm-kernel, linux-kernel, Thomas Gleixner,
	Bjorn Helgaas, Greg KH, Tomasz Nowicki, Ma Jun, Kefeng Wang,
	Charles Garcia-Tobin, linuxarm, Hanjun Guo

From: Hanjun Guo <hanjun.guo@linaro.org>

For devices connecting to ITS, it needs dev id to identify
itself, and this dev id is represented in the IORT table in
named componant node [1] for platform devices, so in this
patch we will scan the IORT to retrieve device's dev id.

Introduce iort_pmsi_get_dev_id() with pointer dev passed
in for that purpose.

[1]: https://static.docs.arm.com/den0049/b/DEN0049B_IO_Remapping_Table.pdf

Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: Tomasz Nowicki <tn@semihalf.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 drivers/acpi/arm64/iort.c                     | 26 ++++++++++++++++++++++++++
 drivers/irqchip/irq-gic-v3-its-platform-msi.c |  4 +++-
 include/linux/acpi_iort.h                     |  8 ++++++++
 3 files changed, 37 insertions(+), 1 deletion(-)

diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
index cee82d4..13a1905 100644
--- a/drivers/acpi/arm64/iort.c
+++ b/drivers/acpi/arm64/iort.c
@@ -408,6 +408,32 @@ u32 iort_msi_map_rid(struct device *dev, u32 req_id)
 }
 
 /**
+ * iort_pmsi_get_dev_id() - Get the device id for a device
+ * @dev: The device for which the mapping is to be done.
+ * @dev_id: The device ID found.
+ *
+ * Returns: 0 for successful find a dev id, errors otherwise
+ */
+int iort_pmsi_get_dev_id(struct device *dev, u32 *dev_id)
+{
+	struct acpi_iort_node *node;
+
+	if (!iort_table)
+		return -ENODEV;
+
+	node = iort_find_dev_node(dev);
+	if (!node) {
+		dev_err(dev, "can't find related IORT node\n");
+		return -ENODEV;
+	}
+
+	if( !iort_node_get_id(node, dev_id, IORT_MSI_TYPE, 0))
+		return -ENODEV;
+
+	return 0;
+}
+
+/**
  * iort_dev_find_its_id() - Find the ITS identifier for a device
  * @dev: The device.
  * @idx: Index of the ITS identifier list.
diff --git a/drivers/irqchip/irq-gic-v3-its-platform-msi.c b/drivers/irqchip/irq-gic-v3-its-platform-msi.c
index 3c94278..3646c23 100644
--- a/drivers/irqchip/irq-gic-v3-its-platform-msi.c
+++ b/drivers/irqchip/irq-gic-v3-its-platform-msi.c
@@ -16,6 +16,7 @@
  */
 
 #include <linux/device.h>
+#include <linux/acpi_iort.h>
 #include <linux/msi.h>
 #include <linux/of.h>
 #include <linux/of_irq.h>
@@ -56,7 +57,8 @@ static int its_pmsi_prepare(struct irq_domain *domain, struct device *dev,
 
 	msi_info = msi_get_domain_info(domain->parent);
 
-	ret = of_pmsi_get_dev_id(domain, dev, &dev_id);
+	ret = dev->of_node ? of_pmsi_get_dev_id(domain, dev, &dev_id) :
+		iort_pmsi_get_dev_id(dev, &dev_id);
 	if (ret)
 		return ret;
 
diff --git a/include/linux/acpi_iort.h b/include/linux/acpi_iort.h
index 167649a..bfaf75f 100644
--- a/include/linux/acpi_iort.h
+++ b/include/linux/acpi_iort.h
@@ -32,6 +32,7 @@ struct fwnode_handle *iort_find_domain_token(int trans_id);
 #ifdef CONFIG_ACPI_IORT
 void acpi_iort_init(void);
 u32 iort_msi_map_rid(struct device *dev, u32 req_id);
+int iort_pmsi_get_dev_id(struct device *dev, u32 *dev_id);
 struct irq_domain *iort_get_device_domain(struct device *dev, u32 req_id);
 int iort_set_fwnode(struct acpi_iort_node *iort_node,
 		    struct fwnode_handle *fwnode);
@@ -42,9 +43,16 @@ const struct iommu_ops *iort_iommu_configure(struct device *dev);
 static inline void acpi_iort_init(void) { }
 static inline u32 iort_msi_map_rid(struct device *dev, u32 req_id)
 { return req_id; }
+
 static inline struct irq_domain *iort_get_device_domain(struct device *dev,
 							u32 req_id)
 { return NULL; }
+
+static inline int iort_pmsi_get_dev_id(struct device *dev, u32 *dev_id)
+{
+	return -ENODEV;
+}
+
 static inline int iort_set_fwnode(struct acpi_iort_node *iort_node,
 				  struct fwnode_handle *fwnode)
 { return -ENODEV; }
-- 
1.7.12.4

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

* [RFC PATCH v2 02/11] ACPI: platform-msi: retrieve dev id from IORT
@ 2016-09-14 14:21   ` Hanjun Guo
  0 siblings, 0 replies; 58+ messages in thread
From: Hanjun Guo @ 2016-09-14 14:21 UTC (permalink / raw)
  To: linux-arm-kernel

From: Hanjun Guo <hanjun.guo@linaro.org>

For devices connecting to ITS, it needs dev id to identify
itself, and this dev id is represented in the IORT table in
named componant node [1] for platform devices, so in this
patch we will scan the IORT to retrieve device's dev id.

Introduce iort_pmsi_get_dev_id() with pointer dev passed
in for that purpose.

[1]: https://static.docs.arm.com/den0049/b/DEN0049B_IO_Remapping_Table.pdf

Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: Tomasz Nowicki <tn@semihalf.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 drivers/acpi/arm64/iort.c                     | 26 ++++++++++++++++++++++++++
 drivers/irqchip/irq-gic-v3-its-platform-msi.c |  4 +++-
 include/linux/acpi_iort.h                     |  8 ++++++++
 3 files changed, 37 insertions(+), 1 deletion(-)

diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
index cee82d4..13a1905 100644
--- a/drivers/acpi/arm64/iort.c
+++ b/drivers/acpi/arm64/iort.c
@@ -408,6 +408,32 @@ u32 iort_msi_map_rid(struct device *dev, u32 req_id)
 }
 
 /**
+ * iort_pmsi_get_dev_id() - Get the device id for a device
+ * @dev: The device for which the mapping is to be done.
+ * @dev_id: The device ID found.
+ *
+ * Returns: 0 for successful find a dev id, errors otherwise
+ */
+int iort_pmsi_get_dev_id(struct device *dev, u32 *dev_id)
+{
+	struct acpi_iort_node *node;
+
+	if (!iort_table)
+		return -ENODEV;
+
+	node = iort_find_dev_node(dev);
+	if (!node) {
+		dev_err(dev, "can't find related IORT node\n");
+		return -ENODEV;
+	}
+
+	if( !iort_node_get_id(node, dev_id, IORT_MSI_TYPE, 0))
+		return -ENODEV;
+
+	return 0;
+}
+
+/**
  * iort_dev_find_its_id() - Find the ITS identifier for a device
  * @dev: The device.
  * @idx: Index of the ITS identifier list.
diff --git a/drivers/irqchip/irq-gic-v3-its-platform-msi.c b/drivers/irqchip/irq-gic-v3-its-platform-msi.c
index 3c94278..3646c23 100644
--- a/drivers/irqchip/irq-gic-v3-its-platform-msi.c
+++ b/drivers/irqchip/irq-gic-v3-its-platform-msi.c
@@ -16,6 +16,7 @@
  */
 
 #include <linux/device.h>
+#include <linux/acpi_iort.h>
 #include <linux/msi.h>
 #include <linux/of.h>
 #include <linux/of_irq.h>
@@ -56,7 +57,8 @@ static int its_pmsi_prepare(struct irq_domain *domain, struct device *dev,
 
 	msi_info = msi_get_domain_info(domain->parent);
 
-	ret = of_pmsi_get_dev_id(domain, dev, &dev_id);
+	ret = dev->of_node ? of_pmsi_get_dev_id(domain, dev, &dev_id) :
+		iort_pmsi_get_dev_id(dev, &dev_id);
 	if (ret)
 		return ret;
 
diff --git a/include/linux/acpi_iort.h b/include/linux/acpi_iort.h
index 167649a..bfaf75f 100644
--- a/include/linux/acpi_iort.h
+++ b/include/linux/acpi_iort.h
@@ -32,6 +32,7 @@ struct fwnode_handle *iort_find_domain_token(int trans_id);
 #ifdef CONFIG_ACPI_IORT
 void acpi_iort_init(void);
 u32 iort_msi_map_rid(struct device *dev, u32 req_id);
+int iort_pmsi_get_dev_id(struct device *dev, u32 *dev_id);
 struct irq_domain *iort_get_device_domain(struct device *dev, u32 req_id);
 int iort_set_fwnode(struct acpi_iort_node *iort_node,
 		    struct fwnode_handle *fwnode);
@@ -42,9 +43,16 @@ const struct iommu_ops *iort_iommu_configure(struct device *dev);
 static inline void acpi_iort_init(void) { }
 static inline u32 iort_msi_map_rid(struct device *dev, u32 req_id)
 { return req_id; }
+
 static inline struct irq_domain *iort_get_device_domain(struct device *dev,
 							u32 req_id)
 { return NULL; }
+
+static inline int iort_pmsi_get_dev_id(struct device *dev, u32 *dev_id)
+{
+	return -ENODEV;
+}
+
 static inline int iort_set_fwnode(struct acpi_iort_node *iort_node,
 				  struct fwnode_handle *fwnode)
 { return -ENODEV; }
-- 
1.7.12.4

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

* [RFC PATCH v2 03/11] irqchip: gicv3-its: platform-msi: refactor its_pmsi_init() to prepare for ACPI
  2016-09-14 14:21 ` Hanjun Guo
  (?)
@ 2016-09-14 14:21   ` Hanjun Guo
  -1 siblings, 0 replies; 58+ messages in thread
From: Hanjun Guo @ 2016-09-14 14:21 UTC (permalink / raw)
  To: Rafael J. Wysocki, Marc Zyngier, Lorenzo Pieralisi
  Cc: linux-acpi, linux-arm-kernel, linux-kernel, Thomas Gleixner,
	Bjorn Helgaas, Greg KH, Tomasz Nowicki, Ma Jun, Kefeng Wang,
	Charles Garcia-Tobin, linuxarm, Hanjun Guo

From: Hanjun Guo <hanjun.guo@linaro.org>

Introduce its_pmsi_init_one() to refactor the code to isolate
ACPI&DT common code to prepare for ACPI later.

Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Tomasz Nowicki <tn@semihalf.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 drivers/irqchip/irq-gic-v3-its-platform-msi.c | 45 ++++++++++++++++-----------
 1 file changed, 27 insertions(+), 18 deletions(-)

diff --git a/drivers/irqchip/irq-gic-v3-its-platform-msi.c b/drivers/irqchip/irq-gic-v3-its-platform-msi.c
index 3646c23..a80ecd7 100644
--- a/drivers/irqchip/irq-gic-v3-its-platform-msi.c
+++ b/drivers/irqchip/irq-gic-v3-its-platform-msi.c
@@ -84,34 +84,43 @@ static struct of_device_id its_device_id[] = {
 	{},
 };
 
-static int __init its_pmsi_init(void)
+static int __init its_pmsi_init_one(struct fwnode_handle *fwnode,
+				const char *name)
 {
-	struct device_node *np;
 	struct irq_domain *parent;
 
+	parent = irq_find_matching_fwnode(fwnode, DOMAIN_BUS_NEXUS);
+	if (!parent || !msi_get_domain_info(parent)) {
+		pr_err("%s: unable to locate ITS domain\n", name);
+		return -ENXIO;
+	}
+
+	if (!platform_msi_create_irq_domain(fwnode, &its_pmsi_domain_info,
+					    parent)) {
+		pr_err("%s: unable to create platform domain\n", name);
+		return -ENXIO;
+	}
+
+	pr_info("Platform MSI: %s domain created\n", name);
+	return 0;
+}
+
+static void __init its_pmsi_of_init(void)
+{
+	struct device_node *np;
+
 	for (np = of_find_matching_node(NULL, its_device_id); np;
 	     np = of_find_matching_node(np, its_device_id)) {
 		if (!of_property_read_bool(np, "msi-controller"))
 			continue;
 
-		parent = irq_find_matching_host(np, DOMAIN_BUS_NEXUS);
-		if (!parent || !msi_get_domain_info(parent)) {
-			pr_err("%s: unable to locate ITS domain\n",
-			       np->full_name);
-			continue;
-		}
-
-		if (!platform_msi_create_irq_domain(of_node_to_fwnode(np),
-						    &its_pmsi_domain_info,
-						    parent)) {
-			pr_err("%s: unable to create platform domain\n",
-			       np->full_name);
-			continue;
-		}
-
-		pr_info("Platform MSI: %s domain created\n", np->full_name);
+		its_pmsi_init_one(of_node_to_fwnode(np), np->full_name);
 	}
+}
 
+static int __init its_pmsi_init(void)
+{
+	its_pmsi_of_init();
 	return 0;
 }
 early_initcall(its_pmsi_init);
-- 
1.7.12.4

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

* [RFC PATCH v2 03/11] irqchip: gicv3-its: platform-msi: refactor its_pmsi_init() to prepare for ACPI
@ 2016-09-14 14:21   ` Hanjun Guo
  0 siblings, 0 replies; 58+ messages in thread
From: Hanjun Guo @ 2016-09-14 14:21 UTC (permalink / raw)
  To: Rafael J. Wysocki, Marc Zyngier, Lorenzo Pieralisi
  Cc: linux-acpi, linux-arm-kernel, linux-kernel, Thomas Gleixner,
	Bjorn Helgaas, Greg KH, Tomasz Nowicki, Ma Jun, Kefeng Wang,
	Charles Garcia-Tobin, linuxarm, Hanjun Guo

From: Hanjun Guo <hanjun.guo@linaro.org>

Introduce its_pmsi_init_one() to refactor the code to isolate
ACPI&DT common code to prepare for ACPI later.

Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Tomasz Nowicki <tn@semihalf.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 drivers/irqchip/irq-gic-v3-its-platform-msi.c | 45 ++++++++++++++++-----------
 1 file changed, 27 insertions(+), 18 deletions(-)

diff --git a/drivers/irqchip/irq-gic-v3-its-platform-msi.c b/drivers/irqchip/irq-gic-v3-its-platform-msi.c
index 3646c23..a80ecd7 100644
--- a/drivers/irqchip/irq-gic-v3-its-platform-msi.c
+++ b/drivers/irqchip/irq-gic-v3-its-platform-msi.c
@@ -84,34 +84,43 @@ static struct of_device_id its_device_id[] = {
 	{},
 };
 
-static int __init its_pmsi_init(void)
+static int __init its_pmsi_init_one(struct fwnode_handle *fwnode,
+				const char *name)
 {
-	struct device_node *np;
 	struct irq_domain *parent;
 
+	parent = irq_find_matching_fwnode(fwnode, DOMAIN_BUS_NEXUS);
+	if (!parent || !msi_get_domain_info(parent)) {
+		pr_err("%s: unable to locate ITS domain\n", name);
+		return -ENXIO;
+	}
+
+	if (!platform_msi_create_irq_domain(fwnode, &its_pmsi_domain_info,
+					    parent)) {
+		pr_err("%s: unable to create platform domain\n", name);
+		return -ENXIO;
+	}
+
+	pr_info("Platform MSI: %s domain created\n", name);
+	return 0;
+}
+
+static void __init its_pmsi_of_init(void)
+{
+	struct device_node *np;
+
 	for (np = of_find_matching_node(NULL, its_device_id); np;
 	     np = of_find_matching_node(np, its_device_id)) {
 		if (!of_property_read_bool(np, "msi-controller"))
 			continue;
 
-		parent = irq_find_matching_host(np, DOMAIN_BUS_NEXUS);
-		if (!parent || !msi_get_domain_info(parent)) {
-			pr_err("%s: unable to locate ITS domain\n",
-			       np->full_name);
-			continue;
-		}
-
-		if (!platform_msi_create_irq_domain(of_node_to_fwnode(np),
-						    &its_pmsi_domain_info,
-						    parent)) {
-			pr_err("%s: unable to create platform domain\n",
-			       np->full_name);
-			continue;
-		}
-
-		pr_info("Platform MSI: %s domain created\n", np->full_name);
+		its_pmsi_init_one(of_node_to_fwnode(np), np->full_name);
 	}
+}
 
+static int __init its_pmsi_init(void)
+{
+	its_pmsi_of_init();
 	return 0;
 }
 early_initcall(its_pmsi_init);
-- 
1.7.12.4

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

* [RFC PATCH v2 03/11] irqchip: gicv3-its: platform-msi: refactor its_pmsi_init() to prepare for ACPI
@ 2016-09-14 14:21   ` Hanjun Guo
  0 siblings, 0 replies; 58+ messages in thread
From: Hanjun Guo @ 2016-09-14 14:21 UTC (permalink / raw)
  To: linux-arm-kernel

From: Hanjun Guo <hanjun.guo@linaro.org>

Introduce its_pmsi_init_one() to refactor the code to isolate
ACPI&DT common code to prepare for ACPI later.

Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Tomasz Nowicki <tn@semihalf.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 drivers/irqchip/irq-gic-v3-its-platform-msi.c | 45 ++++++++++++++++-----------
 1 file changed, 27 insertions(+), 18 deletions(-)

diff --git a/drivers/irqchip/irq-gic-v3-its-platform-msi.c b/drivers/irqchip/irq-gic-v3-its-platform-msi.c
index 3646c23..a80ecd7 100644
--- a/drivers/irqchip/irq-gic-v3-its-platform-msi.c
+++ b/drivers/irqchip/irq-gic-v3-its-platform-msi.c
@@ -84,34 +84,43 @@ static struct of_device_id its_device_id[] = {
 	{},
 };
 
-static int __init its_pmsi_init(void)
+static int __init its_pmsi_init_one(struct fwnode_handle *fwnode,
+				const char *name)
 {
-	struct device_node *np;
 	struct irq_domain *parent;
 
+	parent = irq_find_matching_fwnode(fwnode, DOMAIN_BUS_NEXUS);
+	if (!parent || !msi_get_domain_info(parent)) {
+		pr_err("%s: unable to locate ITS domain\n", name);
+		return -ENXIO;
+	}
+
+	if (!platform_msi_create_irq_domain(fwnode, &its_pmsi_domain_info,
+					    parent)) {
+		pr_err("%s: unable to create platform domain\n", name);
+		return -ENXIO;
+	}
+
+	pr_info("Platform MSI: %s domain created\n", name);
+	return 0;
+}
+
+static void __init its_pmsi_of_init(void)
+{
+	struct device_node *np;
+
 	for (np = of_find_matching_node(NULL, its_device_id); np;
 	     np = of_find_matching_node(np, its_device_id)) {
 		if (!of_property_read_bool(np, "msi-controller"))
 			continue;
 
-		parent = irq_find_matching_host(np, DOMAIN_BUS_NEXUS);
-		if (!parent || !msi_get_domain_info(parent)) {
-			pr_err("%s: unable to locate ITS domain\n",
-			       np->full_name);
-			continue;
-		}
-
-		if (!platform_msi_create_irq_domain(of_node_to_fwnode(np),
-						    &its_pmsi_domain_info,
-						    parent)) {
-			pr_err("%s: unable to create platform domain\n",
-			       np->full_name);
-			continue;
-		}
-
-		pr_info("Platform MSI: %s domain created\n", np->full_name);
+		its_pmsi_init_one(of_node_to_fwnode(np), np->full_name);
 	}
+}
 
+static int __init its_pmsi_init(void)
+{
+	its_pmsi_of_init();
 	return 0;
 }
 early_initcall(its_pmsi_init);
-- 
1.7.12.4

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

* [RFC PATCH v2 04/11] irqchip: gicv3-its: platform-msi: scan MADT to create platform msi domain
  2016-09-14 14:21 ` Hanjun Guo
  (?)
@ 2016-09-14 14:21   ` Hanjun Guo
  -1 siblings, 0 replies; 58+ messages in thread
From: Hanjun Guo @ 2016-09-14 14:21 UTC (permalink / raw)
  To: Rafael J. Wysocki, Marc Zyngier, Lorenzo Pieralisi
  Cc: linux-acpi, linux-arm-kernel, linux-kernel, Thomas Gleixner,
	Bjorn Helgaas, Greg KH, Tomasz Nowicki, Ma Jun, Kefeng Wang,
	Charles Garcia-Tobin, linuxarm, Hanjun Guo

From: Hanjun Guo <hanjun.guo@linaro.org>

With the introduction of its_pmsi_init_one(), we can add some code
on top for ACPI support of platform MSI.

We are scanning the MADT table to get the ITS entry(ies), then use
the information to create the platform msi domain for devices connect
to it, just like the PCI MSI for ITS did.

Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Tomasz Nowicki <tn@semihalf.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 drivers/irqchip/irq-gic-v3-its-platform-msi.c | 37 +++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)

diff --git a/drivers/irqchip/irq-gic-v3-its-platform-msi.c b/drivers/irqchip/irq-gic-v3-its-platform-msi.c
index a80ecd7..e9dade9 100644
--- a/drivers/irqchip/irq-gic-v3-its-platform-msi.c
+++ b/drivers/irqchip/irq-gic-v3-its-platform-msi.c
@@ -15,6 +15,7 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include <linux/acpi.h>
 #include <linux/device.h>
 #include <linux/acpi_iort.h>
 #include <linux/msi.h>
@@ -105,6 +106,41 @@ static int __init its_pmsi_init_one(struct fwnode_handle *fwnode,
 	return 0;
 }
 
+#ifdef CONFIG_ACPI
+static int __init
+its_pmsi_parse_madt(struct acpi_subtable_header *header,
+			const unsigned long end)
+{
+	struct acpi_madt_generic_translator *its_entry;
+	struct fwnode_handle *domain_handle;
+	const char *node_name;
+	int err = -ENXIO;
+
+	its_entry = (struct acpi_madt_generic_translator *)header;
+	node_name = kasprintf(GFP_KERNEL, "ITS@0x%lx",
+			      (long)its_entry->base_address);
+	domain_handle = iort_find_domain_token(its_entry->translation_id);
+	if (!domain_handle) {
+		pr_err("%s: Unable to locate ITS domain handle\n", node_name);
+		goto out;
+	}
+
+	err = its_pmsi_init_one(domain_handle, node_name);
+
+out:
+	kfree(node_name);
+	return err;
+}
+
+static void __init its_acpi_pmsi_init(void)
+{
+	acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_TRANSLATOR,
+			      its_pmsi_parse_madt, 0);
+}
+#else
+static inline void its_acpi_pmsi_init(void) { }
+#endif
+
 static void __init its_pmsi_of_init(void)
 {
 	struct device_node *np;
@@ -121,6 +157,7 @@ static void __init its_pmsi_of_init(void)
 static int __init its_pmsi_init(void)
 {
 	its_pmsi_of_init();
+	its_acpi_pmsi_init();
 	return 0;
 }
 early_initcall(its_pmsi_init);
-- 
1.7.12.4

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

* [RFC PATCH v2 04/11] irqchip: gicv3-its: platform-msi: scan MADT to create platform msi domain
@ 2016-09-14 14:21   ` Hanjun Guo
  0 siblings, 0 replies; 58+ messages in thread
From: Hanjun Guo @ 2016-09-14 14:21 UTC (permalink / raw)
  To: Rafael J. Wysocki, Marc Zyngier, Lorenzo Pieralisi
  Cc: linux-acpi, linux-arm-kernel, linux-kernel, Thomas Gleixner,
	Bjorn Helgaas, Greg KH, Tomasz Nowicki, Ma Jun, Kefeng Wang,
	Charles Garcia-Tobin, linuxarm, Hanjun Guo

From: Hanjun Guo <hanjun.guo@linaro.org>

With the introduction of its_pmsi_init_one(), we can add some code
on top for ACPI support of platform MSI.

We are scanning the MADT table to get the ITS entry(ies), then use
the information to create the platform msi domain for devices connect
to it, just like the PCI MSI for ITS did.

Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Tomasz Nowicki <tn@semihalf.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 drivers/irqchip/irq-gic-v3-its-platform-msi.c | 37 +++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)

diff --git a/drivers/irqchip/irq-gic-v3-its-platform-msi.c b/drivers/irqchip/irq-gic-v3-its-platform-msi.c
index a80ecd7..e9dade9 100644
--- a/drivers/irqchip/irq-gic-v3-its-platform-msi.c
+++ b/drivers/irqchip/irq-gic-v3-its-platform-msi.c
@@ -15,6 +15,7 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include <linux/acpi.h>
 #include <linux/device.h>
 #include <linux/acpi_iort.h>
 #include <linux/msi.h>
@@ -105,6 +106,41 @@ static int __init its_pmsi_init_one(struct fwnode_handle *fwnode,
 	return 0;
 }
 
+#ifdef CONFIG_ACPI
+static int __init
+its_pmsi_parse_madt(struct acpi_subtable_header *header,
+			const unsigned long end)
+{
+	struct acpi_madt_generic_translator *its_entry;
+	struct fwnode_handle *domain_handle;
+	const char *node_name;
+	int err = -ENXIO;
+
+	its_entry = (struct acpi_madt_generic_translator *)header;
+	node_name = kasprintf(GFP_KERNEL, "ITS@0x%lx",
+			      (long)its_entry->base_address);
+	domain_handle = iort_find_domain_token(its_entry->translation_id);
+	if (!domain_handle) {
+		pr_err("%s: Unable to locate ITS domain handle\n", node_name);
+		goto out;
+	}
+
+	err = its_pmsi_init_one(domain_handle, node_name);
+
+out:
+	kfree(node_name);
+	return err;
+}
+
+static void __init its_acpi_pmsi_init(void)
+{
+	acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_TRANSLATOR,
+			      its_pmsi_parse_madt, 0);
+}
+#else
+static inline void its_acpi_pmsi_init(void) { }
+#endif
+
 static void __init its_pmsi_of_init(void)
 {
 	struct device_node *np;
@@ -121,6 +157,7 @@ static void __init its_pmsi_of_init(void)
 static int __init its_pmsi_init(void)
 {
 	its_pmsi_of_init();
+	its_acpi_pmsi_init();
 	return 0;
 }
 early_initcall(its_pmsi_init);
-- 
1.7.12.4

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

* [RFC PATCH v2 04/11] irqchip: gicv3-its: platform-msi: scan MADT to create platform msi domain
@ 2016-09-14 14:21   ` Hanjun Guo
  0 siblings, 0 replies; 58+ messages in thread
From: Hanjun Guo @ 2016-09-14 14:21 UTC (permalink / raw)
  To: linux-arm-kernel

From: Hanjun Guo <hanjun.guo@linaro.org>

With the introduction of its_pmsi_init_one(), we can add some code
on top for ACPI support of platform MSI.

We are scanning the MADT table to get the ITS entry(ies), then use
the information to create the platform msi domain for devices connect
to it, just like the PCI MSI for ITS did.

Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Tomasz Nowicki <tn@semihalf.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 drivers/irqchip/irq-gic-v3-its-platform-msi.c | 37 +++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)

diff --git a/drivers/irqchip/irq-gic-v3-its-platform-msi.c b/drivers/irqchip/irq-gic-v3-its-platform-msi.c
index a80ecd7..e9dade9 100644
--- a/drivers/irqchip/irq-gic-v3-its-platform-msi.c
+++ b/drivers/irqchip/irq-gic-v3-its-platform-msi.c
@@ -15,6 +15,7 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include <linux/acpi.h>
 #include <linux/device.h>
 #include <linux/acpi_iort.h>
 #include <linux/msi.h>
@@ -105,6 +106,41 @@ static int __init its_pmsi_init_one(struct fwnode_handle *fwnode,
 	return 0;
 }
 
+#ifdef CONFIG_ACPI
+static int __init
+its_pmsi_parse_madt(struct acpi_subtable_header *header,
+			const unsigned long end)
+{
+	struct acpi_madt_generic_translator *its_entry;
+	struct fwnode_handle *domain_handle;
+	const char *node_name;
+	int err = -ENXIO;
+
+	its_entry = (struct acpi_madt_generic_translator *)header;
+	node_name = kasprintf(GFP_KERNEL, "ITS at 0x%lx",
+			      (long)its_entry->base_address);
+	domain_handle = iort_find_domain_token(its_entry->translation_id);
+	if (!domain_handle) {
+		pr_err("%s: Unable to locate ITS domain handle\n", node_name);
+		goto out;
+	}
+
+	err = its_pmsi_init_one(domain_handle, node_name);
+
+out:
+	kfree(node_name);
+	return err;
+}
+
+static void __init its_acpi_pmsi_init(void)
+{
+	acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_TRANSLATOR,
+			      its_pmsi_parse_madt, 0);
+}
+#else
+static inline void its_acpi_pmsi_init(void) { }
+#endif
+
 static void __init its_pmsi_of_init(void)
 {
 	struct device_node *np;
@@ -121,6 +157,7 @@ static void __init its_pmsi_of_init(void)
 static int __init its_pmsi_init(void)
 {
 	its_pmsi_of_init();
+	its_acpi_pmsi_init();
 	return 0;
 }
 early_initcall(its_pmsi_init);
-- 
1.7.12.4

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

* [RFC PATCH v2 05/11] ACPI: platform: setup MSI domain for ACPI based platform device
  2016-09-14 14:21 ` Hanjun Guo
  (?)
@ 2016-09-14 14:21   ` Hanjun Guo
  -1 siblings, 0 replies; 58+ messages in thread
From: Hanjun Guo @ 2016-09-14 14:21 UTC (permalink / raw)
  To: Rafael J. Wysocki, Marc Zyngier, Lorenzo Pieralisi
  Cc: Kefeng Wang, Greg KH, linux-kernel, linuxarm, linux-acpi,
	Hanjun Guo, Tomasz Nowicki, Bjorn Helgaas, Thomas Gleixner,
	Charles Garcia-Tobin, linux-arm-kernel, Ma Jun

From: Hanjun Guo <hanjun.guo@linaro.org>

With the platform msi domain created, we can set up the msi domain
for a platform device when it's probed.

This patch introduces acpi_configure_msi_domain(), which retrieves
the domain from iort and set it to platform device.

As some platform devices such as an irqchip needs the msi irqdomain
to be the interrupt parent domain, we need to get irqdomain before
platform device is probed.

Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Greg KH <gregkh@linuxfoundation.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Bjorn Helgaas <bhelgaas@google.com>
Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: Tomasz Nowicki <tn@semihalf.com>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 drivers/acpi/arm64/iort.c   |  5 ++++-
 drivers/base/platform-msi.c | 15 ++++++++++++++-
 drivers/base/platform.c     |  2 ++
 include/linux/msi.h         |  1 +
 4 files changed, 21 insertions(+), 2 deletions(-)

diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
index 13a1905..bccd3cc 100644
--- a/drivers/acpi/arm64/iort.c
+++ b/drivers/acpi/arm64/iort.c
@@ -478,6 +478,7 @@ struct irq_domain *iort_get_device_domain(struct device *dev, u32 req_id)
 {
 	struct fwnode_handle *handle;
 	int its_id;
+	enum irq_domain_bus_token bus_token;
 
 	if (iort_dev_find_its_id(dev, req_id, 0, &its_id))
 		return NULL;
@@ -486,7 +487,9 @@ struct irq_domain *iort_get_device_domain(struct device *dev, u32 req_id)
 	if (!handle)
 		return NULL;
 
-	return irq_find_matching_fwnode(handle, DOMAIN_BUS_PCI_MSI);
+	bus_token = dev_is_pci(dev) ?
+			DOMAIN_BUS_PCI_MSI : DOMAIN_BUS_PLATFORM_MSI;
+	return irq_find_matching_fwnode(handle, bus_token);
 }
 
 static int __get_pci_rid(struct pci_dev *pdev, u16 alias, void *data)
diff --git a/drivers/base/platform-msi.c b/drivers/base/platform-msi.c
index 279e539..f6eae18 100644
--- a/drivers/base/platform-msi.c
+++ b/drivers/base/platform-msi.c
@@ -17,8 +17,8 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include <linux/acpi_iort.h>
 #include <linux/device.h>
-#include <linux/idr.h>
 #include <linux/irq.h>
 #include <linux/irqdomain.h>
 #include <linux/msi.h>
@@ -416,3 +416,16 @@ int platform_msi_domain_alloc(struct irq_domain *domain, unsigned int virq,
 
 	return err;
 }
+
+int acpi_configure_msi_domain(struct device *dev)
+{
+	struct irq_domain *d = NULL;
+
+	d = iort_get_device_domain(dev, 0);
+	if (d) {
+		dev_set_msi_domain(dev, d);
+		return 0;
+	}
+
+	return -EINVAL;
+}
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index 6482d47..ea01a37 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -24,6 +24,7 @@
 #include <linux/pm_domain.h>
 #include <linux/idr.h>
 #include <linux/acpi.h>
+#include <linux/msi.h>
 #include <linux/clk/clk-conf.h>
 #include <linux/limits.h>
 #include <linux/property.h>
@@ -500,6 +501,7 @@ struct platform_device *platform_device_register_full(
 	pdev->dev.parent = pdevinfo->parent;
 	pdev->dev.fwnode = pdevinfo->fwnode;
 
+	acpi_configure_msi_domain(&pdev->dev);
 	if (pdevinfo->dma_mask) {
 		/*
 		 * This memory isn't freed when the device is put,
diff --git a/include/linux/msi.h b/include/linux/msi.h
index e8c81fb..1e93a78 100644
--- a/include/linux/msi.h
+++ b/include/linux/msi.h
@@ -308,6 +308,7 @@ int platform_msi_domain_alloc(struct irq_domain *domain, unsigned int virq,
 void platform_msi_domain_free(struct irq_domain *domain, unsigned int virq,
 			      unsigned int nvec);
 void *platform_msi_get_host_data(struct irq_domain *domain);
+int acpi_configure_msi_domain(struct device *dev);
 #endif /* CONFIG_GENERIC_MSI_IRQ_DOMAIN */
 
 #ifdef CONFIG_PCI_MSI_IRQ_DOMAIN
-- 
1.7.12.4

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

* [RFC PATCH v2 05/11] ACPI: platform: setup MSI domain for ACPI based platform device
@ 2016-09-14 14:21   ` Hanjun Guo
  0 siblings, 0 replies; 58+ messages in thread
From: Hanjun Guo @ 2016-09-14 14:21 UTC (permalink / raw)
  To: Rafael J. Wysocki, Marc Zyngier, Lorenzo Pieralisi
  Cc: linux-acpi, linux-arm-kernel, linux-kernel, Thomas Gleixner,
	Bjorn Helgaas, Greg KH, Tomasz Nowicki, Ma Jun, Kefeng Wang,
	Charles Garcia-Tobin, linuxarm, Hanjun Guo

From: Hanjun Guo <hanjun.guo@linaro.org>

With the platform msi domain created, we can set up the msi domain
for a platform device when it's probed.

This patch introduces acpi_configure_msi_domain(), which retrieves
the domain from iort and set it to platform device.

As some platform devices such as an irqchip needs the msi irqdomain
to be the interrupt parent domain, we need to get irqdomain before
platform device is probed.

Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Greg KH <gregkh@linuxfoundation.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Bjorn Helgaas <bhelgaas@google.com>
Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: Tomasz Nowicki <tn@semihalf.com>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 drivers/acpi/arm64/iort.c   |  5 ++++-
 drivers/base/platform-msi.c | 15 ++++++++++++++-
 drivers/base/platform.c     |  2 ++
 include/linux/msi.h         |  1 +
 4 files changed, 21 insertions(+), 2 deletions(-)

diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
index 13a1905..bccd3cc 100644
--- a/drivers/acpi/arm64/iort.c
+++ b/drivers/acpi/arm64/iort.c
@@ -478,6 +478,7 @@ struct irq_domain *iort_get_device_domain(struct device *dev, u32 req_id)
 {
 	struct fwnode_handle *handle;
 	int its_id;
+	enum irq_domain_bus_token bus_token;
 
 	if (iort_dev_find_its_id(dev, req_id, 0, &its_id))
 		return NULL;
@@ -486,7 +487,9 @@ struct irq_domain *iort_get_device_domain(struct device *dev, u32 req_id)
 	if (!handle)
 		return NULL;
 
-	return irq_find_matching_fwnode(handle, DOMAIN_BUS_PCI_MSI);
+	bus_token = dev_is_pci(dev) ?
+			DOMAIN_BUS_PCI_MSI : DOMAIN_BUS_PLATFORM_MSI;
+	return irq_find_matching_fwnode(handle, bus_token);
 }
 
 static int __get_pci_rid(struct pci_dev *pdev, u16 alias, void *data)
diff --git a/drivers/base/platform-msi.c b/drivers/base/platform-msi.c
index 279e539..f6eae18 100644
--- a/drivers/base/platform-msi.c
+++ b/drivers/base/platform-msi.c
@@ -17,8 +17,8 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include <linux/acpi_iort.h>
 #include <linux/device.h>
-#include <linux/idr.h>
 #include <linux/irq.h>
 #include <linux/irqdomain.h>
 #include <linux/msi.h>
@@ -416,3 +416,16 @@ int platform_msi_domain_alloc(struct irq_domain *domain, unsigned int virq,
 
 	return err;
 }
+
+int acpi_configure_msi_domain(struct device *dev)
+{
+	struct irq_domain *d = NULL;
+
+	d = iort_get_device_domain(dev, 0);
+	if (d) {
+		dev_set_msi_domain(dev, d);
+		return 0;
+	}
+
+	return -EINVAL;
+}
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index 6482d47..ea01a37 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -24,6 +24,7 @@
 #include <linux/pm_domain.h>
 #include <linux/idr.h>
 #include <linux/acpi.h>
+#include <linux/msi.h>
 #include <linux/clk/clk-conf.h>
 #include <linux/limits.h>
 #include <linux/property.h>
@@ -500,6 +501,7 @@ struct platform_device *platform_device_register_full(
 	pdev->dev.parent = pdevinfo->parent;
 	pdev->dev.fwnode = pdevinfo->fwnode;
 
+	acpi_configure_msi_domain(&pdev->dev);
 	if (pdevinfo->dma_mask) {
 		/*
 		 * This memory isn't freed when the device is put,
diff --git a/include/linux/msi.h b/include/linux/msi.h
index e8c81fb..1e93a78 100644
--- a/include/linux/msi.h
+++ b/include/linux/msi.h
@@ -308,6 +308,7 @@ int platform_msi_domain_alloc(struct irq_domain *domain, unsigned int virq,
 void platform_msi_domain_free(struct irq_domain *domain, unsigned int virq,
 			      unsigned int nvec);
 void *platform_msi_get_host_data(struct irq_domain *domain);
+int acpi_configure_msi_domain(struct device *dev);
 #endif /* CONFIG_GENERIC_MSI_IRQ_DOMAIN */
 
 #ifdef CONFIG_PCI_MSI_IRQ_DOMAIN
-- 
1.7.12.4

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

* [RFC PATCH v2 05/11] ACPI: platform: setup MSI domain for ACPI based platform device
@ 2016-09-14 14:21   ` Hanjun Guo
  0 siblings, 0 replies; 58+ messages in thread
From: Hanjun Guo @ 2016-09-14 14:21 UTC (permalink / raw)
  To: linux-arm-kernel

From: Hanjun Guo <hanjun.guo@linaro.org>

With the platform msi domain created, we can set up the msi domain
for a platform device when it's probed.

This patch introduces acpi_configure_msi_domain(), which retrieves
the domain from iort and set it to platform device.

As some platform devices such as an irqchip needs the msi irqdomain
to be the interrupt parent domain, we need to get irqdomain before
platform device is probed.

Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Greg KH <gregkh@linuxfoundation.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Bjorn Helgaas <bhelgaas@google.com>
Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: Tomasz Nowicki <tn@semihalf.com>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 drivers/acpi/arm64/iort.c   |  5 ++++-
 drivers/base/platform-msi.c | 15 ++++++++++++++-
 drivers/base/platform.c     |  2 ++
 include/linux/msi.h         |  1 +
 4 files changed, 21 insertions(+), 2 deletions(-)

diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
index 13a1905..bccd3cc 100644
--- a/drivers/acpi/arm64/iort.c
+++ b/drivers/acpi/arm64/iort.c
@@ -478,6 +478,7 @@ struct irq_domain *iort_get_device_domain(struct device *dev, u32 req_id)
 {
 	struct fwnode_handle *handle;
 	int its_id;
+	enum irq_domain_bus_token bus_token;
 
 	if (iort_dev_find_its_id(dev, req_id, 0, &its_id))
 		return NULL;
@@ -486,7 +487,9 @@ struct irq_domain *iort_get_device_domain(struct device *dev, u32 req_id)
 	if (!handle)
 		return NULL;
 
-	return irq_find_matching_fwnode(handle, DOMAIN_BUS_PCI_MSI);
+	bus_token = dev_is_pci(dev) ?
+			DOMAIN_BUS_PCI_MSI : DOMAIN_BUS_PLATFORM_MSI;
+	return irq_find_matching_fwnode(handle, bus_token);
 }
 
 static int __get_pci_rid(struct pci_dev *pdev, u16 alias, void *data)
diff --git a/drivers/base/platform-msi.c b/drivers/base/platform-msi.c
index 279e539..f6eae18 100644
--- a/drivers/base/platform-msi.c
+++ b/drivers/base/platform-msi.c
@@ -17,8 +17,8 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include <linux/acpi_iort.h>
 #include <linux/device.h>
-#include <linux/idr.h>
 #include <linux/irq.h>
 #include <linux/irqdomain.h>
 #include <linux/msi.h>
@@ -416,3 +416,16 @@ int platform_msi_domain_alloc(struct irq_domain *domain, unsigned int virq,
 
 	return err;
 }
+
+int acpi_configure_msi_domain(struct device *dev)
+{
+	struct irq_domain *d = NULL;
+
+	d = iort_get_device_domain(dev, 0);
+	if (d) {
+		dev_set_msi_domain(dev, d);
+		return 0;
+	}
+
+	return -EINVAL;
+}
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index 6482d47..ea01a37 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -24,6 +24,7 @@
 #include <linux/pm_domain.h>
 #include <linux/idr.h>
 #include <linux/acpi.h>
+#include <linux/msi.h>
 #include <linux/clk/clk-conf.h>
 #include <linux/limits.h>
 #include <linux/property.h>
@@ -500,6 +501,7 @@ struct platform_device *platform_device_register_full(
 	pdev->dev.parent = pdevinfo->parent;
 	pdev->dev.fwnode = pdevinfo->fwnode;
 
+	acpi_configure_msi_domain(&pdev->dev);
 	if (pdevinfo->dma_mask) {
 		/*
 		 * This memory isn't freed when the device is put,
diff --git a/include/linux/msi.h b/include/linux/msi.h
index e8c81fb..1e93a78 100644
--- a/include/linux/msi.h
+++ b/include/linux/msi.h
@@ -308,6 +308,7 @@ int platform_msi_domain_alloc(struct irq_domain *domain, unsigned int virq,
 void platform_msi_domain_free(struct irq_domain *domain, unsigned int virq,
 			      unsigned int nvec);
 void *platform_msi_get_host_data(struct irq_domain *domain);
+int acpi_configure_msi_domain(struct device *dev);
 #endif /* CONFIG_GENERIC_MSI_IRQ_DOMAIN */
 
 #ifdef CONFIG_PCI_MSI_IRQ_DOMAIN
-- 
1.7.12.4

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

* [RFC PATCH v2 06/11] msi: platform: make platform_msi_create_device_domain() ACPI aware
  2016-09-14 14:21 ` Hanjun Guo
  (?)
@ 2016-09-14 14:21   ` Hanjun Guo
  -1 siblings, 0 replies; 58+ messages in thread
From: Hanjun Guo @ 2016-09-14 14:21 UTC (permalink / raw)
  To: Rafael J. Wysocki, Marc Zyngier, Lorenzo Pieralisi
  Cc: linux-acpi, linux-arm-kernel, linux-kernel, Thomas Gleixner,
	Bjorn Helgaas, Greg KH, Tomasz Nowicki, Ma Jun, Kefeng Wang,
	Charles Garcia-Tobin, linuxarm, Hanjun Guo

From: Hanjun Guo <hanjun.guo@linaro.org>

With the platform msi domain created for ITS, irqchip such as
mbi-gen connecting ITS, which needs ctreate its own irqdomain.

Fortunately with the platform msi support upstreamed by Marc,
we just need to add minor code to make it run properly.

platform_msi_create_device_domain() is almost ready for ACPI use
except of_node_to_fwnode() is for dt only, make it ACPI aware then
things will work in both DTS and ACPI.

Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Greg KH <gregkh@linuxfoundation.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Bjorn Helgaas <bhelgaas@google.com>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 drivers/base/platform-msi.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/base/platform-msi.c b/drivers/base/platform-msi.c
index f6eae18..9a550a8 100644
--- a/drivers/base/platform-msi.c
+++ b/drivers/base/platform-msi.c
@@ -338,16 +338,17 @@ platform_msi_create_device_domain(struct device *dev,
 {
 	struct platform_msi_priv_data *data;
 	struct irq_domain *domain;
+	struct fwnode_handle *fwnode;
 	int err;
 
 	data = platform_msi_alloc_priv_data(dev, nvec, write_msi_msg);
 	if (IS_ERR(data))
 		return NULL;
 
+	fwnode = dev->of_node ? &dev->of_node->fwnode : dev->fwnode;
 	data->host_data = host_data;
 	domain = irq_domain_create_hierarchy(dev->msi_domain, 0, nvec,
-					     of_node_to_fwnode(dev->of_node),
-					     ops, data);
+					     fwnode, ops, data);
 	if (!domain)
 		goto free_priv;
 
-- 
1.7.12.4

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

* [RFC PATCH v2 06/11] msi: platform: make platform_msi_create_device_domain() ACPI aware
@ 2016-09-14 14:21   ` Hanjun Guo
  0 siblings, 0 replies; 58+ messages in thread
From: Hanjun Guo @ 2016-09-14 14:21 UTC (permalink / raw)
  To: Rafael J. Wysocki, Marc Zyngier, Lorenzo Pieralisi
  Cc: linux-acpi, linux-arm-kernel, linux-kernel, Thomas Gleixner,
	Bjorn Helgaas, Greg KH, Tomasz Nowicki, Ma Jun, Kefeng Wang,
	Charles Garcia-Tobin, linuxarm, Hanjun Guo

From: Hanjun Guo <hanjun.guo@linaro.org>

With the platform msi domain created for ITS, irqchip such as
mbi-gen connecting ITS, which needs ctreate its own irqdomain.

Fortunately with the platform msi support upstreamed by Marc,
we just need to add minor code to make it run properly.

platform_msi_create_device_domain() is almost ready for ACPI use
except of_node_to_fwnode() is for dt only, make it ACPI aware then
things will work in both DTS and ACPI.

Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Greg KH <gregkh@linuxfoundation.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Bjorn Helgaas <bhelgaas@google.com>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 drivers/base/platform-msi.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/base/platform-msi.c b/drivers/base/platform-msi.c
index f6eae18..9a550a8 100644
--- a/drivers/base/platform-msi.c
+++ b/drivers/base/platform-msi.c
@@ -338,16 +338,17 @@ platform_msi_create_device_domain(struct device *dev,
 {
 	struct platform_msi_priv_data *data;
 	struct irq_domain *domain;
+	struct fwnode_handle *fwnode;
 	int err;
 
 	data = platform_msi_alloc_priv_data(dev, nvec, write_msi_msg);
 	if (IS_ERR(data))
 		return NULL;
 
+	fwnode = dev->of_node ? &dev->of_node->fwnode : dev->fwnode;
 	data->host_data = host_data;
 	domain = irq_domain_create_hierarchy(dev->msi_domain, 0, nvec,
-					     of_node_to_fwnode(dev->of_node),
-					     ops, data);
+					     fwnode, ops, data);
 	if (!domain)
 		goto free_priv;
 
-- 
1.7.12.4

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

* [RFC PATCH v2 06/11] msi: platform: make platform_msi_create_device_domain() ACPI aware
@ 2016-09-14 14:21   ` Hanjun Guo
  0 siblings, 0 replies; 58+ messages in thread
From: Hanjun Guo @ 2016-09-14 14:21 UTC (permalink / raw)
  To: linux-arm-kernel

From: Hanjun Guo <hanjun.guo@linaro.org>

With the platform msi domain created for ITS, irqchip such as
mbi-gen connecting ITS, which needs ctreate its own irqdomain.

Fortunately with the platform msi support upstreamed by Marc,
we just need to add minor code to make it run properly.

platform_msi_create_device_domain() is almost ready for ACPI use
except of_node_to_fwnode() is for dt only, make it ACPI aware then
things will work in both DTS and ACPI.

Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Greg KH <gregkh@linuxfoundation.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Bjorn Helgaas <bhelgaas@google.com>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 drivers/base/platform-msi.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/base/platform-msi.c b/drivers/base/platform-msi.c
index f6eae18..9a550a8 100644
--- a/drivers/base/platform-msi.c
+++ b/drivers/base/platform-msi.c
@@ -338,16 +338,17 @@ platform_msi_create_device_domain(struct device *dev,
 {
 	struct platform_msi_priv_data *data;
 	struct irq_domain *domain;
+	struct fwnode_handle *fwnode;
 	int err;
 
 	data = platform_msi_alloc_priv_data(dev, nvec, write_msi_msg);
 	if (IS_ERR(data))
 		return NULL;
 
+	fwnode = dev->of_node ? &dev->of_node->fwnode : dev->fwnode;
 	data->host_data = host_data;
 	domain = irq_domain_create_hierarchy(dev->msi_domain, 0, nvec,
-					     of_node_to_fwnode(dev->of_node),
-					     ops, data);
+					     fwnode, ops, data);
 	if (!domain)
 		goto free_priv;
 
-- 
1.7.12.4

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

* [RFC PATCH v2 07/11] ACPI: irq: introduce interrupt producer
  2016-09-14 14:21 ` Hanjun Guo
  (?)
@ 2016-09-14 14:21   ` Hanjun Guo
  -1 siblings, 0 replies; 58+ messages in thread
From: Hanjun Guo @ 2016-09-14 14:21 UTC (permalink / raw)
  To: Rafael J. Wysocki, Marc Zyngier, Lorenzo Pieralisi
  Cc: linux-acpi, linux-arm-kernel, linux-kernel, Thomas Gleixner,
	Bjorn Helgaas, Greg KH, Tomasz Nowicki, Ma Jun, Kefeng Wang,
	Charles Garcia-Tobin, linuxarm, Hanjun Guo, Agustin Vega-Frias

From: Hanjun Guo <hanjun.guo@linaro.org>

In ACPI 6.1 spec, section 19.6.62, Interrupt Resource Descriptor Macro,

Interrupt (ResourceUsage, EdgeLevel, ActiveLevel, Shared,
ResourceSourceIndex, ResourceSource, DescriptorName)
{ InterruptList } => Buffer

For the arguement ResourceUsage and DescriptorName, which means:

ResourceUsage describes whether the device consumes the specified
interrupt ( ResourceConsumer ) or produces it for use by a child
device ( ResourceProducer ).
If nothing is specified, then ResourceConsumer is assumed.

DescriptorName evaluates to a name string which refers to the
entire resource descriptor.

So it can be used for devices connecting to a specific interrupt
prodcucer instead of the main interrupt controller in MADT. In the
real world, we have irqchip such as mbi-gen which connecting to
a group of wired interrupts and then issue msi to the ITS, devices
connecting to such interrupt controller fit this scope.

For now the irq for ACPI only pointer to the main interrupt
controller's irqdomain, for devices not connecting to those
irqdomains, which need to present its irq parent, we can use
following ASL code to represent it:

Interrupt(ResourceConsumer,..., "\_SB.IRQP") {12,14,....}

then we can parse the interrupt producer with the full
path name "\_SB.IRQP".

In order to do that, we introduce a pointer interrupt_producer
in struct acpi_device, and fill it when scanning irq resources
for acpi device if it specifies the interrupt producer.

But for now when parsing the resources for acpi devices, we don't
pass the acpi device for acpi_walk_resoures() in drivers/acpi/resource.c,
so introduce a adev in struct res_proc_context to pass it as a context
to scan the interrupt resources, then finally pass to acpi_register_gsi()
to find its interrupt producer to get the virq from diffrent domains.

With steps above ready, rework acpi_register_gsi() to get other
interrupt producer if devices not connecting to main interrupt
controller.

Since we often pass NULL to acpi_register_gsi() and there is no interrupt
producer for devices connect to gicd on ARM or io-apic on X86, so it will
use the default irqdomain for those deivces and no functional changes to
those devices.

Cc: Rafael J. Wysocki <rjw@rjwysocki.net>
Cc: Agustin Vega-Frias <agustinv@codeaurora.org>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 drivers/acpi/gsi.c      | 10 ++++--
 drivers/acpi/resource.c | 85 ++++++++++++++++++++++++++++++++++---------------
 include/acpi/acpi_bus.h |  1 +
 3 files changed, 68 insertions(+), 28 deletions(-)

diff --git a/drivers/acpi/gsi.c b/drivers/acpi/gsi.c
index ee9e0f2..29ee547 100644
--- a/drivers/acpi/gsi.c
+++ b/drivers/acpi/gsi.c
@@ -55,13 +55,19 @@ int acpi_register_gsi(struct device *dev, u32 gsi, int trigger,
 		      int polarity)
 {
 	struct irq_fwspec fwspec;
+	struct acpi_device *adev = dev ? to_acpi_device(dev) : NULL;
 
-	if (WARN_ON(!acpi_gsi_domain_id)) {
+	if (adev && &adev->fwnode && adev->interrupt_producer)
+		/* devices in DSDT connecting to spefic interrupt producer */
+		fwspec.fwnode = adev->interrupt_producer;
+	else if (acpi_gsi_domain_id)
+		/* devices connecting to gicd in default */
+		fwspec.fwnode = acpi_gsi_domain_id;
+	else {
 		pr_warn("GSI: No registered irqchip, giving up\n");
 		return -EINVAL;
 	}
 
-	fwspec.fwnode = acpi_gsi_domain_id;
 	fwspec.param[0] = gsi;
 	fwspec.param[1] = acpi_dev_get_irq_type(trigger, polarity);
 	fwspec.param_count = 2;
diff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c
index 56241eb..f1371cf 100644
--- a/drivers/acpi/resource.c
+++ b/drivers/acpi/resource.c
@@ -381,7 +381,7 @@ static void acpi_dev_irqresource_disabled(struct resource *res, u32 gsi)
 	res->flags = IORESOURCE_IRQ | IORESOURCE_DISABLED | IORESOURCE_UNSET;
 }
 
-static void acpi_dev_get_irqresource(struct resource *res, u32 gsi,
+static void acpi_dev_get_irqresource(struct acpi_device *adev, struct resource *res, u32 gsi,
 				     u8 triggering, u8 polarity, u8 shareable,
 				     bool legacy)
 {
@@ -415,7 +415,7 @@ static void acpi_dev_get_irqresource(struct resource *res, u32 gsi,
 	}
 
 	res->flags = acpi_dev_irq_flags(triggering, polarity, shareable);
-	irq = acpi_register_gsi(NULL, gsi, triggering, polarity);
+	irq = acpi_register_gsi(&adev->dev, gsi, triggering, polarity);
 	if (irq >= 0) {
 		res->start = irq;
 		res->end = irq;
@@ -424,27 +424,9 @@ static void acpi_dev_get_irqresource(struct resource *res, u32 gsi,
 	}
 }
 
-/**
- * acpi_dev_resource_interrupt - Extract ACPI interrupt resource information.
- * @ares: Input ACPI resource object.
- * @index: Index into the array of GSIs represented by the resource.
- * @res: Output generic resource object.
- *
- * Check if the given ACPI resource object represents an interrupt resource
- * and @index does not exceed the resource's interrupt count (true is returned
- * in that case regardless of the results of the other checks)).  If that's the
- * case, register the GSI corresponding to @index from the array of interrupts
- * represented by the resource and populate the generic resource object pointed
- * to by @res accordingly.  If the registration of the GSI is not successful,
- * IORESOURCE_DISABLED will be set it that object's flags.
- *
- * Return:
- * 1) false with res->flags setting to zero: not the expected resource type
- * 2) false with IORESOURCE_DISABLED in res->flags: valid unassigned resource
- * 3) true: valid assigned resource
- */
-bool acpi_dev_resource_interrupt(struct acpi_resource *ares, int index,
-				 struct resource *res)
+static bool __acpi_dev_resource_interrupt(struct acpi_device *adev,
+					  struct acpi_resource *ares, int index,
+					  struct resource *res)
 {
 	struct acpi_resource_irq *irq;
 	struct acpi_resource_extended_irq *ext_irq;
@@ -460,7 +442,7 @@ bool acpi_dev_resource_interrupt(struct acpi_resource *ares, int index,
 			acpi_dev_irqresource_disabled(res, 0);
 			return false;
 		}
-		acpi_dev_get_irqresource(res, irq->interrupts[index],
+		acpi_dev_get_irqresource(adev, res, irq->interrupts[index],
 					 irq->triggering, irq->polarity,
 					 irq->sharable, true);
 		break;
@@ -470,7 +452,31 @@ bool acpi_dev_resource_interrupt(struct acpi_resource *ares, int index,
 			acpi_dev_irqresource_disabled(res, 0);
 			return false;
 		}
-		acpi_dev_get_irqresource(res, ext_irq->interrupts[index],
+
+		/*
+		 * It's a interrupt consumer device and connecting to specfic
+		 * interrupt controller. For now, we only support connecting
+		 * interrupts to one irq controller for a single device
+		 */
+		if (ext_irq->producer_consumer == ACPI_CONSUMER
+		    && ext_irq->resource_source.string_length != 0
+		    && !adev->interrupt_producer) {
+			acpi_status status;
+			acpi_handle handle;
+			struct acpi_device *device;
+
+			status = acpi_get_handle(NULL, ext_irq->resource_source.string_ptr, &handle);
+			if (ACPI_FAILURE(status))
+				return false;
+
+			device = acpi_bus_get_acpi_device(handle);
+			if (!device)
+				return false;
+
+			adev->interrupt_producer = &device->fwnode;
+		}
+
+		acpi_dev_get_irqresource(adev, res, ext_irq->interrupts[index],
 					 ext_irq->triggering, ext_irq->polarity,
 					 ext_irq->sharable, false);
 		break;
@@ -481,6 +487,31 @@ bool acpi_dev_resource_interrupt(struct acpi_resource *ares, int index,
 
 	return true;
 }
+
+/**
+ * acpi_dev_resource_interrupt - Extract ACPI interrupt resource information.
+ * @ares: Input ACPI resource object.
+ * @index: Index into the array of GSIs represented by the resource.
+ * @res: Output generic resource object.
+ *
+ * Check if the given ACPI resource object represents an interrupt resource
+ * and @index does not exceed the resource's interrupt count (true is returned
+ * in that case regardless of the results of the other checks)).  If that's the
+ * case, register the GSI corresponding to @index from the array of interrupts
+ * represented by the resource and populate the generic resource object pointed
+ * to by @res accordingly.  If the registration of the GSI is not successful,
+ * IORESOURCE_DISABLED will be set it that object's flags.
+ *
+ * Return:
+ * 1) false with res->flags setting to zero: not the expected resource type
+ * 2) false with IORESOURCE_DISABLED in res->flags: valid unassigned resource
+ * 3) true: valid assigned resource
+ */
+bool acpi_dev_resource_interrupt(struct acpi_resource *ares, int index,
+				 struct resource *res)
+{
+	return __acpi_dev_resource_interrupt(NULL, ares, index, res);
+}
 EXPORT_SYMBOL_GPL(acpi_dev_resource_interrupt);
 
 /**
@@ -499,6 +530,7 @@ struct res_proc_context {
 	void *preproc_data;
 	int count;
 	int error;
+	struct acpi_device *adev;
 };
 
 static acpi_status acpi_dev_new_resource_entry(struct resource_win *win,
@@ -546,7 +578,7 @@ static acpi_status acpi_dev_process_resource(struct acpi_resource *ares,
 	    || acpi_dev_resource_ext_address_space(ares, &win))
 		return acpi_dev_new_resource_entry(&win, c);
 
-	for (i = 0; acpi_dev_resource_interrupt(ares, i, res); i++) {
+	for (i = 0; __acpi_dev_resource_interrupt(c->adev, ares, i, res); i++) {
 		acpi_status status;
 
 		status = acpi_dev_new_resource_entry(&win, c);
@@ -599,6 +631,7 @@ int acpi_dev_get_resources(struct acpi_device *adev, struct list_head *list,
 	c.preproc_data = preproc_data;
 	c.count = 0;
 	c.error = 0;
+	c.adev = adev;
 	status = acpi_walk_resources(adev->handle, METHOD_NAME__CRS,
 				     acpi_dev_process_resource, &c);
 	if (ACPI_FAILURE(status)) {
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index 4242c31..5410d3b 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -355,6 +355,7 @@ struct acpi_device {
 	int device_type;
 	acpi_handle handle;		/* no handle for fixed hardware */
 	struct fwnode_handle fwnode;
+	struct fwnode_handle *interrupt_producer;
 	struct acpi_device *parent;
 	struct list_head children;
 	struct list_head node;
-- 
1.7.12.4

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

* [RFC PATCH v2 07/11] ACPI: irq: introduce interrupt producer
@ 2016-09-14 14:21   ` Hanjun Guo
  0 siblings, 0 replies; 58+ messages in thread
From: Hanjun Guo @ 2016-09-14 14:21 UTC (permalink / raw)
  To: Rafael J. Wysocki, Marc Zyngier, Lorenzo Pieralisi
  Cc: linux-acpi, linux-arm-kernel, linux-kernel, Thomas Gleixner,
	Bjorn Helgaas, Greg KH, Tomasz Nowicki, Ma Jun, Kefeng Wang,
	Charles Garcia-Tobin, linuxarm, Hanjun Guo, Agustin Vega-Frias

From: Hanjun Guo <hanjun.guo@linaro.org>

In ACPI 6.1 spec, section 19.6.62, Interrupt Resource Descriptor Macro,

Interrupt (ResourceUsage, EdgeLevel, ActiveLevel, Shared,
ResourceSourceIndex, ResourceSource, DescriptorName)
{ InterruptList } => Buffer

For the arguement ResourceUsage and DescriptorName, which means:

ResourceUsage describes whether the device consumes the specified
interrupt ( ResourceConsumer ) or produces it for use by a child
device ( ResourceProducer ).
If nothing is specified, then ResourceConsumer is assumed.

DescriptorName evaluates to a name string which refers to the
entire resource descriptor.

So it can be used for devices connecting to a specific interrupt
prodcucer instead of the main interrupt controller in MADT. In the
real world, we have irqchip such as mbi-gen which connecting to
a group of wired interrupts and then issue msi to the ITS, devices
connecting to such interrupt controller fit this scope.

For now the irq for ACPI only pointer to the main interrupt
controller's irqdomain, for devices not connecting to those
irqdomains, which need to present its irq parent, we can use
following ASL code to represent it:

Interrupt(ResourceConsumer,..., "\_SB.IRQP") {12,14,....}

then we can parse the interrupt producer with the full
path name "\_SB.IRQP".

In order to do that, we introduce a pointer interrupt_producer
in struct acpi_device, and fill it when scanning irq resources
for acpi device if it specifies the interrupt producer.

But for now when parsing the resources for acpi devices, we don't
pass the acpi device for acpi_walk_resoures() in drivers/acpi/resource.c,
so introduce a adev in struct res_proc_context to pass it as a context
to scan the interrupt resources, then finally pass to acpi_register_gsi()
to find its interrupt producer to get the virq from diffrent domains.

With steps above ready, rework acpi_register_gsi() to get other
interrupt producer if devices not connecting to main interrupt
controller.

Since we often pass NULL to acpi_register_gsi() and there is no interrupt
producer for devices connect to gicd on ARM or io-apic on X86, so it will
use the default irqdomain for those deivces and no functional changes to
those devices.

Cc: Rafael J. Wysocki <rjw@rjwysocki.net>
Cc: Agustin Vega-Frias <agustinv@codeaurora.org>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 drivers/acpi/gsi.c      | 10 ++++--
 drivers/acpi/resource.c | 85 ++++++++++++++++++++++++++++++++++---------------
 include/acpi/acpi_bus.h |  1 +
 3 files changed, 68 insertions(+), 28 deletions(-)

diff --git a/drivers/acpi/gsi.c b/drivers/acpi/gsi.c
index ee9e0f2..29ee547 100644
--- a/drivers/acpi/gsi.c
+++ b/drivers/acpi/gsi.c
@@ -55,13 +55,19 @@ int acpi_register_gsi(struct device *dev, u32 gsi, int trigger,
 		      int polarity)
 {
 	struct irq_fwspec fwspec;
+	struct acpi_device *adev = dev ? to_acpi_device(dev) : NULL;
 
-	if (WARN_ON(!acpi_gsi_domain_id)) {
+	if (adev && &adev->fwnode && adev->interrupt_producer)
+		/* devices in DSDT connecting to spefic interrupt producer */
+		fwspec.fwnode = adev->interrupt_producer;
+	else if (acpi_gsi_domain_id)
+		/* devices connecting to gicd in default */
+		fwspec.fwnode = acpi_gsi_domain_id;
+	else {
 		pr_warn("GSI: No registered irqchip, giving up\n");
 		return -EINVAL;
 	}
 
-	fwspec.fwnode = acpi_gsi_domain_id;
 	fwspec.param[0] = gsi;
 	fwspec.param[1] = acpi_dev_get_irq_type(trigger, polarity);
 	fwspec.param_count = 2;
diff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c
index 56241eb..f1371cf 100644
--- a/drivers/acpi/resource.c
+++ b/drivers/acpi/resource.c
@@ -381,7 +381,7 @@ static void acpi_dev_irqresource_disabled(struct resource *res, u32 gsi)
 	res->flags = IORESOURCE_IRQ | IORESOURCE_DISABLED | IORESOURCE_UNSET;
 }
 
-static void acpi_dev_get_irqresource(struct resource *res, u32 gsi,
+static void acpi_dev_get_irqresource(struct acpi_device *adev, struct resource *res, u32 gsi,
 				     u8 triggering, u8 polarity, u8 shareable,
 				     bool legacy)
 {
@@ -415,7 +415,7 @@ static void acpi_dev_get_irqresource(struct resource *res, u32 gsi,
 	}
 
 	res->flags = acpi_dev_irq_flags(triggering, polarity, shareable);
-	irq = acpi_register_gsi(NULL, gsi, triggering, polarity);
+	irq = acpi_register_gsi(&adev->dev, gsi, triggering, polarity);
 	if (irq >= 0) {
 		res->start = irq;
 		res->end = irq;
@@ -424,27 +424,9 @@ static void acpi_dev_get_irqresource(struct resource *res, u32 gsi,
 	}
 }
 
-/**
- * acpi_dev_resource_interrupt - Extract ACPI interrupt resource information.
- * @ares: Input ACPI resource object.
- * @index: Index into the array of GSIs represented by the resource.
- * @res: Output generic resource object.
- *
- * Check if the given ACPI resource object represents an interrupt resource
- * and @index does not exceed the resource's interrupt count (true is returned
- * in that case regardless of the results of the other checks)).  If that's the
- * case, register the GSI corresponding to @index from the array of interrupts
- * represented by the resource and populate the generic resource object pointed
- * to by @res accordingly.  If the registration of the GSI is not successful,
- * IORESOURCE_DISABLED will be set it that object's flags.
- *
- * Return:
- * 1) false with res->flags setting to zero: not the expected resource type
- * 2) false with IORESOURCE_DISABLED in res->flags: valid unassigned resource
- * 3) true: valid assigned resource
- */
-bool acpi_dev_resource_interrupt(struct acpi_resource *ares, int index,
-				 struct resource *res)
+static bool __acpi_dev_resource_interrupt(struct acpi_device *adev,
+					  struct acpi_resource *ares, int index,
+					  struct resource *res)
 {
 	struct acpi_resource_irq *irq;
 	struct acpi_resource_extended_irq *ext_irq;
@@ -460,7 +442,7 @@ bool acpi_dev_resource_interrupt(struct acpi_resource *ares, int index,
 			acpi_dev_irqresource_disabled(res, 0);
 			return false;
 		}
-		acpi_dev_get_irqresource(res, irq->interrupts[index],
+		acpi_dev_get_irqresource(adev, res, irq->interrupts[index],
 					 irq->triggering, irq->polarity,
 					 irq->sharable, true);
 		break;
@@ -470,7 +452,31 @@ bool acpi_dev_resource_interrupt(struct acpi_resource *ares, int index,
 			acpi_dev_irqresource_disabled(res, 0);
 			return false;
 		}
-		acpi_dev_get_irqresource(res, ext_irq->interrupts[index],
+
+		/*
+		 * It's a interrupt consumer device and connecting to specfic
+		 * interrupt controller. For now, we only support connecting
+		 * interrupts to one irq controller for a single device
+		 */
+		if (ext_irq->producer_consumer == ACPI_CONSUMER
+		    && ext_irq->resource_source.string_length != 0
+		    && !adev->interrupt_producer) {
+			acpi_status status;
+			acpi_handle handle;
+			struct acpi_device *device;
+
+			status = acpi_get_handle(NULL, ext_irq->resource_source.string_ptr, &handle);
+			if (ACPI_FAILURE(status))
+				return false;
+
+			device = acpi_bus_get_acpi_device(handle);
+			if (!device)
+				return false;
+
+			adev->interrupt_producer = &device->fwnode;
+		}
+
+		acpi_dev_get_irqresource(adev, res, ext_irq->interrupts[index],
 					 ext_irq->triggering, ext_irq->polarity,
 					 ext_irq->sharable, false);
 		break;
@@ -481,6 +487,31 @@ bool acpi_dev_resource_interrupt(struct acpi_resource *ares, int index,
 
 	return true;
 }
+
+/**
+ * acpi_dev_resource_interrupt - Extract ACPI interrupt resource information.
+ * @ares: Input ACPI resource object.
+ * @index: Index into the array of GSIs represented by the resource.
+ * @res: Output generic resource object.
+ *
+ * Check if the given ACPI resource object represents an interrupt resource
+ * and @index does not exceed the resource's interrupt count (true is returned
+ * in that case regardless of the results of the other checks)).  If that's the
+ * case, register the GSI corresponding to @index from the array of interrupts
+ * represented by the resource and populate the generic resource object pointed
+ * to by @res accordingly.  If the registration of the GSI is not successful,
+ * IORESOURCE_DISABLED will be set it that object's flags.
+ *
+ * Return:
+ * 1) false with res->flags setting to zero: not the expected resource type
+ * 2) false with IORESOURCE_DISABLED in res->flags: valid unassigned resource
+ * 3) true: valid assigned resource
+ */
+bool acpi_dev_resource_interrupt(struct acpi_resource *ares, int index,
+				 struct resource *res)
+{
+	return __acpi_dev_resource_interrupt(NULL, ares, index, res);
+}
 EXPORT_SYMBOL_GPL(acpi_dev_resource_interrupt);
 
 /**
@@ -499,6 +530,7 @@ struct res_proc_context {
 	void *preproc_data;
 	int count;
 	int error;
+	struct acpi_device *adev;
 };
 
 static acpi_status acpi_dev_new_resource_entry(struct resource_win *win,
@@ -546,7 +578,7 @@ static acpi_status acpi_dev_process_resource(struct acpi_resource *ares,
 	    || acpi_dev_resource_ext_address_space(ares, &win))
 		return acpi_dev_new_resource_entry(&win, c);
 
-	for (i = 0; acpi_dev_resource_interrupt(ares, i, res); i++) {
+	for (i = 0; __acpi_dev_resource_interrupt(c->adev, ares, i, res); i++) {
 		acpi_status status;
 
 		status = acpi_dev_new_resource_entry(&win, c);
@@ -599,6 +631,7 @@ int acpi_dev_get_resources(struct acpi_device *adev, struct list_head *list,
 	c.preproc_data = preproc_data;
 	c.count = 0;
 	c.error = 0;
+	c.adev = adev;
 	status = acpi_walk_resources(adev->handle, METHOD_NAME__CRS,
 				     acpi_dev_process_resource, &c);
 	if (ACPI_FAILURE(status)) {
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index 4242c31..5410d3b 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -355,6 +355,7 @@ struct acpi_device {
 	int device_type;
 	acpi_handle handle;		/* no handle for fixed hardware */
 	struct fwnode_handle fwnode;
+	struct fwnode_handle *interrupt_producer;
 	struct acpi_device *parent;
 	struct list_head children;
 	struct list_head node;
-- 
1.7.12.4

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

* [RFC PATCH v2 07/11] ACPI: irq: introduce interrupt producer
@ 2016-09-14 14:21   ` Hanjun Guo
  0 siblings, 0 replies; 58+ messages in thread
From: Hanjun Guo @ 2016-09-14 14:21 UTC (permalink / raw)
  To: linux-arm-kernel

From: Hanjun Guo <hanjun.guo@linaro.org>

In ACPI 6.1 spec, section 19.6.62, Interrupt Resource Descriptor Macro,

Interrupt (ResourceUsage, EdgeLevel, ActiveLevel, Shared,
ResourceSourceIndex, ResourceSource, DescriptorName)
{ InterruptList } => Buffer

For the arguement ResourceUsage and DescriptorName, which means:

ResourceUsage describes whether the device consumes the specified
interrupt ( ResourceConsumer ) or produces it for use by a child
device ( ResourceProducer ).
If nothing is specified, then ResourceConsumer is assumed.

DescriptorName evaluates to a name string which refers to the
entire resource descriptor.

So it can be used for devices connecting to a specific interrupt
prodcucer instead of the main interrupt controller in MADT. In the
real world, we have irqchip such as mbi-gen which connecting to
a group of wired interrupts and then issue msi to the ITS, devices
connecting to such interrupt controller fit this scope.

For now the irq for ACPI only pointer to the main interrupt
controller's irqdomain, for devices not connecting to those
irqdomains, which need to present its irq parent, we can use
following ASL code to represent it:

Interrupt(ResourceConsumer,..., "\_SB.IRQP") {12,14,....}

then we can parse the interrupt producer with the full
path name "\_SB.IRQP".

In order to do that, we introduce a pointer interrupt_producer
in struct acpi_device, and fill it when scanning irq resources
for acpi device if it specifies the interrupt producer.

But for now when parsing the resources for acpi devices, we don't
pass the acpi device for acpi_walk_resoures() in drivers/acpi/resource.c,
so introduce a adev in struct res_proc_context to pass it as a context
to scan the interrupt resources, then finally pass to acpi_register_gsi()
to find its interrupt producer to get the virq from diffrent domains.

With steps above ready, rework acpi_register_gsi() to get other
interrupt producer if devices not connecting to main interrupt
controller.

Since we often pass NULL to acpi_register_gsi() and there is no interrupt
producer for devices connect to gicd on ARM or io-apic on X86, so it will
use the default irqdomain for those deivces and no functional changes to
those devices.

Cc: Rafael J. Wysocki <rjw@rjwysocki.net>
Cc: Agustin Vega-Frias <agustinv@codeaurora.org>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 drivers/acpi/gsi.c      | 10 ++++--
 drivers/acpi/resource.c | 85 ++++++++++++++++++++++++++++++++++---------------
 include/acpi/acpi_bus.h |  1 +
 3 files changed, 68 insertions(+), 28 deletions(-)

diff --git a/drivers/acpi/gsi.c b/drivers/acpi/gsi.c
index ee9e0f2..29ee547 100644
--- a/drivers/acpi/gsi.c
+++ b/drivers/acpi/gsi.c
@@ -55,13 +55,19 @@ int acpi_register_gsi(struct device *dev, u32 gsi, int trigger,
 		      int polarity)
 {
 	struct irq_fwspec fwspec;
+	struct acpi_device *adev = dev ? to_acpi_device(dev) : NULL;
 
-	if (WARN_ON(!acpi_gsi_domain_id)) {
+	if (adev && &adev->fwnode && adev->interrupt_producer)
+		/* devices in DSDT connecting to spefic interrupt producer */
+		fwspec.fwnode = adev->interrupt_producer;
+	else if (acpi_gsi_domain_id)
+		/* devices connecting to gicd in default */
+		fwspec.fwnode = acpi_gsi_domain_id;
+	else {
 		pr_warn("GSI: No registered irqchip, giving up\n");
 		return -EINVAL;
 	}
 
-	fwspec.fwnode = acpi_gsi_domain_id;
 	fwspec.param[0] = gsi;
 	fwspec.param[1] = acpi_dev_get_irq_type(trigger, polarity);
 	fwspec.param_count = 2;
diff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c
index 56241eb..f1371cf 100644
--- a/drivers/acpi/resource.c
+++ b/drivers/acpi/resource.c
@@ -381,7 +381,7 @@ static void acpi_dev_irqresource_disabled(struct resource *res, u32 gsi)
 	res->flags = IORESOURCE_IRQ | IORESOURCE_DISABLED | IORESOURCE_UNSET;
 }
 
-static void acpi_dev_get_irqresource(struct resource *res, u32 gsi,
+static void acpi_dev_get_irqresource(struct acpi_device *adev, struct resource *res, u32 gsi,
 				     u8 triggering, u8 polarity, u8 shareable,
 				     bool legacy)
 {
@@ -415,7 +415,7 @@ static void acpi_dev_get_irqresource(struct resource *res, u32 gsi,
 	}
 
 	res->flags = acpi_dev_irq_flags(triggering, polarity, shareable);
-	irq = acpi_register_gsi(NULL, gsi, triggering, polarity);
+	irq = acpi_register_gsi(&adev->dev, gsi, triggering, polarity);
 	if (irq >= 0) {
 		res->start = irq;
 		res->end = irq;
@@ -424,27 +424,9 @@ static void acpi_dev_get_irqresource(struct resource *res, u32 gsi,
 	}
 }
 
-/**
- * acpi_dev_resource_interrupt - Extract ACPI interrupt resource information.
- * @ares: Input ACPI resource object.
- * @index: Index into the array of GSIs represented by the resource.
- * @res: Output generic resource object.
- *
- * Check if the given ACPI resource object represents an interrupt resource
- * and @index does not exceed the resource's interrupt count (true is returned
- * in that case regardless of the results of the other checks)).  If that's the
- * case, register the GSI corresponding to @index from the array of interrupts
- * represented by the resource and populate the generic resource object pointed
- * to by @res accordingly.  If the registration of the GSI is not successful,
- * IORESOURCE_DISABLED will be set it that object's flags.
- *
- * Return:
- * 1) false with res->flags setting to zero: not the expected resource type
- * 2) false with IORESOURCE_DISABLED in res->flags: valid unassigned resource
- * 3) true: valid assigned resource
- */
-bool acpi_dev_resource_interrupt(struct acpi_resource *ares, int index,
-				 struct resource *res)
+static bool __acpi_dev_resource_interrupt(struct acpi_device *adev,
+					  struct acpi_resource *ares, int index,
+					  struct resource *res)
 {
 	struct acpi_resource_irq *irq;
 	struct acpi_resource_extended_irq *ext_irq;
@@ -460,7 +442,7 @@ bool acpi_dev_resource_interrupt(struct acpi_resource *ares, int index,
 			acpi_dev_irqresource_disabled(res, 0);
 			return false;
 		}
-		acpi_dev_get_irqresource(res, irq->interrupts[index],
+		acpi_dev_get_irqresource(adev, res, irq->interrupts[index],
 					 irq->triggering, irq->polarity,
 					 irq->sharable, true);
 		break;
@@ -470,7 +452,31 @@ bool acpi_dev_resource_interrupt(struct acpi_resource *ares, int index,
 			acpi_dev_irqresource_disabled(res, 0);
 			return false;
 		}
-		acpi_dev_get_irqresource(res, ext_irq->interrupts[index],
+
+		/*
+		 * It's a interrupt consumer device and connecting to specfic
+		 * interrupt controller. For now, we only support connecting
+		 * interrupts to one irq controller for a single device
+		 */
+		if (ext_irq->producer_consumer == ACPI_CONSUMER
+		    && ext_irq->resource_source.string_length != 0
+		    && !adev->interrupt_producer) {
+			acpi_status status;
+			acpi_handle handle;
+			struct acpi_device *device;
+
+			status = acpi_get_handle(NULL, ext_irq->resource_source.string_ptr, &handle);
+			if (ACPI_FAILURE(status))
+				return false;
+
+			device = acpi_bus_get_acpi_device(handle);
+			if (!device)
+				return false;
+
+			adev->interrupt_producer = &device->fwnode;
+		}
+
+		acpi_dev_get_irqresource(adev, res, ext_irq->interrupts[index],
 					 ext_irq->triggering, ext_irq->polarity,
 					 ext_irq->sharable, false);
 		break;
@@ -481,6 +487,31 @@ bool acpi_dev_resource_interrupt(struct acpi_resource *ares, int index,
 
 	return true;
 }
+
+/**
+ * acpi_dev_resource_interrupt - Extract ACPI interrupt resource information.
+ * @ares: Input ACPI resource object.
+ * @index: Index into the array of GSIs represented by the resource.
+ * @res: Output generic resource object.
+ *
+ * Check if the given ACPI resource object represents an interrupt resource
+ * and @index does not exceed the resource's interrupt count (true is returned
+ * in that case regardless of the results of the other checks)).  If that's the
+ * case, register the GSI corresponding to @index from the array of interrupts
+ * represented by the resource and populate the generic resource object pointed
+ * to by @res accordingly.  If the registration of the GSI is not successful,
+ * IORESOURCE_DISABLED will be set it that object's flags.
+ *
+ * Return:
+ * 1) false with res->flags setting to zero: not the expected resource type
+ * 2) false with IORESOURCE_DISABLED in res->flags: valid unassigned resource
+ * 3) true: valid assigned resource
+ */
+bool acpi_dev_resource_interrupt(struct acpi_resource *ares, int index,
+				 struct resource *res)
+{
+	return __acpi_dev_resource_interrupt(NULL, ares, index, res);
+}
 EXPORT_SYMBOL_GPL(acpi_dev_resource_interrupt);
 
 /**
@@ -499,6 +530,7 @@ struct res_proc_context {
 	void *preproc_data;
 	int count;
 	int error;
+	struct acpi_device *adev;
 };
 
 static acpi_status acpi_dev_new_resource_entry(struct resource_win *win,
@@ -546,7 +578,7 @@ static acpi_status acpi_dev_process_resource(struct acpi_resource *ares,
 	    || acpi_dev_resource_ext_address_space(ares, &win))
 		return acpi_dev_new_resource_entry(&win, c);
 
-	for (i = 0; acpi_dev_resource_interrupt(ares, i, res); i++) {
+	for (i = 0; __acpi_dev_resource_interrupt(c->adev, ares, i, res); i++) {
 		acpi_status status;
 
 		status = acpi_dev_new_resource_entry(&win, c);
@@ -599,6 +631,7 @@ int acpi_dev_get_resources(struct acpi_device *adev, struct list_head *list,
 	c.preproc_data = preproc_data;
 	c.count = 0;
 	c.error = 0;
+	c.adev = adev;
 	status = acpi_walk_resources(adev->handle, METHOD_NAME__CRS,
 				     acpi_dev_process_resource, &c);
 	if (ACPI_FAILURE(status)) {
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index 4242c31..5410d3b 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -355,6 +355,7 @@ struct acpi_device {
 	int device_type;
 	acpi_handle handle;		/* no handle for fixed hardware */
 	struct fwnode_handle fwnode;
+	struct fwnode_handle *interrupt_producer;
 	struct acpi_device *parent;
 	struct list_head children;
 	struct list_head node;
-- 
1.7.12.4

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

* [RFC PATCH v2 08/11] irqchip: mbigen: drop module owner
  2016-09-14 14:21 ` Hanjun Guo
  (?)
@ 2016-09-14 14:21   ` Hanjun Guo
  -1 siblings, 0 replies; 58+ messages in thread
From: Hanjun Guo @ 2016-09-14 14:21 UTC (permalink / raw)
  To: Rafael J. Wysocki, Marc Zyngier, Lorenzo Pieralisi
  Cc: linux-acpi, linux-arm-kernel, linux-kernel, Thomas Gleixner,
	Bjorn Helgaas, Greg KH, Tomasz Nowicki, Ma Jun, Kefeng Wang,
	Charles Garcia-Tobin, linuxarm, Hanjun Guo

From: Kefeng Wang <wangkefeng.wang@huawei.com>

Module owner will be set by driver core, so drop it.

Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ma Jun <majun258@huawei.com>
Signed-off-by: Kefeng Wang <wangkefeng.wang@huawei.com>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 drivers/irqchip/irq-mbigen.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/irqchip/irq-mbigen.c b/drivers/irqchip/irq-mbigen.c
index 03b79b0..c01ab41 100644
--- a/drivers/irqchip/irq-mbigen.c
+++ b/drivers/irqchip/irq-mbigen.c
@@ -293,7 +293,6 @@ MODULE_DEVICE_TABLE(of, mbigen_of_match);
 static struct platform_driver mbigen_platform_driver = {
 	.driver = {
 		.name		= "Hisilicon MBIGEN-V2",
-		.owner		= THIS_MODULE,
 		.of_match_table	= mbigen_of_match,
 	},
 	.probe			= mbigen_device_probe,
-- 
1.7.12.4


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

* [RFC PATCH v2 08/11] irqchip: mbigen: drop module owner
@ 2016-09-14 14:21   ` Hanjun Guo
  0 siblings, 0 replies; 58+ messages in thread
From: Hanjun Guo @ 2016-09-14 14:21 UTC (permalink / raw)
  To: Rafael J. Wysocki, Marc Zyngier, Lorenzo Pieralisi
  Cc: linux-acpi, linux-arm-kernel, linux-kernel, Thomas Gleixner,
	Bjorn Helgaas, Greg KH, Tomasz Nowicki, Ma Jun, Kefeng Wang,
	Charles Garcia-Tobin, linuxarm, Hanjun Guo

From: Kefeng Wang <wangkefeng.wang@huawei.com>

Module owner will be set by driver core, so drop it.

Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ma Jun <majun258@huawei.com>
Signed-off-by: Kefeng Wang <wangkefeng.wang@huawei.com>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 drivers/irqchip/irq-mbigen.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/irqchip/irq-mbigen.c b/drivers/irqchip/irq-mbigen.c
index 03b79b0..c01ab41 100644
--- a/drivers/irqchip/irq-mbigen.c
+++ b/drivers/irqchip/irq-mbigen.c
@@ -293,7 +293,6 @@ MODULE_DEVICE_TABLE(of, mbigen_of_match);
 static struct platform_driver mbigen_platform_driver = {
 	.driver = {
 		.name		= "Hisilicon MBIGEN-V2",
-		.owner		= THIS_MODULE,
 		.of_match_table	= mbigen_of_match,
 	},
 	.probe			= mbigen_device_probe,
-- 
1.7.12.4

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

* [RFC PATCH v2 08/11] irqchip: mbigen: drop module owner
@ 2016-09-14 14:21   ` Hanjun Guo
  0 siblings, 0 replies; 58+ messages in thread
From: Hanjun Guo @ 2016-09-14 14:21 UTC (permalink / raw)
  To: linux-arm-kernel

From: Kefeng Wang <wangkefeng.wang@huawei.com>

Module owner will be set by driver core, so drop it.

Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ma Jun <majun258@huawei.com>
Signed-off-by: Kefeng Wang <wangkefeng.wang@huawei.com>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 drivers/irqchip/irq-mbigen.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/irqchip/irq-mbigen.c b/drivers/irqchip/irq-mbigen.c
index 03b79b0..c01ab41 100644
--- a/drivers/irqchip/irq-mbigen.c
+++ b/drivers/irqchip/irq-mbigen.c
@@ -293,7 +293,6 @@ MODULE_DEVICE_TABLE(of, mbigen_of_match);
 static struct platform_driver mbigen_platform_driver = {
 	.driver = {
 		.name		= "Hisilicon MBIGEN-V2",
-		.owner		= THIS_MODULE,
 		.of_match_table	= mbigen_of_match,
 	},
 	.probe			= mbigen_device_probe,
-- 
1.7.12.4

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

* [RFC PATCH v2 09/11] irqchip: mbigen: introduce mbigen_of_create_domain()
  2016-09-14 14:21 ` Hanjun Guo
  (?)
@ 2016-09-14 14:21   ` Hanjun Guo
  -1 siblings, 0 replies; 58+ messages in thread
From: Hanjun Guo @ 2016-09-14 14:21 UTC (permalink / raw)
  To: Rafael J. Wysocki, Marc Zyngier, Lorenzo Pieralisi
  Cc: linux-acpi, linux-arm-kernel, linux-kernel, Thomas Gleixner,
	Bjorn Helgaas, Greg KH, Tomasz Nowicki, Ma Jun, Kefeng Wang,
	Charles Garcia-Tobin, linuxarm, Hanjun Guo

From: Kefeng Wang <wangkefeng.wang@huawei.com>

Introduce mbigen_of_create_domain() to consolidate OF related
code and prepare for ACPI later.

Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ma Jun <majun258@huawei.com>
Signed-off-by: Kefeng Wang <wangkefeng.wang@huawei.com>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 drivers/irqchip/irq-mbigen.c | 42 +++++++++++++++++++++++++++---------------
 1 file changed, 27 insertions(+), 15 deletions(-)

diff --git a/drivers/irqchip/irq-mbigen.c b/drivers/irqchip/irq-mbigen.c
index c01ab41..9484ea0 100644
--- a/drivers/irqchip/irq-mbigen.c
+++ b/drivers/irqchip/irq-mbigen.c
@@ -236,27 +236,15 @@ static struct irq_domain_ops mbigen_domain_ops = {
 	.free		= irq_domain_free_irqs_common,
 };
 
-static int mbigen_device_probe(struct platform_device *pdev)
+static int mbigen_of_create_domain(struct platform_device *pdev,
+				   struct mbigen_device *mgn_chip)
 {
-	struct mbigen_device *mgn_chip;
+	struct device *parent;
 	struct platform_device *child;
 	struct irq_domain *domain;
 	struct device_node *np;
-	struct device *parent;
-	struct resource *res;
 	u32 num_pins;
 
-	mgn_chip = devm_kzalloc(&pdev->dev, sizeof(*mgn_chip), GFP_KERNEL);
-	if (!mgn_chip)
-		return -ENOMEM;
-
-	mgn_chip->pdev = pdev;
-
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	mgn_chip->base = devm_ioremap_resource(&pdev->dev, res);
-	if (IS_ERR(mgn_chip->base))
-		return PTR_ERR(mgn_chip->base);
-
 	for_each_child_of_node(pdev->dev.of_node, np) {
 		if (!of_property_read_bool(np, "interrupt-controller"))
 			continue;
@@ -280,6 +268,30 @@ static int mbigen_device_probe(struct platform_device *pdev)
 			return -ENOMEM;
 	}
 
+	return 0;
+}
+
+static int mbigen_device_probe(struct platform_device *pdev)
+{
+	struct mbigen_device *mgn_chip;
+	struct resource *res;
+	int err;
+
+	mgn_chip = devm_kzalloc(&pdev->dev, sizeof(*mgn_chip), GFP_KERNEL);
+	if (!mgn_chip)
+		return -ENOMEM;
+
+	mgn_chip->pdev = pdev;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	mgn_chip->base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(mgn_chip->base))
+		return PTR_ERR(mgn_chip->base);
+
+	err = mbigen_of_create_domain(pdev, mgn_chip);
+	if (err)
+		return err;
+
 	platform_set_drvdata(pdev, mgn_chip);
 	return 0;
 }
-- 
1.7.12.4


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

* [RFC PATCH v2 09/11] irqchip: mbigen: introduce mbigen_of_create_domain()
@ 2016-09-14 14:21   ` Hanjun Guo
  0 siblings, 0 replies; 58+ messages in thread
From: Hanjun Guo @ 2016-09-14 14:21 UTC (permalink / raw)
  To: Rafael J. Wysocki, Marc Zyngier, Lorenzo Pieralisi
  Cc: linux-acpi, linux-arm-kernel, linux-kernel, Thomas Gleixner,
	Bjorn Helgaas, Greg KH, Tomasz Nowicki, Ma Jun, Kefeng Wang,
	Charles Garcia-Tobin, linuxarm, Hanjun Guo

From: Kefeng Wang <wangkefeng.wang@huawei.com>

Introduce mbigen_of_create_domain() to consolidate OF related
code and prepare for ACPI later.

Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ma Jun <majun258@huawei.com>
Signed-off-by: Kefeng Wang <wangkefeng.wang@huawei.com>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 drivers/irqchip/irq-mbigen.c | 42 +++++++++++++++++++++++++++---------------
 1 file changed, 27 insertions(+), 15 deletions(-)

diff --git a/drivers/irqchip/irq-mbigen.c b/drivers/irqchip/irq-mbigen.c
index c01ab41..9484ea0 100644
--- a/drivers/irqchip/irq-mbigen.c
+++ b/drivers/irqchip/irq-mbigen.c
@@ -236,27 +236,15 @@ static struct irq_domain_ops mbigen_domain_ops = {
 	.free		= irq_domain_free_irqs_common,
 };
 
-static int mbigen_device_probe(struct platform_device *pdev)
+static int mbigen_of_create_domain(struct platform_device *pdev,
+				   struct mbigen_device *mgn_chip)
 {
-	struct mbigen_device *mgn_chip;
+	struct device *parent;
 	struct platform_device *child;
 	struct irq_domain *domain;
 	struct device_node *np;
-	struct device *parent;
-	struct resource *res;
 	u32 num_pins;
 
-	mgn_chip = devm_kzalloc(&pdev->dev, sizeof(*mgn_chip), GFP_KERNEL);
-	if (!mgn_chip)
-		return -ENOMEM;
-
-	mgn_chip->pdev = pdev;
-
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	mgn_chip->base = devm_ioremap_resource(&pdev->dev, res);
-	if (IS_ERR(mgn_chip->base))
-		return PTR_ERR(mgn_chip->base);
-
 	for_each_child_of_node(pdev->dev.of_node, np) {
 		if (!of_property_read_bool(np, "interrupt-controller"))
 			continue;
@@ -280,6 +268,30 @@ static int mbigen_device_probe(struct platform_device *pdev)
 			return -ENOMEM;
 	}
 
+	return 0;
+}
+
+static int mbigen_device_probe(struct platform_device *pdev)
+{
+	struct mbigen_device *mgn_chip;
+	struct resource *res;
+	int err;
+
+	mgn_chip = devm_kzalloc(&pdev->dev, sizeof(*mgn_chip), GFP_KERNEL);
+	if (!mgn_chip)
+		return -ENOMEM;
+
+	mgn_chip->pdev = pdev;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	mgn_chip->base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(mgn_chip->base))
+		return PTR_ERR(mgn_chip->base);
+
+	err = mbigen_of_create_domain(pdev, mgn_chip);
+	if (err)
+		return err;
+
 	platform_set_drvdata(pdev, mgn_chip);
 	return 0;
 }
-- 
1.7.12.4

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

* [RFC PATCH v2 09/11] irqchip: mbigen: introduce mbigen_of_create_domain()
@ 2016-09-14 14:21   ` Hanjun Guo
  0 siblings, 0 replies; 58+ messages in thread
From: Hanjun Guo @ 2016-09-14 14:21 UTC (permalink / raw)
  To: linux-arm-kernel

From: Kefeng Wang <wangkefeng.wang@huawei.com>

Introduce mbigen_of_create_domain() to consolidate OF related
code and prepare for ACPI later.

Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ma Jun <majun258@huawei.com>
Signed-off-by: Kefeng Wang <wangkefeng.wang@huawei.com>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 drivers/irqchip/irq-mbigen.c | 42 +++++++++++++++++++++++++++---------------
 1 file changed, 27 insertions(+), 15 deletions(-)

diff --git a/drivers/irqchip/irq-mbigen.c b/drivers/irqchip/irq-mbigen.c
index c01ab41..9484ea0 100644
--- a/drivers/irqchip/irq-mbigen.c
+++ b/drivers/irqchip/irq-mbigen.c
@@ -236,27 +236,15 @@ static struct irq_domain_ops mbigen_domain_ops = {
 	.free		= irq_domain_free_irqs_common,
 };
 
-static int mbigen_device_probe(struct platform_device *pdev)
+static int mbigen_of_create_domain(struct platform_device *pdev,
+				   struct mbigen_device *mgn_chip)
 {
-	struct mbigen_device *mgn_chip;
+	struct device *parent;
 	struct platform_device *child;
 	struct irq_domain *domain;
 	struct device_node *np;
-	struct device *parent;
-	struct resource *res;
 	u32 num_pins;
 
-	mgn_chip = devm_kzalloc(&pdev->dev, sizeof(*mgn_chip), GFP_KERNEL);
-	if (!mgn_chip)
-		return -ENOMEM;
-
-	mgn_chip->pdev = pdev;
-
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	mgn_chip->base = devm_ioremap_resource(&pdev->dev, res);
-	if (IS_ERR(mgn_chip->base))
-		return PTR_ERR(mgn_chip->base);
-
 	for_each_child_of_node(pdev->dev.of_node, np) {
 		if (!of_property_read_bool(np, "interrupt-controller"))
 			continue;
@@ -280,6 +268,30 @@ static int mbigen_device_probe(struct platform_device *pdev)
 			return -ENOMEM;
 	}
 
+	return 0;
+}
+
+static int mbigen_device_probe(struct platform_device *pdev)
+{
+	struct mbigen_device *mgn_chip;
+	struct resource *res;
+	int err;
+
+	mgn_chip = devm_kzalloc(&pdev->dev, sizeof(*mgn_chip), GFP_KERNEL);
+	if (!mgn_chip)
+		return -ENOMEM;
+
+	mgn_chip->pdev = pdev;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	mgn_chip->base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(mgn_chip->base))
+		return PTR_ERR(mgn_chip->base);
+
+	err = mbigen_of_create_domain(pdev, mgn_chip);
+	if (err)
+		return err;
+
 	platform_set_drvdata(pdev, mgn_chip);
 	return 0;
 }
-- 
1.7.12.4

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

* [RFC PATCH v2 10/11] irqchip: mbigen: Add ACPI support
  2016-09-14 14:21 ` Hanjun Guo
  (?)
@ 2016-09-14 14:21   ` Hanjun Guo
  -1 siblings, 0 replies; 58+ messages in thread
From: Hanjun Guo @ 2016-09-14 14:21 UTC (permalink / raw)
  To: Rafael J. Wysocki, Marc Zyngier, Lorenzo Pieralisi
  Cc: linux-acpi, linux-arm-kernel, linux-kernel, Thomas Gleixner,
	Bjorn Helgaas, Greg KH, Tomasz Nowicki, Ma Jun, Kefeng Wang,
	Charles Garcia-Tobin, linuxarm, Hanjun Guo

From: Hanjun Guo <hanjun.guo@linaro.org>

With the preparation of platform msi support and interrupt producer
in DSDT, we can add mbigen ACPI support now.

We are using _PRS methd to indicate number of irq pins instead
of num_pins in DT.

For mbi-gen,
    Device(MBI0) {
          Name(_HID, "HISI0152")
          Name(_UID, Zero)
          Name(_CRS, ResourceTemplate() {
                  Memory32Fixed(ReadWrite, 0xa0080000, 0x10000)
          })

          Name (_PRS, ResourceTemplate() {
		  Interrupt(ResourceProducer,...) {12,14,....}
          })
    }

For devices,

   Device(COM0) {
          Name(_HID, "ACPIIDxx")
          Name(_UID, Zero)
          Name(_CRS, ResourceTemplate() {
                 Memory32Fixed(ReadWrite, 0xb0030000, 0x10000)
		 Interrupt(ResourceConsumer,..., "\_SB.MBI0") {12}
          })
    }

With the helpe of platform msi and interrupt producer, then devices
will get the virq from mbi-gen's irqdomain.

Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ma Jun <majun258@huawei.com>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 drivers/irqchip/irq-mbigen.c | 70 ++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 67 insertions(+), 3 deletions(-)

diff --git a/drivers/irqchip/irq-mbigen.c b/drivers/irqchip/irq-mbigen.c
index 9484ea0..ca6add1 100644
--- a/drivers/irqchip/irq-mbigen.c
+++ b/drivers/irqchip/irq-mbigen.c
@@ -16,6 +16,7 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include <linux/acpi.h>
 #include <linux/interrupt.h>
 #include <linux/irqchip.h>
 #include <linux/module.h>
@@ -180,7 +181,7 @@ static int mbigen_domain_translate(struct irq_domain *d,
 				    unsigned long *hwirq,
 				    unsigned int *type)
 {
-	if (is_of_node(fwspec->fwnode)) {
+	if (is_of_node(fwspec->fwnode) || is_acpi_device_node(fwspec->fwnode)) {
 		if (fwspec->param_count != 2)
 			return -EINVAL;
 
@@ -271,6 +272,54 @@ static int mbigen_of_create_domain(struct platform_device *pdev,
 	return 0;
 }
 
+#ifdef CONFIG_ACPI
+static acpi_status mbigen_acpi_process_resource(struct acpi_resource *ares,
+					     void *context)
+{
+	struct acpi_resource_extended_irq *ext_irq;
+	u32 *num_irqs = context;
+
+	switch (ares->type) {
+	case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
+		ext_irq = &ares->data.extended_irq;
+		*num_irqs += ext_irq->interrupt_count;
+		break;
+	default:
+		break;
+	}
+
+	return AE_OK;
+}
+
+static int mbigen_acpi_create_domain(struct platform_device *pdev,
+				     struct mbigen_device *mgn_chip)
+{
+	struct irq_domain *domain;
+	u32 num_msis = 0;
+	acpi_status status;
+
+	status = acpi_walk_resources(ACPI_HANDLE(&pdev->dev), METHOD_NAME__PRS,
+				     mbigen_acpi_process_resource, &num_msis);
+        if (ACPI_FAILURE(status) || num_msis == 0)
+		return -EINVAL;
+
+	domain = platform_msi_create_device_domain(&pdev->dev, num_msis,
+						   mbigen_write_msg,
+						   &mbigen_domain_ops,
+						   mgn_chip);
+	if (!domain)
+		return -ENOMEM;
+
+	return 0;
+}
+#else
+static int mbigen_acpi_create_domain(struct platform_device *pdev,
+				     struct mbigen_device *mgn_chip)
+{
+	return -ENODEV;
+}
+#endif
+
 static int mbigen_device_probe(struct platform_device *pdev)
 {
 	struct mbigen_device *mgn_chip;
@@ -288,9 +337,17 @@ static int mbigen_device_probe(struct platform_device *pdev)
 	if (IS_ERR(mgn_chip->base))
 		return PTR_ERR(mgn_chip->base);
 
-	err = mbigen_of_create_domain(pdev, mgn_chip);
-	if (err)
+	if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node)
+		err = mbigen_of_create_domain(pdev, mgn_chip);
+	else if (ACPI_COMPANION(&pdev->dev))
+		err = mbigen_acpi_create_domain(pdev, mgn_chip);
+	else
+		err = -EINVAL;
+
+	if (err) {
+		dev_err(&pdev->dev, "Failed to create mbi-gen@%p irqdomain", mgn_chip->base);
 		return err;
+	}
 
 	platform_set_drvdata(pdev, mgn_chip);
 	return 0;
@@ -302,10 +359,17 @@ static const struct of_device_id mbigen_of_match[] = {
 };
 MODULE_DEVICE_TABLE(of, mbigen_of_match);
 
+static const struct acpi_device_id mbigen_acpi_match[] = {
+        { "HISI0152", 0 },
+	{}
+};
+MODULE_DEVICE_TABLE(acpi, mbigen_acpi_match);
+
 static struct platform_driver mbigen_platform_driver = {
 	.driver = {
 		.name		= "Hisilicon MBIGEN-V2",
 		.of_match_table	= mbigen_of_match,
+		.acpi_match_table = ACPI_PTR(mbigen_acpi_match),
 	},
 	.probe			= mbigen_device_probe,
 };
-- 
1.7.12.4

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

* [RFC PATCH v2 10/11] irqchip: mbigen: Add ACPI support
@ 2016-09-14 14:21   ` Hanjun Guo
  0 siblings, 0 replies; 58+ messages in thread
From: Hanjun Guo @ 2016-09-14 14:21 UTC (permalink / raw)
  To: Rafael J. Wysocki, Marc Zyngier, Lorenzo Pieralisi
  Cc: linux-acpi, linux-arm-kernel, linux-kernel, Thomas Gleixner,
	Bjorn Helgaas, Greg KH, Tomasz Nowicki, Ma Jun, Kefeng Wang,
	Charles Garcia-Tobin, linuxarm, Hanjun Guo

From: Hanjun Guo <hanjun.guo@linaro.org>

With the preparation of platform msi support and interrupt producer
in DSDT, we can add mbigen ACPI support now.

We are using _PRS methd to indicate number of irq pins instead
of num_pins in DT.

For mbi-gen,
    Device(MBI0) {
          Name(_HID, "HISI0152")
          Name(_UID, Zero)
          Name(_CRS, ResourceTemplate() {
                  Memory32Fixed(ReadWrite, 0xa0080000, 0x10000)
          })

          Name (_PRS, ResourceTemplate() {
		  Interrupt(ResourceProducer,...) {12,14,....}
          })
    }

For devices,

   Device(COM0) {
          Name(_HID, "ACPIIDxx")
          Name(_UID, Zero)
          Name(_CRS, ResourceTemplate() {
                 Memory32Fixed(ReadWrite, 0xb0030000, 0x10000)
		 Interrupt(ResourceConsumer,..., "\_SB.MBI0") {12}
          })
    }

With the helpe of platform msi and interrupt producer, then devices
will get the virq from mbi-gen's irqdomain.

Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ma Jun <majun258@huawei.com>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 drivers/irqchip/irq-mbigen.c | 70 ++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 67 insertions(+), 3 deletions(-)

diff --git a/drivers/irqchip/irq-mbigen.c b/drivers/irqchip/irq-mbigen.c
index 9484ea0..ca6add1 100644
--- a/drivers/irqchip/irq-mbigen.c
+++ b/drivers/irqchip/irq-mbigen.c
@@ -16,6 +16,7 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include <linux/acpi.h>
 #include <linux/interrupt.h>
 #include <linux/irqchip.h>
 #include <linux/module.h>
@@ -180,7 +181,7 @@ static int mbigen_domain_translate(struct irq_domain *d,
 				    unsigned long *hwirq,
 				    unsigned int *type)
 {
-	if (is_of_node(fwspec->fwnode)) {
+	if (is_of_node(fwspec->fwnode) || is_acpi_device_node(fwspec->fwnode)) {
 		if (fwspec->param_count != 2)
 			return -EINVAL;
 
@@ -271,6 +272,54 @@ static int mbigen_of_create_domain(struct platform_device *pdev,
 	return 0;
 }
 
+#ifdef CONFIG_ACPI
+static acpi_status mbigen_acpi_process_resource(struct acpi_resource *ares,
+					     void *context)
+{
+	struct acpi_resource_extended_irq *ext_irq;
+	u32 *num_irqs = context;
+
+	switch (ares->type) {
+	case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
+		ext_irq = &ares->data.extended_irq;
+		*num_irqs += ext_irq->interrupt_count;
+		break;
+	default:
+		break;
+	}
+
+	return AE_OK;
+}
+
+static int mbigen_acpi_create_domain(struct platform_device *pdev,
+				     struct mbigen_device *mgn_chip)
+{
+	struct irq_domain *domain;
+	u32 num_msis = 0;
+	acpi_status status;
+
+	status = acpi_walk_resources(ACPI_HANDLE(&pdev->dev), METHOD_NAME__PRS,
+				     mbigen_acpi_process_resource, &num_msis);
+        if (ACPI_FAILURE(status) || num_msis == 0)
+		return -EINVAL;
+
+	domain = platform_msi_create_device_domain(&pdev->dev, num_msis,
+						   mbigen_write_msg,
+						   &mbigen_domain_ops,
+						   mgn_chip);
+	if (!domain)
+		return -ENOMEM;
+
+	return 0;
+}
+#else
+static int mbigen_acpi_create_domain(struct platform_device *pdev,
+				     struct mbigen_device *mgn_chip)
+{
+	return -ENODEV;
+}
+#endif
+
 static int mbigen_device_probe(struct platform_device *pdev)
 {
 	struct mbigen_device *mgn_chip;
@@ -288,9 +337,17 @@ static int mbigen_device_probe(struct platform_device *pdev)
 	if (IS_ERR(mgn_chip->base))
 		return PTR_ERR(mgn_chip->base);
 
-	err = mbigen_of_create_domain(pdev, mgn_chip);
-	if (err)
+	if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node)
+		err = mbigen_of_create_domain(pdev, mgn_chip);
+	else if (ACPI_COMPANION(&pdev->dev))
+		err = mbigen_acpi_create_domain(pdev, mgn_chip);
+	else
+		err = -EINVAL;
+
+	if (err) {
+		dev_err(&pdev->dev, "Failed to create mbi-gen@%p irqdomain", mgn_chip->base);
 		return err;
+	}
 
 	platform_set_drvdata(pdev, mgn_chip);
 	return 0;
@@ -302,10 +359,17 @@ static const struct of_device_id mbigen_of_match[] = {
 };
 MODULE_DEVICE_TABLE(of, mbigen_of_match);
 
+static const struct acpi_device_id mbigen_acpi_match[] = {
+        { "HISI0152", 0 },
+	{}
+};
+MODULE_DEVICE_TABLE(acpi, mbigen_acpi_match);
+
 static struct platform_driver mbigen_platform_driver = {
 	.driver = {
 		.name		= "Hisilicon MBIGEN-V2",
 		.of_match_table	= mbigen_of_match,
+		.acpi_match_table = ACPI_PTR(mbigen_acpi_match),
 	},
 	.probe			= mbigen_device_probe,
 };
-- 
1.7.12.4

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

* [RFC PATCH v2 10/11] irqchip: mbigen: Add ACPI support
@ 2016-09-14 14:21   ` Hanjun Guo
  0 siblings, 0 replies; 58+ messages in thread
From: Hanjun Guo @ 2016-09-14 14:21 UTC (permalink / raw)
  To: linux-arm-kernel

From: Hanjun Guo <hanjun.guo@linaro.org>

With the preparation of platform msi support and interrupt producer
in DSDT, we can add mbigen ACPI support now.

We are using _PRS methd to indicate number of irq pins instead
of num_pins in DT.

For mbi-gen,
    Device(MBI0) {
          Name(_HID, "HISI0152")
          Name(_UID, Zero)
          Name(_CRS, ResourceTemplate() {
                  Memory32Fixed(ReadWrite, 0xa0080000, 0x10000)
          })

          Name (_PRS, ResourceTemplate() {
		  Interrupt(ResourceProducer,...) {12,14,....}
          })
    }

For devices,

   Device(COM0) {
          Name(_HID, "ACPIIDxx")
          Name(_UID, Zero)
          Name(_CRS, ResourceTemplate() {
                 Memory32Fixed(ReadWrite, 0xb0030000, 0x10000)
		 Interrupt(ResourceConsumer,..., "\_SB.MBI0") {12}
          })
    }

With the helpe of platform msi and interrupt producer, then devices
will get the virq from mbi-gen's irqdomain.

Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ma Jun <majun258@huawei.com>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 drivers/irqchip/irq-mbigen.c | 70 ++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 67 insertions(+), 3 deletions(-)

diff --git a/drivers/irqchip/irq-mbigen.c b/drivers/irqchip/irq-mbigen.c
index 9484ea0..ca6add1 100644
--- a/drivers/irqchip/irq-mbigen.c
+++ b/drivers/irqchip/irq-mbigen.c
@@ -16,6 +16,7 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include <linux/acpi.h>
 #include <linux/interrupt.h>
 #include <linux/irqchip.h>
 #include <linux/module.h>
@@ -180,7 +181,7 @@ static int mbigen_domain_translate(struct irq_domain *d,
 				    unsigned long *hwirq,
 				    unsigned int *type)
 {
-	if (is_of_node(fwspec->fwnode)) {
+	if (is_of_node(fwspec->fwnode) || is_acpi_device_node(fwspec->fwnode)) {
 		if (fwspec->param_count != 2)
 			return -EINVAL;
 
@@ -271,6 +272,54 @@ static int mbigen_of_create_domain(struct platform_device *pdev,
 	return 0;
 }
 
+#ifdef CONFIG_ACPI
+static acpi_status mbigen_acpi_process_resource(struct acpi_resource *ares,
+					     void *context)
+{
+	struct acpi_resource_extended_irq *ext_irq;
+	u32 *num_irqs = context;
+
+	switch (ares->type) {
+	case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
+		ext_irq = &ares->data.extended_irq;
+		*num_irqs += ext_irq->interrupt_count;
+		break;
+	default:
+		break;
+	}
+
+	return AE_OK;
+}
+
+static int mbigen_acpi_create_domain(struct platform_device *pdev,
+				     struct mbigen_device *mgn_chip)
+{
+	struct irq_domain *domain;
+	u32 num_msis = 0;
+	acpi_status status;
+
+	status = acpi_walk_resources(ACPI_HANDLE(&pdev->dev), METHOD_NAME__PRS,
+				     mbigen_acpi_process_resource, &num_msis);
+        if (ACPI_FAILURE(status) || num_msis == 0)
+		return -EINVAL;
+
+	domain = platform_msi_create_device_domain(&pdev->dev, num_msis,
+						   mbigen_write_msg,
+						   &mbigen_domain_ops,
+						   mgn_chip);
+	if (!domain)
+		return -ENOMEM;
+
+	return 0;
+}
+#else
+static int mbigen_acpi_create_domain(struct platform_device *pdev,
+				     struct mbigen_device *mgn_chip)
+{
+	return -ENODEV;
+}
+#endif
+
 static int mbigen_device_probe(struct platform_device *pdev)
 {
 	struct mbigen_device *mgn_chip;
@@ -288,9 +337,17 @@ static int mbigen_device_probe(struct platform_device *pdev)
 	if (IS_ERR(mgn_chip->base))
 		return PTR_ERR(mgn_chip->base);
 
-	err = mbigen_of_create_domain(pdev, mgn_chip);
-	if (err)
+	if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node)
+		err = mbigen_of_create_domain(pdev, mgn_chip);
+	else if (ACPI_COMPANION(&pdev->dev))
+		err = mbigen_acpi_create_domain(pdev, mgn_chip);
+	else
+		err = -EINVAL;
+
+	if (err) {
+		dev_err(&pdev->dev, "Failed to create mbi-gen@%p irqdomain", mgn_chip->base);
 		return err;
+	}
 
 	platform_set_drvdata(pdev, mgn_chip);
 	return 0;
@@ -302,10 +359,17 @@ static const struct of_device_id mbigen_of_match[] = {
 };
 MODULE_DEVICE_TABLE(of, mbigen_of_match);
 
+static const struct acpi_device_id mbigen_acpi_match[] = {
+        { "HISI0152", 0 },
+	{}
+};
+MODULE_DEVICE_TABLE(acpi, mbigen_acpi_match);
+
 static struct platform_driver mbigen_platform_driver = {
 	.driver = {
 		.name		= "Hisilicon MBIGEN-V2",
 		.of_match_table	= mbigen_of_match,
+		.acpi_match_table = ACPI_PTR(mbigen_acpi_match),
 	},
 	.probe			= mbigen_device_probe,
 };
-- 
1.7.12.4

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

* [RFC PATCH v2 11/11] irqchip: mbigen: promote mbigen init
  2016-09-14 14:21 ` Hanjun Guo
  (?)
@ 2016-09-14 14:21   ` Hanjun Guo
  -1 siblings, 0 replies; 58+ messages in thread
From: Hanjun Guo @ 2016-09-14 14:21 UTC (permalink / raw)
  To: Rafael J. Wysocki, Marc Zyngier, Lorenzo Pieralisi
  Cc: Kefeng Wang, Greg KH, linux-kernel, linuxarm, linux-acpi,
	Hanjun Guo, Tomasz Nowicki, Bjorn Helgaas, Thomas Gleixner,
	Charles Garcia-Tobin, linux-arm-kernel, Ma Jun

From: Hanjun Guo <hanjun.guo@linaro.org>

mbigen is an irqchip and it needs to be probed before
devices, same logic is used for SMMU and etc., let's
use arch_initcall instead of platform init for mbigen.

Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ma Jun <majun258@huawei.com>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 drivers/irqchip/irq-mbigen.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/irqchip/irq-mbigen.c b/drivers/irqchip/irq-mbigen.c
index ca6add1..3a33de6 100644
--- a/drivers/irqchip/irq-mbigen.c
+++ b/drivers/irqchip/irq-mbigen.c
@@ -374,7 +374,11 @@ static struct platform_driver mbigen_platform_driver = {
 	.probe			= mbigen_device_probe,
 };
 
-module_platform_driver(mbigen_platform_driver);
+static __init int mbigen_init(void)
+{
+	return platform_driver_register(&mbigen_platform_driver);
+}
+arch_initcall(mbigen_init);
 
 MODULE_AUTHOR("Jun Ma <majun258@huawei.com>");
 MODULE_AUTHOR("Yun Wu <wuyun.wu@huawei.com>");
-- 
1.7.12.4

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

* [RFC PATCH v2 11/11] irqchip: mbigen: promote mbigen init
@ 2016-09-14 14:21   ` Hanjun Guo
  0 siblings, 0 replies; 58+ messages in thread
From: Hanjun Guo @ 2016-09-14 14:21 UTC (permalink / raw)
  To: Rafael J. Wysocki, Marc Zyngier, Lorenzo Pieralisi
  Cc: linux-acpi, linux-arm-kernel, linux-kernel, Thomas Gleixner,
	Bjorn Helgaas, Greg KH, Tomasz Nowicki, Ma Jun, Kefeng Wang,
	Charles Garcia-Tobin, linuxarm, Hanjun Guo

From: Hanjun Guo <hanjun.guo@linaro.org>

mbigen is an irqchip and it needs to be probed before
devices, same logic is used for SMMU and etc., let's
use arch_initcall instead of platform init for mbigen.

Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ma Jun <majun258@huawei.com>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 drivers/irqchip/irq-mbigen.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/irqchip/irq-mbigen.c b/drivers/irqchip/irq-mbigen.c
index ca6add1..3a33de6 100644
--- a/drivers/irqchip/irq-mbigen.c
+++ b/drivers/irqchip/irq-mbigen.c
@@ -374,7 +374,11 @@ static struct platform_driver mbigen_platform_driver = {
 	.probe			= mbigen_device_probe,
 };
 
-module_platform_driver(mbigen_platform_driver);
+static __init int mbigen_init(void)
+{
+	return platform_driver_register(&mbigen_platform_driver);
+}
+arch_initcall(mbigen_init);
 
 MODULE_AUTHOR("Jun Ma <majun258@huawei.com>");
 MODULE_AUTHOR("Yun Wu <wuyun.wu@huawei.com>");
-- 
1.7.12.4

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

* [RFC PATCH v2 11/11] irqchip: mbigen: promote mbigen init
@ 2016-09-14 14:21   ` Hanjun Guo
  0 siblings, 0 replies; 58+ messages in thread
From: Hanjun Guo @ 2016-09-14 14:21 UTC (permalink / raw)
  To: linux-arm-kernel

From: Hanjun Guo <hanjun.guo@linaro.org>

mbigen is an irqchip and it needs to be probed before
devices, same logic is used for SMMU and etc., let's
use arch_initcall instead of platform init for mbigen.

Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ma Jun <majun258@huawei.com>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
 drivers/irqchip/irq-mbigen.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/irqchip/irq-mbigen.c b/drivers/irqchip/irq-mbigen.c
index ca6add1..3a33de6 100644
--- a/drivers/irqchip/irq-mbigen.c
+++ b/drivers/irqchip/irq-mbigen.c
@@ -374,7 +374,11 @@ static struct platform_driver mbigen_platform_driver = {
 	.probe			= mbigen_device_probe,
 };
 
-module_platform_driver(mbigen_platform_driver);
+static __init int mbigen_init(void)
+{
+	return platform_driver_register(&mbigen_platform_driver);
+}
+arch_initcall(mbigen_init);
 
 MODULE_AUTHOR("Jun Ma <majun258@huawei.com>");
 MODULE_AUTHOR("Yun Wu <wuyun.wu@huawei.com>");
-- 
1.7.12.4

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

* Re: [RFC PATCH v2 05/11] ACPI: platform: setup MSI domain for ACPI based platform device
  2016-09-14 14:21   ` Hanjun Guo
@ 2016-09-14 15:45     ` Marc Zyngier
  -1 siblings, 0 replies; 58+ messages in thread
From: Marc Zyngier @ 2016-09-14 15:45 UTC (permalink / raw)
  To: Hanjun Guo, Rafael J. Wysocki, Lorenzo Pieralisi
  Cc: linux-acpi, linux-arm-kernel, linux-kernel, Thomas Gleixner,
	Bjorn Helgaas, Greg KH, Tomasz Nowicki, Ma Jun, Kefeng Wang,
	Charles Garcia-Tobin, linuxarm, Hanjun Guo

On 14/09/16 15:21, Hanjun Guo wrote:
> From: Hanjun Guo <hanjun.guo@linaro.org>
> 
> With the platform msi domain created, we can set up the msi domain
> for a platform device when it's probed.
> 
> This patch introduces acpi_configure_msi_domain(), which retrieves
> the domain from iort and set it to platform device.
> 
> As some platform devices such as an irqchip needs the msi irqdomain
> to be the interrupt parent domain, we need to get irqdomain before
> platform device is probed.
> 
> Cc: Marc Zyngier <marc.zyngier@arm.com>
> Cc: Greg KH <gregkh@linuxfoundation.org>
> Cc: Thomas Gleixner <tglx@linutronix.de>
> Cc: Bjorn Helgaas <bhelgaas@google.com>
> Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> Cc: Tomasz Nowicki <tn@semihalf.com>
> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
> ---
>  drivers/acpi/arm64/iort.c   |  5 ++++-
>  drivers/base/platform-msi.c | 15 ++++++++++++++-
>  drivers/base/platform.c     |  2 ++
>  include/linux/msi.h         |  1 +
>  4 files changed, 21 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
> index 13a1905..bccd3cc 100644
> --- a/drivers/acpi/arm64/iort.c
> +++ b/drivers/acpi/arm64/iort.c
> @@ -478,6 +478,7 @@ struct irq_domain *iort_get_device_domain(struct device *dev, u32 req_id)
>  {
>  	struct fwnode_handle *handle;
>  	int its_id;
> +	enum irq_domain_bus_token bus_token;
>  
>  	if (iort_dev_find_its_id(dev, req_id, 0, &its_id))
>  		return NULL;
> @@ -486,7 +487,9 @@ struct irq_domain *iort_get_device_domain(struct device *dev, u32 req_id)
>  	if (!handle)
>  		return NULL;
>  
> -	return irq_find_matching_fwnode(handle, DOMAIN_BUS_PCI_MSI);
> +	bus_token = dev_is_pci(dev) ?
> +			DOMAIN_BUS_PCI_MSI : DOMAIN_BUS_PLATFORM_MSI;
> +	return irq_find_matching_fwnode(handle, bus_token);
>  }
>  
>  static int __get_pci_rid(struct pci_dev *pdev, u16 alias, void *data)
> diff --git a/drivers/base/platform-msi.c b/drivers/base/platform-msi.c
> index 279e539..f6eae18 100644
> --- a/drivers/base/platform-msi.c
> +++ b/drivers/base/platform-msi.c
> @@ -17,8 +17,8 @@
>   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
>   */
>  
> +#include <linux/acpi_iort.h>
>  #include <linux/device.h>
> -#include <linux/idr.h>
>  #include <linux/irq.h>
>  #include <linux/irqdomain.h>
>  #include <linux/msi.h>
> @@ -416,3 +416,16 @@ int platform_msi_domain_alloc(struct irq_domain *domain, unsigned int virq,
>  
>  	return err;
>  }
> +
> +int acpi_configure_msi_domain(struct device *dev)
> +{
> +	struct irq_domain *d = NULL;
> +
> +	d = iort_get_device_domain(dev, 0);

This looks completely wrong. Why RID 0? As far as I can see, 0 is not a
special value, and could be something else.

> +	if (d) {
> +		dev_set_msi_domain(dev, d);
> +		return 0;
> +	}
> +
> +	return -EINVAL;
> +}

I really hate this, as the platform MSI code is intentionally free of
any firmware reference. This should live in the ACPI code.

> diff --git a/drivers/base/platform.c b/drivers/base/platform.c
> index 6482d47..ea01a37 100644
> --- a/drivers/base/platform.c
> +++ b/drivers/base/platform.c
> @@ -24,6 +24,7 @@
>  #include <linux/pm_domain.h>
>  #include <linux/idr.h>
>  #include <linux/acpi.h>
> +#include <linux/msi.h>
>  #include <linux/clk/clk-conf.h>
>  #include <linux/limits.h>
>  #include <linux/property.h>
> @@ -500,6 +501,7 @@ struct platform_device *platform_device_register_full(
>  	pdev->dev.parent = pdevinfo->parent;
>  	pdev->dev.fwnode = pdevinfo->fwnode;
>  
> +	acpi_configure_msi_domain(&pdev->dev);

It feels odd to put this in the generic code, while you could perfectly
put the call into acpi_platform.c and keep the firmware stuff away from
the generic code.

>  	if (pdevinfo->dma_mask) {
>  		/*
>  		 * This memory isn't freed when the device is put,
> diff --git a/include/linux/msi.h b/include/linux/msi.h
> index e8c81fb..1e93a78 100644
> --- a/include/linux/msi.h
> +++ b/include/linux/msi.h
> @@ -308,6 +308,7 @@ int platform_msi_domain_alloc(struct irq_domain *domain, unsigned int virq,
>  void platform_msi_domain_free(struct irq_domain *domain, unsigned int virq,
>  			      unsigned int nvec);
>  void *platform_msi_get_host_data(struct irq_domain *domain);
> +int acpi_configure_msi_domain(struct device *dev);
>  #endif /* CONFIG_GENERIC_MSI_IRQ_DOMAIN */
>  
>  #ifdef CONFIG_PCI_MSI_IRQ_DOMAIN
> 

Thanks,

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

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

* [RFC PATCH v2 05/11] ACPI: platform: setup MSI domain for ACPI based platform device
@ 2016-09-14 15:45     ` Marc Zyngier
  0 siblings, 0 replies; 58+ messages in thread
From: Marc Zyngier @ 2016-09-14 15:45 UTC (permalink / raw)
  To: linux-arm-kernel

On 14/09/16 15:21, Hanjun Guo wrote:
> From: Hanjun Guo <hanjun.guo@linaro.org>
> 
> With the platform msi domain created, we can set up the msi domain
> for a platform device when it's probed.
> 
> This patch introduces acpi_configure_msi_domain(), which retrieves
> the domain from iort and set it to platform device.
> 
> As some platform devices such as an irqchip needs the msi irqdomain
> to be the interrupt parent domain, we need to get irqdomain before
> platform device is probed.
> 
> Cc: Marc Zyngier <marc.zyngier@arm.com>
> Cc: Greg KH <gregkh@linuxfoundation.org>
> Cc: Thomas Gleixner <tglx@linutronix.de>
> Cc: Bjorn Helgaas <bhelgaas@google.com>
> Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> Cc: Tomasz Nowicki <tn@semihalf.com>
> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
> ---
>  drivers/acpi/arm64/iort.c   |  5 ++++-
>  drivers/base/platform-msi.c | 15 ++++++++++++++-
>  drivers/base/platform.c     |  2 ++
>  include/linux/msi.h         |  1 +
>  4 files changed, 21 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
> index 13a1905..bccd3cc 100644
> --- a/drivers/acpi/arm64/iort.c
> +++ b/drivers/acpi/arm64/iort.c
> @@ -478,6 +478,7 @@ struct irq_domain *iort_get_device_domain(struct device *dev, u32 req_id)
>  {
>  	struct fwnode_handle *handle;
>  	int its_id;
> +	enum irq_domain_bus_token bus_token;
>  
>  	if (iort_dev_find_its_id(dev, req_id, 0, &its_id))
>  		return NULL;
> @@ -486,7 +487,9 @@ struct irq_domain *iort_get_device_domain(struct device *dev, u32 req_id)
>  	if (!handle)
>  		return NULL;
>  
> -	return irq_find_matching_fwnode(handle, DOMAIN_BUS_PCI_MSI);
> +	bus_token = dev_is_pci(dev) ?
> +			DOMAIN_BUS_PCI_MSI : DOMAIN_BUS_PLATFORM_MSI;
> +	return irq_find_matching_fwnode(handle, bus_token);
>  }
>  
>  static int __get_pci_rid(struct pci_dev *pdev, u16 alias, void *data)
> diff --git a/drivers/base/platform-msi.c b/drivers/base/platform-msi.c
> index 279e539..f6eae18 100644
> --- a/drivers/base/platform-msi.c
> +++ b/drivers/base/platform-msi.c
> @@ -17,8 +17,8 @@
>   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
>   */
>  
> +#include <linux/acpi_iort.h>
>  #include <linux/device.h>
> -#include <linux/idr.h>
>  #include <linux/irq.h>
>  #include <linux/irqdomain.h>
>  #include <linux/msi.h>
> @@ -416,3 +416,16 @@ int platform_msi_domain_alloc(struct irq_domain *domain, unsigned int virq,
>  
>  	return err;
>  }
> +
> +int acpi_configure_msi_domain(struct device *dev)
> +{
> +	struct irq_domain *d = NULL;
> +
> +	d = iort_get_device_domain(dev, 0);

This looks completely wrong. Why RID 0? As far as I can see, 0 is not a
special value, and could be something else.

> +	if (d) {
> +		dev_set_msi_domain(dev, d);
> +		return 0;
> +	}
> +
> +	return -EINVAL;
> +}

I really hate this, as the platform MSI code is intentionally free of
any firmware reference. This should live in the ACPI code.

> diff --git a/drivers/base/platform.c b/drivers/base/platform.c
> index 6482d47..ea01a37 100644
> --- a/drivers/base/platform.c
> +++ b/drivers/base/platform.c
> @@ -24,6 +24,7 @@
>  #include <linux/pm_domain.h>
>  #include <linux/idr.h>
>  #include <linux/acpi.h>
> +#include <linux/msi.h>
>  #include <linux/clk/clk-conf.h>
>  #include <linux/limits.h>
>  #include <linux/property.h>
> @@ -500,6 +501,7 @@ struct platform_device *platform_device_register_full(
>  	pdev->dev.parent = pdevinfo->parent;
>  	pdev->dev.fwnode = pdevinfo->fwnode;
>  
> +	acpi_configure_msi_domain(&pdev->dev);

It feels odd to put this in the generic code, while you could perfectly
put the call into acpi_platform.c and keep the firmware stuff away from
the generic code.

>  	if (pdevinfo->dma_mask) {
>  		/*
>  		 * This memory isn't freed when the device is put,
> diff --git a/include/linux/msi.h b/include/linux/msi.h
> index e8c81fb..1e93a78 100644
> --- a/include/linux/msi.h
> +++ b/include/linux/msi.h
> @@ -308,6 +308,7 @@ int platform_msi_domain_alloc(struct irq_domain *domain, unsigned int virq,
>  void platform_msi_domain_free(struct irq_domain *domain, unsigned int virq,
>  			      unsigned int nvec);
>  void *platform_msi_get_host_data(struct irq_domain *domain);
> +int acpi_configure_msi_domain(struct device *dev);
>  #endif /* CONFIG_GENERIC_MSI_IRQ_DOMAIN */
>  
>  #ifdef CONFIG_PCI_MSI_IRQ_DOMAIN
> 

Thanks,

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

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

* Re: [RFC PATCH v2 10/11] irqchip: mbigen: Add ACPI support
  2016-09-14 14:21   ` Hanjun Guo
  (?)
@ 2016-09-15  8:49     ` Marc Zyngier
  -1 siblings, 0 replies; 58+ messages in thread
From: Marc Zyngier @ 2016-09-15  8:49 UTC (permalink / raw)
  To: Hanjun Guo, Rafael J. Wysocki, Lorenzo Pieralisi
  Cc: Kefeng Wang, Greg KH, linux-kernel, linuxarm, linux-acpi,
	Hanjun Guo, Tomasz Nowicki, Bjorn Helgaas, Thomas Gleixner,
	Charles Garcia-Tobin, linux-arm-kernel, Ma Jun

On 14/09/16 15:21, Hanjun Guo wrote:
> From: Hanjun Guo <hanjun.guo@linaro.org>
> 
> With the preparation of platform msi support and interrupt producer
> in DSDT, we can add mbigen ACPI support now.
> 
> We are using _PRS methd to indicate number of irq pins instead
> of num_pins in DT.
> 
> For mbi-gen,
>     Device(MBI0) {
>           Name(_HID, "HISI0152")
>           Name(_UID, Zero)
>           Name(_CRS, ResourceTemplate() {
>                   Memory32Fixed(ReadWrite, 0xa0080000, 0x10000)
>           })
> 
>           Name (_PRS, ResourceTemplate() {
> 		  Interrupt(ResourceProducer,...) {12,14,....}
>           })

Since I know next to nothing about all of this, I'm going to play the
village idiot. What makes it legal to use _PRS as a way to describe the
interrupts that are exposed by MBI0? Looking at the 6.0 spec, I do not
see why the interrupts would be put there instead of _CRS, and why you'd
have a _PRS at all.

Also, are you going to exhaustively describe all the possible interrupts
via this method? Knowing that the mbigen can expose thousands of
interrupts, I find it slightly mad. Can't you express a range?

>     }
> 
> For devices,
> 
>    Device(COM0) {
>           Name(_HID, "ACPIIDxx")
>           Name(_UID, Zero)
>           Name(_CRS, ResourceTemplate() {
>                  Memory32Fixed(ReadWrite, 0xb0030000, 0x10000)
> 		 Interrupt(ResourceConsumer,..., "\_SB.MBI0") {12}
>           })
>     }
> 
> With the helpe of platform msi and interrupt producer, then devices
> will get the virq from mbi-gen's irqdomain.
> 
> Cc: Marc Zyngier <marc.zyngier@arm.com>
> Cc: Thomas Gleixner <tglx@linutronix.de>
> Cc: Ma Jun <majun258@huawei.com>
> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
> ---
>  drivers/irqchip/irq-mbigen.c | 70 ++++++++++++++++++++++++++++++++++++++++++--
>  1 file changed, 67 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/irqchip/irq-mbigen.c b/drivers/irqchip/irq-mbigen.c
> index 9484ea0..ca6add1 100644
> --- a/drivers/irqchip/irq-mbigen.c
> +++ b/drivers/irqchip/irq-mbigen.c
> @@ -16,6 +16,7 @@
>   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
>   */
>  
> +#include <linux/acpi.h>
>  #include <linux/interrupt.h>
>  #include <linux/irqchip.h>
>  #include <linux/module.h>
> @@ -180,7 +181,7 @@ static int mbigen_domain_translate(struct irq_domain *d,
>  				    unsigned long *hwirq,
>  				    unsigned int *type)
>  {
> -	if (is_of_node(fwspec->fwnode)) {
> +	if (is_of_node(fwspec->fwnode) || is_acpi_device_node(fwspec->fwnode)) {
>  		if (fwspec->param_count != 2)
>  			return -EINVAL;
>  
> @@ -271,6 +272,54 @@ static int mbigen_of_create_domain(struct platform_device *pdev,
>  	return 0;
>  }
>  
> +#ifdef CONFIG_ACPI
> +static acpi_status mbigen_acpi_process_resource(struct acpi_resource *ares,
> +					     void *context)
> +{
> +	struct acpi_resource_extended_irq *ext_irq;
> +	u32 *num_irqs = context;
> +
> +	switch (ares->type) {
> +	case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
> +		ext_irq = &ares->data.extended_irq;
> +		*num_irqs += ext_irq->interrupt_count;
> +		break;
> +	default:
> +		break;
> +	}
> +
> +	return AE_OK;
> +}
> +
> +static int mbigen_acpi_create_domain(struct platform_device *pdev,
> +				     struct mbigen_device *mgn_chip)
> +{
> +	struct irq_domain *domain;
> +	u32 num_msis = 0;
> +	acpi_status status;
> +
> +	status = acpi_walk_resources(ACPI_HANDLE(&pdev->dev), METHOD_NAME__PRS,
> +				     mbigen_acpi_process_resource, &num_msis);
> +        if (ACPI_FAILURE(status) || num_msis == 0)
> +		return -EINVAL;
> +
> +	domain = platform_msi_create_device_domain(&pdev->dev, num_msis,
> +						   mbigen_write_msg,
> +						   &mbigen_domain_ops,
> +						   mgn_chip);
> +	if (!domain)
> +		return -ENOMEM;
> +
> +	return 0;
> +}
> +#else
> +static int mbigen_acpi_create_domain(struct platform_device *pdev,
> +				     struct mbigen_device *mgn_chip)
> +{
> +	return -ENODEV;
> +}
> +#endif
> +
>  static int mbigen_device_probe(struct platform_device *pdev)
>  {
>  	struct mbigen_device *mgn_chip;
> @@ -288,9 +337,17 @@ static int mbigen_device_probe(struct platform_device *pdev)
>  	if (IS_ERR(mgn_chip->base))
>  		return PTR_ERR(mgn_chip->base);
>  
> -	err = mbigen_of_create_domain(pdev, mgn_chip);
> -	if (err)
> +	if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node)
> +		err = mbigen_of_create_domain(pdev, mgn_chip);
> +	else if (ACPI_COMPANION(&pdev->dev))
> +		err = mbigen_acpi_create_domain(pdev, mgn_chip);
> +	else
> +		err = -EINVAL;
> +
> +	if (err) {
> +		dev_err(&pdev->dev, "Failed to create mbi-gen@%p irqdomain", mgn_chip->base);
>  		return err;
> +	}
>  
>  	platform_set_drvdata(pdev, mgn_chip);
>  	return 0;
> @@ -302,10 +359,17 @@ static const struct of_device_id mbigen_of_match[] = {
>  };
>  MODULE_DEVICE_TABLE(of, mbigen_of_match);
>  
> +static const struct acpi_device_id mbigen_acpi_match[] = {
> +        { "HISI0152", 0 },
> +	{}
> +};
> +MODULE_DEVICE_TABLE(acpi, mbigen_acpi_match);
> +
>  static struct platform_driver mbigen_platform_driver = {
>  	.driver = {
>  		.name		= "Hisilicon MBIGEN-V2",
>  		.of_match_table	= mbigen_of_match,
> +		.acpi_match_table = ACPI_PTR(mbigen_acpi_match),
>  	},
>  	.probe			= mbigen_device_probe,
>  };
> 

Thanks,

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

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

* Re: [RFC PATCH v2 10/11] irqchip: mbigen: Add ACPI support
@ 2016-09-15  8:49     ` Marc Zyngier
  0 siblings, 0 replies; 58+ messages in thread
From: Marc Zyngier @ 2016-09-15  8:49 UTC (permalink / raw)
  To: Hanjun Guo, Rafael J. Wysocki, Lorenzo Pieralisi
  Cc: linux-acpi, linux-arm-kernel, linux-kernel, Thomas Gleixner,
	Bjorn Helgaas, Greg KH, Tomasz Nowicki, Ma Jun, Kefeng Wang,
	Charles Garcia-Tobin, linuxarm, Hanjun Guo

On 14/09/16 15:21, Hanjun Guo wrote:
> From: Hanjun Guo <hanjun.guo@linaro.org>
> 
> With the preparation of platform msi support and interrupt producer
> in DSDT, we can add mbigen ACPI support now.
> 
> We are using _PRS methd to indicate number of irq pins instead
> of num_pins in DT.
> 
> For mbi-gen,
>     Device(MBI0) {
>           Name(_HID, "HISI0152")
>           Name(_UID, Zero)
>           Name(_CRS, ResourceTemplate() {
>                   Memory32Fixed(ReadWrite, 0xa0080000, 0x10000)
>           })
> 
>           Name (_PRS, ResourceTemplate() {
> 		  Interrupt(ResourceProducer,...) {12,14,....}
>           })

Since I know next to nothing about all of this, I'm going to play the
village idiot. What makes it legal to use _PRS as a way to describe the
interrupts that are exposed by MBI0? Looking at the 6.0 spec, I do not
see why the interrupts would be put there instead of _CRS, and why you'd
have a _PRS at all.

Also, are you going to exhaustively describe all the possible interrupts
via this method? Knowing that the mbigen can expose thousands of
interrupts, I find it slightly mad. Can't you express a range?

>     }
> 
> For devices,
> 
>    Device(COM0) {
>           Name(_HID, "ACPIIDxx")
>           Name(_UID, Zero)
>           Name(_CRS, ResourceTemplate() {
>                  Memory32Fixed(ReadWrite, 0xb0030000, 0x10000)
> 		 Interrupt(ResourceConsumer,..., "\_SB.MBI0") {12}
>           })
>     }
> 
> With the helpe of platform msi and interrupt producer, then devices
> will get the virq from mbi-gen's irqdomain.
> 
> Cc: Marc Zyngier <marc.zyngier@arm.com>
> Cc: Thomas Gleixner <tglx@linutronix.de>
> Cc: Ma Jun <majun258@huawei.com>
> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
> ---
>  drivers/irqchip/irq-mbigen.c | 70 ++++++++++++++++++++++++++++++++++++++++++--
>  1 file changed, 67 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/irqchip/irq-mbigen.c b/drivers/irqchip/irq-mbigen.c
> index 9484ea0..ca6add1 100644
> --- a/drivers/irqchip/irq-mbigen.c
> +++ b/drivers/irqchip/irq-mbigen.c
> @@ -16,6 +16,7 @@
>   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
>   */
>  
> +#include <linux/acpi.h>
>  #include <linux/interrupt.h>
>  #include <linux/irqchip.h>
>  #include <linux/module.h>
> @@ -180,7 +181,7 @@ static int mbigen_domain_translate(struct irq_domain *d,
>  				    unsigned long *hwirq,
>  				    unsigned int *type)
>  {
> -	if (is_of_node(fwspec->fwnode)) {
> +	if (is_of_node(fwspec->fwnode) || is_acpi_device_node(fwspec->fwnode)) {
>  		if (fwspec->param_count != 2)
>  			return -EINVAL;
>  
> @@ -271,6 +272,54 @@ static int mbigen_of_create_domain(struct platform_device *pdev,
>  	return 0;
>  }
>  
> +#ifdef CONFIG_ACPI
> +static acpi_status mbigen_acpi_process_resource(struct acpi_resource *ares,
> +					     void *context)
> +{
> +	struct acpi_resource_extended_irq *ext_irq;
> +	u32 *num_irqs = context;
> +
> +	switch (ares->type) {
> +	case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
> +		ext_irq = &ares->data.extended_irq;
> +		*num_irqs += ext_irq->interrupt_count;
> +		break;
> +	default:
> +		break;
> +	}
> +
> +	return AE_OK;
> +}
> +
> +static int mbigen_acpi_create_domain(struct platform_device *pdev,
> +				     struct mbigen_device *mgn_chip)
> +{
> +	struct irq_domain *domain;
> +	u32 num_msis = 0;
> +	acpi_status status;
> +
> +	status = acpi_walk_resources(ACPI_HANDLE(&pdev->dev), METHOD_NAME__PRS,
> +				     mbigen_acpi_process_resource, &num_msis);
> +        if (ACPI_FAILURE(status) || num_msis == 0)
> +		return -EINVAL;
> +
> +	domain = platform_msi_create_device_domain(&pdev->dev, num_msis,
> +						   mbigen_write_msg,
> +						   &mbigen_domain_ops,
> +						   mgn_chip);
> +	if (!domain)
> +		return -ENOMEM;
> +
> +	return 0;
> +}
> +#else
> +static int mbigen_acpi_create_domain(struct platform_device *pdev,
> +				     struct mbigen_device *mgn_chip)
> +{
> +	return -ENODEV;
> +}
> +#endif
> +
>  static int mbigen_device_probe(struct platform_device *pdev)
>  {
>  	struct mbigen_device *mgn_chip;
> @@ -288,9 +337,17 @@ static int mbigen_device_probe(struct platform_device *pdev)
>  	if (IS_ERR(mgn_chip->base))
>  		return PTR_ERR(mgn_chip->base);
>  
> -	err = mbigen_of_create_domain(pdev, mgn_chip);
> -	if (err)
> +	if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node)
> +		err = mbigen_of_create_domain(pdev, mgn_chip);
> +	else if (ACPI_COMPANION(&pdev->dev))
> +		err = mbigen_acpi_create_domain(pdev, mgn_chip);
> +	else
> +		err = -EINVAL;
> +
> +	if (err) {
> +		dev_err(&pdev->dev, "Failed to create mbi-gen@%p irqdomain", mgn_chip->base);
>  		return err;
> +	}
>  
>  	platform_set_drvdata(pdev, mgn_chip);
>  	return 0;
> @@ -302,10 +359,17 @@ static const struct of_device_id mbigen_of_match[] = {
>  };
>  MODULE_DEVICE_TABLE(of, mbigen_of_match);
>  
> +static const struct acpi_device_id mbigen_acpi_match[] = {
> +        { "HISI0152", 0 },
> +	{}
> +};
> +MODULE_DEVICE_TABLE(acpi, mbigen_acpi_match);
> +
>  static struct platform_driver mbigen_platform_driver = {
>  	.driver = {
>  		.name		= "Hisilicon MBIGEN-V2",
>  		.of_match_table	= mbigen_of_match,
> +		.acpi_match_table = ACPI_PTR(mbigen_acpi_match),
>  	},
>  	.probe			= mbigen_device_probe,
>  };
> 

Thanks,

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

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

* [RFC PATCH v2 10/11] irqchip: mbigen: Add ACPI support
@ 2016-09-15  8:49     ` Marc Zyngier
  0 siblings, 0 replies; 58+ messages in thread
From: Marc Zyngier @ 2016-09-15  8:49 UTC (permalink / raw)
  To: linux-arm-kernel

On 14/09/16 15:21, Hanjun Guo wrote:
> From: Hanjun Guo <hanjun.guo@linaro.org>
> 
> With the preparation of platform msi support and interrupt producer
> in DSDT, we can add mbigen ACPI support now.
> 
> We are using _PRS methd to indicate number of irq pins instead
> of num_pins in DT.
> 
> For mbi-gen,
>     Device(MBI0) {
>           Name(_HID, "HISI0152")
>           Name(_UID, Zero)
>           Name(_CRS, ResourceTemplate() {
>                   Memory32Fixed(ReadWrite, 0xa0080000, 0x10000)
>           })
> 
>           Name (_PRS, ResourceTemplate() {
> 		  Interrupt(ResourceProducer,...) {12,14,....}
>           })

Since I know next to nothing about all of this, I'm going to play the
village idiot. What makes it legal to use _PRS as a way to describe the
interrupts that are exposed by MBI0? Looking at the 6.0 spec, I do not
see why the interrupts would be put there instead of _CRS, and why you'd
have a _PRS at all.

Also, are you going to exhaustively describe all the possible interrupts
via this method? Knowing that the mbigen can expose thousands of
interrupts, I find it slightly mad. Can't you express a range?

>     }
> 
> For devices,
> 
>    Device(COM0) {
>           Name(_HID, "ACPIIDxx")
>           Name(_UID, Zero)
>           Name(_CRS, ResourceTemplate() {
>                  Memory32Fixed(ReadWrite, 0xb0030000, 0x10000)
> 		 Interrupt(ResourceConsumer,..., "\_SB.MBI0") {12}
>           })
>     }
> 
> With the helpe of platform msi and interrupt producer, then devices
> will get the virq from mbi-gen's irqdomain.
> 
> Cc: Marc Zyngier <marc.zyngier@arm.com>
> Cc: Thomas Gleixner <tglx@linutronix.de>
> Cc: Ma Jun <majun258@huawei.com>
> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
> ---
>  drivers/irqchip/irq-mbigen.c | 70 ++++++++++++++++++++++++++++++++++++++++++--
>  1 file changed, 67 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/irqchip/irq-mbigen.c b/drivers/irqchip/irq-mbigen.c
> index 9484ea0..ca6add1 100644
> --- a/drivers/irqchip/irq-mbigen.c
> +++ b/drivers/irqchip/irq-mbigen.c
> @@ -16,6 +16,7 @@
>   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
>   */
>  
> +#include <linux/acpi.h>
>  #include <linux/interrupt.h>
>  #include <linux/irqchip.h>
>  #include <linux/module.h>
> @@ -180,7 +181,7 @@ static int mbigen_domain_translate(struct irq_domain *d,
>  				    unsigned long *hwirq,
>  				    unsigned int *type)
>  {
> -	if (is_of_node(fwspec->fwnode)) {
> +	if (is_of_node(fwspec->fwnode) || is_acpi_device_node(fwspec->fwnode)) {
>  		if (fwspec->param_count != 2)
>  			return -EINVAL;
>  
> @@ -271,6 +272,54 @@ static int mbigen_of_create_domain(struct platform_device *pdev,
>  	return 0;
>  }
>  
> +#ifdef CONFIG_ACPI
> +static acpi_status mbigen_acpi_process_resource(struct acpi_resource *ares,
> +					     void *context)
> +{
> +	struct acpi_resource_extended_irq *ext_irq;
> +	u32 *num_irqs = context;
> +
> +	switch (ares->type) {
> +	case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
> +		ext_irq = &ares->data.extended_irq;
> +		*num_irqs += ext_irq->interrupt_count;
> +		break;
> +	default:
> +		break;
> +	}
> +
> +	return AE_OK;
> +}
> +
> +static int mbigen_acpi_create_domain(struct platform_device *pdev,
> +				     struct mbigen_device *mgn_chip)
> +{
> +	struct irq_domain *domain;
> +	u32 num_msis = 0;
> +	acpi_status status;
> +
> +	status = acpi_walk_resources(ACPI_HANDLE(&pdev->dev), METHOD_NAME__PRS,
> +				     mbigen_acpi_process_resource, &num_msis);
> +        if (ACPI_FAILURE(status) || num_msis == 0)
> +		return -EINVAL;
> +
> +	domain = platform_msi_create_device_domain(&pdev->dev, num_msis,
> +						   mbigen_write_msg,
> +						   &mbigen_domain_ops,
> +						   mgn_chip);
> +	if (!domain)
> +		return -ENOMEM;
> +
> +	return 0;
> +}
> +#else
> +static int mbigen_acpi_create_domain(struct platform_device *pdev,
> +				     struct mbigen_device *mgn_chip)
> +{
> +	return -ENODEV;
> +}
> +#endif
> +
>  static int mbigen_device_probe(struct platform_device *pdev)
>  {
>  	struct mbigen_device *mgn_chip;
> @@ -288,9 +337,17 @@ static int mbigen_device_probe(struct platform_device *pdev)
>  	if (IS_ERR(mgn_chip->base))
>  		return PTR_ERR(mgn_chip->base);
>  
> -	err = mbigen_of_create_domain(pdev, mgn_chip);
> -	if (err)
> +	if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node)
> +		err = mbigen_of_create_domain(pdev, mgn_chip);
> +	else if (ACPI_COMPANION(&pdev->dev))
> +		err = mbigen_acpi_create_domain(pdev, mgn_chip);
> +	else
> +		err = -EINVAL;
> +
> +	if (err) {
> +		dev_err(&pdev->dev, "Failed to create mbi-gen@%p irqdomain", mgn_chip->base);
>  		return err;
> +	}
>  
>  	platform_set_drvdata(pdev, mgn_chip);
>  	return 0;
> @@ -302,10 +359,17 @@ static const struct of_device_id mbigen_of_match[] = {
>  };
>  MODULE_DEVICE_TABLE(of, mbigen_of_match);
>  
> +static const struct acpi_device_id mbigen_acpi_match[] = {
> +        { "HISI0152", 0 },
> +	{}
> +};
> +MODULE_DEVICE_TABLE(acpi, mbigen_acpi_match);
> +
>  static struct platform_driver mbigen_platform_driver = {
>  	.driver = {
>  		.name		= "Hisilicon MBIGEN-V2",
>  		.of_match_table	= mbigen_of_match,
> +		.acpi_match_table = ACPI_PTR(mbigen_acpi_match),
>  	},
>  	.probe			= mbigen_device_probe,
>  };
> 

Thanks,

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

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

* Re: [RFC PATCH v2 05/11] ACPI: platform: setup MSI domain for ACPI based platform device
  2016-09-14 15:45     ` Marc Zyngier
@ 2016-09-15 14:05       ` Hanjun Guo
  -1 siblings, 0 replies; 58+ messages in thread
From: Hanjun Guo @ 2016-09-15 14:05 UTC (permalink / raw)
  To: Marc Zyngier, Hanjun Guo, Rafael J. Wysocki, Lorenzo Pieralisi
  Cc: linux-acpi, linux-arm-kernel, linux-kernel, Thomas Gleixner,
	Bjorn Helgaas, Greg KH, Tomasz Nowicki, Ma Jun, Kefeng Wang,
	Charles Garcia-Tobin, linuxarm

Hi Marc,

Thanks for your review, reply inline.

On 09/14/2016 11:45 PM, Marc Zyngier wrote:
> On 14/09/16 15:21, Hanjun Guo wrote:
>> From: Hanjun Guo <hanjun.guo@linaro.org>
>>
>> With the platform msi domain created, we can set up the msi domain
>> for a platform device when it's probed.
>>
>> This patch introduces acpi_configure_msi_domain(), which retrieves
>> the domain from iort and set it to platform device.
>>
>> As some platform devices such as an irqchip needs the msi irqdomain
>> to be the interrupt parent domain, we need to get irqdomain before
>> platform device is probed.
>>
>> Cc: Marc Zyngier <marc.zyngier@arm.com>
>> Cc: Greg KH <gregkh@linuxfoundation.org>
>> Cc: Thomas Gleixner <tglx@linutronix.de>
>> Cc: Bjorn Helgaas <bhelgaas@google.com>
>> Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
>> Cc: Tomasz Nowicki <tn@semihalf.com>
>> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
>> ---
>>   drivers/acpi/arm64/iort.c   |  5 ++++-
>>   drivers/base/platform-msi.c | 15 ++++++++++++++-
>>   drivers/base/platform.c     |  2 ++
>>   include/linux/msi.h         |  1 +
>>   4 files changed, 21 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
>> index 13a1905..bccd3cc 100644
>> --- a/drivers/acpi/arm64/iort.c
>> +++ b/drivers/acpi/arm64/iort.c
>> @@ -478,6 +478,7 @@ struct irq_domain *iort_get_device_domain(struct device *dev, u32 req_id)
>>   {
>>   	struct fwnode_handle *handle;
>>   	int its_id;
>> +	enum irq_domain_bus_token bus_token;
>>
>>   	if (iort_dev_find_its_id(dev, req_id, 0, &its_id))
>>   		return NULL;
>> @@ -486,7 +487,9 @@ struct irq_domain *iort_get_device_domain(struct device *dev, u32 req_id)
>>   	if (!handle)
>>   		return NULL;
>>
>> -	return irq_find_matching_fwnode(handle, DOMAIN_BUS_PCI_MSI);
>> +	bus_token = dev_is_pci(dev) ?
>> +			DOMAIN_BUS_PCI_MSI : DOMAIN_BUS_PLATFORM_MSI;
>> +	return irq_find_matching_fwnode(handle, bus_token);
>>   }
>>
>>   static int __get_pci_rid(struct pci_dev *pdev, u16 alias, void *data)
>> diff --git a/drivers/base/platform-msi.c b/drivers/base/platform-msi.c
>> index 279e539..f6eae18 100644
>> --- a/drivers/base/platform-msi.c
>> +++ b/drivers/base/platform-msi.c
>> @@ -17,8 +17,8 @@
>>    * along with this program.  If not, see <http://www.gnu.org/licenses/>.
>>    */
>>
>> +#include <linux/acpi_iort.h>
>>   #include <linux/device.h>
>> -#include <linux/idr.h>
>>   #include <linux/irq.h>
>>   #include <linux/irqdomain.h>
>>   #include <linux/msi.h>
>> @@ -416,3 +416,16 @@ int platform_msi_domain_alloc(struct irq_domain *domain, unsigned int virq,
>>
>>   	return err;
>>   }
>> +
>> +int acpi_configure_msi_domain(struct device *dev)
>> +{
>> +	struct irq_domain *d = NULL;
>> +
>> +	d = iort_get_device_domain(dev, 0);
>
> This looks completely wrong. Why RID 0? As far as I can see, 0 is not a
> special value, and could be something else.

You are right. I tried to reuse the API of get irqdomain in IORT for
PCI devices, but for platform device, we don't have req id in named
component, so I just pass 0 here, I think I need to prepare another
API for platform devices.

>
>> +	if (d) {
>> +		dev_set_msi_domain(dev, d);
>> +		return 0;
>> +	}
>> +
>> +	return -EINVAL;
>> +}
>
> I really hate this, as the platform MSI code is intentionally free of
> any firmware reference. This should live in the ACPI code.

Will do, I think locate it in iort.c is better.

>
>> diff --git a/drivers/base/platform.c b/drivers/base/platform.c
>> index 6482d47..ea01a37 100644
>> --- a/drivers/base/platform.c
>> +++ b/drivers/base/platform.c
>> @@ -24,6 +24,7 @@
>>   #include <linux/pm_domain.h>
>>   #include <linux/idr.h>
>>   #include <linux/acpi.h>
>> +#include <linux/msi.h>
>>   #include <linux/clk/clk-conf.h>
>>   #include <linux/limits.h>
>>   #include <linux/property.h>
>> @@ -500,6 +501,7 @@ struct platform_device *platform_device_register_full(
>>   	pdev->dev.parent = pdevinfo->parent;
>>   	pdev->dev.fwnode = pdevinfo->fwnode;
>>
>> +	acpi_configure_msi_domain(&pdev->dev);
>
> It feels odd to put this in the generic code, while you could perfectly
> put the call into acpi_platform.c and keep the firmware stuff away from
> the generic code.

My feeling is the same, I'm still trying to find a new way to do it,
but I can't simply put that in acpi_platform.c, because

acpi_create_platform_device()
    platform_device_register_full()
	platform_device_alloc()  --> dev is alloced
         ...
         dev.fwnode  is set
	(I get the msi domain by the fwnode in acpi_configure_msi_domain)
         ...
         platform_device_add()  --> which the device is probed.

For devices like irqchip which needs the dev->msi_domain to be
set before it's really probed, because it needs the msi domain
to be the parent domain.

If I call the function in acpi_create_platform_device() before
platform_device_register_full(), we just can't set dev's msi
domain, but if call it after platform_device_register_full(),
the irqchip like mbigen will not get its parent domain...

DT is using another API for platform device probe, so has no
problems like I said above, any suggestions to do it right in
ACPI?

Thanks
Hanjun

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

* [RFC PATCH v2 05/11] ACPI: platform: setup MSI domain for ACPI based platform device
@ 2016-09-15 14:05       ` Hanjun Guo
  0 siblings, 0 replies; 58+ messages in thread
From: Hanjun Guo @ 2016-09-15 14:05 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Marc,

Thanks for your review, reply inline.

On 09/14/2016 11:45 PM, Marc Zyngier wrote:
> On 14/09/16 15:21, Hanjun Guo wrote:
>> From: Hanjun Guo <hanjun.guo@linaro.org>
>>
>> With the platform msi domain created, we can set up the msi domain
>> for a platform device when it's probed.
>>
>> This patch introduces acpi_configure_msi_domain(), which retrieves
>> the domain from iort and set it to platform device.
>>
>> As some platform devices such as an irqchip needs the msi irqdomain
>> to be the interrupt parent domain, we need to get irqdomain before
>> platform device is probed.
>>
>> Cc: Marc Zyngier <marc.zyngier@arm.com>
>> Cc: Greg KH <gregkh@linuxfoundation.org>
>> Cc: Thomas Gleixner <tglx@linutronix.de>
>> Cc: Bjorn Helgaas <bhelgaas@google.com>
>> Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
>> Cc: Tomasz Nowicki <tn@semihalf.com>
>> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
>> ---
>>   drivers/acpi/arm64/iort.c   |  5 ++++-
>>   drivers/base/platform-msi.c | 15 ++++++++++++++-
>>   drivers/base/platform.c     |  2 ++
>>   include/linux/msi.h         |  1 +
>>   4 files changed, 21 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
>> index 13a1905..bccd3cc 100644
>> --- a/drivers/acpi/arm64/iort.c
>> +++ b/drivers/acpi/arm64/iort.c
>> @@ -478,6 +478,7 @@ struct irq_domain *iort_get_device_domain(struct device *dev, u32 req_id)
>>   {
>>   	struct fwnode_handle *handle;
>>   	int its_id;
>> +	enum irq_domain_bus_token bus_token;
>>
>>   	if (iort_dev_find_its_id(dev, req_id, 0, &its_id))
>>   		return NULL;
>> @@ -486,7 +487,9 @@ struct irq_domain *iort_get_device_domain(struct device *dev, u32 req_id)
>>   	if (!handle)
>>   		return NULL;
>>
>> -	return irq_find_matching_fwnode(handle, DOMAIN_BUS_PCI_MSI);
>> +	bus_token = dev_is_pci(dev) ?
>> +			DOMAIN_BUS_PCI_MSI : DOMAIN_BUS_PLATFORM_MSI;
>> +	return irq_find_matching_fwnode(handle, bus_token);
>>   }
>>
>>   static int __get_pci_rid(struct pci_dev *pdev, u16 alias, void *data)
>> diff --git a/drivers/base/platform-msi.c b/drivers/base/platform-msi.c
>> index 279e539..f6eae18 100644
>> --- a/drivers/base/platform-msi.c
>> +++ b/drivers/base/platform-msi.c
>> @@ -17,8 +17,8 @@
>>    * along with this program.  If not, see <http://www.gnu.org/licenses/>.
>>    */
>>
>> +#include <linux/acpi_iort.h>
>>   #include <linux/device.h>
>> -#include <linux/idr.h>
>>   #include <linux/irq.h>
>>   #include <linux/irqdomain.h>
>>   #include <linux/msi.h>
>> @@ -416,3 +416,16 @@ int platform_msi_domain_alloc(struct irq_domain *domain, unsigned int virq,
>>
>>   	return err;
>>   }
>> +
>> +int acpi_configure_msi_domain(struct device *dev)
>> +{
>> +	struct irq_domain *d = NULL;
>> +
>> +	d = iort_get_device_domain(dev, 0);
>
> This looks completely wrong. Why RID 0? As far as I can see, 0 is not a
> special value, and could be something else.

You are right. I tried to reuse the API of get irqdomain in IORT for
PCI devices, but for platform device, we don't have req id in named
component, so I just pass 0 here, I think I need to prepare another
API for platform devices.

>
>> +	if (d) {
>> +		dev_set_msi_domain(dev, d);
>> +		return 0;
>> +	}
>> +
>> +	return -EINVAL;
>> +}
>
> I really hate this, as the platform MSI code is intentionally free of
> any firmware reference. This should live in the ACPI code.

Will do, I think locate it in iort.c is better.

>
>> diff --git a/drivers/base/platform.c b/drivers/base/platform.c
>> index 6482d47..ea01a37 100644
>> --- a/drivers/base/platform.c
>> +++ b/drivers/base/platform.c
>> @@ -24,6 +24,7 @@
>>   #include <linux/pm_domain.h>
>>   #include <linux/idr.h>
>>   #include <linux/acpi.h>
>> +#include <linux/msi.h>
>>   #include <linux/clk/clk-conf.h>
>>   #include <linux/limits.h>
>>   #include <linux/property.h>
>> @@ -500,6 +501,7 @@ struct platform_device *platform_device_register_full(
>>   	pdev->dev.parent = pdevinfo->parent;
>>   	pdev->dev.fwnode = pdevinfo->fwnode;
>>
>> +	acpi_configure_msi_domain(&pdev->dev);
>
> It feels odd to put this in the generic code, while you could perfectly
> put the call into acpi_platform.c and keep the firmware stuff away from
> the generic code.

My feeling is the same, I'm still trying to find a new way to do it,
but I can't simply put that in acpi_platform.c, because

acpi_create_platform_device()
    platform_device_register_full()
	platform_device_alloc()  --> dev is alloced
         ...
         dev.fwnode  is set
	(I get the msi domain by the fwnode in acpi_configure_msi_domain)
         ...
         platform_device_add()  --> which the device is probed.

For devices like irqchip which needs the dev->msi_domain to be
set before it's really probed, because it needs the msi domain
to be the parent domain.

If I call the function in acpi_create_platform_device() before
platform_device_register_full(), we just can't set dev's msi
domain, but if call it after platform_device_register_full(),
the irqchip like mbigen will not get its parent domain...

DT is using another API for platform device probe, so has no
problems like I said above, any suggestions to do it right in
ACPI?

Thanks
Hanjun

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

* Re: [RFC PATCH v2 05/11] ACPI: platform: setup MSI domain for ACPI based platform device
  2016-09-15 14:05       ` Hanjun Guo
@ 2016-09-15 15:18         ` Marc Zyngier
  -1 siblings, 0 replies; 58+ messages in thread
From: Marc Zyngier @ 2016-09-15 15:18 UTC (permalink / raw)
  To: Hanjun Guo, Hanjun Guo, Rafael J. Wysocki, Lorenzo Pieralisi
  Cc: linux-acpi, linux-arm-kernel, linux-kernel, Thomas Gleixner,
	Bjorn Helgaas, Greg KH, Tomasz Nowicki, Ma Jun, Kefeng Wang,
	Charles Garcia-Tobin, linuxarm

On 15/09/16 15:05, Hanjun Guo wrote:
> Hi Marc,
> 
> Thanks for your review, reply inline.
> 
> On 09/14/2016 11:45 PM, Marc Zyngier wrote:
>> On 14/09/16 15:21, Hanjun Guo wrote:
>>> From: Hanjun Guo <hanjun.guo@linaro.org>
>>>
>>> With the platform msi domain created, we can set up the msi domain
>>> for a platform device when it's probed.
>>>
>>> This patch introduces acpi_configure_msi_domain(), which retrieves
>>> the domain from iort and set it to platform device.
>>>
>>> As some platform devices such as an irqchip needs the msi irqdomain
>>> to be the interrupt parent domain, we need to get irqdomain before
>>> platform device is probed.
>>>
>>> Cc: Marc Zyngier <marc.zyngier@arm.com>
>>> Cc: Greg KH <gregkh@linuxfoundation.org>
>>> Cc: Thomas Gleixner <tglx@linutronix.de>
>>> Cc: Bjorn Helgaas <bhelgaas@google.com>
>>> Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
>>> Cc: Tomasz Nowicki <tn@semihalf.com>
>>> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
>>> ---
>>>   drivers/acpi/arm64/iort.c   |  5 ++++-
>>>   drivers/base/platform-msi.c | 15 ++++++++++++++-
>>>   drivers/base/platform.c     |  2 ++
>>>   include/linux/msi.h         |  1 +
>>>   4 files changed, 21 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
>>> index 13a1905..bccd3cc 100644
>>> --- a/drivers/acpi/arm64/iort.c
>>> +++ b/drivers/acpi/arm64/iort.c
>>> @@ -478,6 +478,7 @@ struct irq_domain *iort_get_device_domain(struct device *dev, u32 req_id)
>>>   {
>>>   	struct fwnode_handle *handle;
>>>   	int its_id;
>>> +	enum irq_domain_bus_token bus_token;
>>>
>>>   	if (iort_dev_find_its_id(dev, req_id, 0, &its_id))
>>>   		return NULL;
>>> @@ -486,7 +487,9 @@ struct irq_domain *iort_get_device_domain(struct device *dev, u32 req_id)
>>>   	if (!handle)
>>>   		return NULL;
>>>
>>> -	return irq_find_matching_fwnode(handle, DOMAIN_BUS_PCI_MSI);
>>> +	bus_token = dev_is_pci(dev) ?
>>> +			DOMAIN_BUS_PCI_MSI : DOMAIN_BUS_PLATFORM_MSI;
>>> +	return irq_find_matching_fwnode(handle, bus_token);
>>>   }
>>>
>>>   static int __get_pci_rid(struct pci_dev *pdev, u16 alias, void *data)
>>> diff --git a/drivers/base/platform-msi.c b/drivers/base/platform-msi.c
>>> index 279e539..f6eae18 100644
>>> --- a/drivers/base/platform-msi.c
>>> +++ b/drivers/base/platform-msi.c
>>> @@ -17,8 +17,8 @@
>>>    * along with this program.  If not, see <http://www.gnu.org/licenses/>.
>>>    */
>>>
>>> +#include <linux/acpi_iort.h>
>>>   #include <linux/device.h>
>>> -#include <linux/idr.h>
>>>   #include <linux/irq.h>
>>>   #include <linux/irqdomain.h>
>>>   #include <linux/msi.h>
>>> @@ -416,3 +416,16 @@ int platform_msi_domain_alloc(struct irq_domain *domain, unsigned int virq,
>>>
>>>   	return err;
>>>   }
>>> +
>>> +int acpi_configure_msi_domain(struct device *dev)
>>> +{
>>> +	struct irq_domain *d = NULL;
>>> +
>>> +	d = iort_get_device_domain(dev, 0);
>>
>> This looks completely wrong. Why RID 0? As far as I can see, 0 is not a
>> special value, and could be something else.
> 
> You are right. I tried to reuse the API of get irqdomain in IORT for
> PCI devices, but for platform device, we don't have req id in named
> component, so I just pass 0 here, I think I need to prepare another
> API for platform devices.
> 
>>
>>> +	if (d) {
>>> +		dev_set_msi_domain(dev, d);
>>> +		return 0;
>>> +	}
>>> +
>>> +	return -EINVAL;
>>> +}
>>
>> I really hate this, as the platform MSI code is intentionally free of
>> any firmware reference. This should live in the ACPI code.
> 
> Will do, I think locate it in iort.c is better.
> 
>>
>>> diff --git a/drivers/base/platform.c b/drivers/base/platform.c
>>> index 6482d47..ea01a37 100644
>>> --- a/drivers/base/platform.c
>>> +++ b/drivers/base/platform.c
>>> @@ -24,6 +24,7 @@
>>>   #include <linux/pm_domain.h>
>>>   #include <linux/idr.h>
>>>   #include <linux/acpi.h>
>>> +#include <linux/msi.h>
>>>   #include <linux/clk/clk-conf.h>
>>>   #include <linux/limits.h>
>>>   #include <linux/property.h>
>>> @@ -500,6 +501,7 @@ struct platform_device *platform_device_register_full(
>>>   	pdev->dev.parent = pdevinfo->parent;
>>>   	pdev->dev.fwnode = pdevinfo->fwnode;
>>>
>>> +	acpi_configure_msi_domain(&pdev->dev);
>>
>> It feels odd to put this in the generic code, while you could perfectly
>> put the call into acpi_platform.c and keep the firmware stuff away from
>> the generic code.
> 
> My feeling is the same, I'm still trying to find a new way to do it,
> but I can't simply put that in acpi_platform.c, because
> 
> acpi_create_platform_device()
>     platform_device_register_full()
> 	platform_device_alloc()  --> dev is alloced
>          ...
>          dev.fwnode  is set
> 	(I get the msi domain by the fwnode in acpi_configure_msi_domain)
>          ...
>          platform_device_add()  --> which the device is probed.
> 
> For devices like irqchip which needs the dev->msi_domain to be
> set before it's really probed, because it needs the msi domain
> to be the parent domain.
> 
> If I call the function in acpi_create_platform_device() before
> platform_device_register_full(), we just can't set dev's msi
> domain, but if call it after platform_device_register_full(),
> the irqchip like mbigen will not get its parent domain...
> 
> DT is using another API for platform device probe, so has no
> problems like I said above, any suggestions to do it right in
> ACPI?

How about having something that's completely generic and solves
the problem once and for all? Something like this:

diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index 6482d47..6f0f90b 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -533,6 +533,9 @@ struct platform_device *platform_device_register_full(
 			goto err;
 	}
 
+	if (pdevinfo->pre_add_cb)
+		pdevinfo->pre_add_cb(&pdev->dev);
+
 	ret = platform_device_add(pdev);
 	if (ret) {
 err:
diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h
index 98c2a7c..44ea133 100644
--- a/include/linux/platform_device.h
+++ b/include/linux/platform_device.h
@@ -74,6 +74,7 @@ struct platform_device_info {
 		u64 dma_mask;
 
 		struct property_entry *properties;
+		void (*pre_add_cb)(struct device *);
 };
 extern struct platform_device *platform_device_register_full(
 		const struct platform_device_info *pdevinfo);

Plug pre_add_cb with your ACPI callback where you can do all the
processing you want before the device is actually added.

Thanks,

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

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

* [RFC PATCH v2 05/11] ACPI: platform: setup MSI domain for ACPI based platform device
@ 2016-09-15 15:18         ` Marc Zyngier
  0 siblings, 0 replies; 58+ messages in thread
From: Marc Zyngier @ 2016-09-15 15:18 UTC (permalink / raw)
  To: linux-arm-kernel

On 15/09/16 15:05, Hanjun Guo wrote:
> Hi Marc,
> 
> Thanks for your review, reply inline.
> 
> On 09/14/2016 11:45 PM, Marc Zyngier wrote:
>> On 14/09/16 15:21, Hanjun Guo wrote:
>>> From: Hanjun Guo <hanjun.guo@linaro.org>
>>>
>>> With the platform msi domain created, we can set up the msi domain
>>> for a platform device when it's probed.
>>>
>>> This patch introduces acpi_configure_msi_domain(), which retrieves
>>> the domain from iort and set it to platform device.
>>>
>>> As some platform devices such as an irqchip needs the msi irqdomain
>>> to be the interrupt parent domain, we need to get irqdomain before
>>> platform device is probed.
>>>
>>> Cc: Marc Zyngier <marc.zyngier@arm.com>
>>> Cc: Greg KH <gregkh@linuxfoundation.org>
>>> Cc: Thomas Gleixner <tglx@linutronix.de>
>>> Cc: Bjorn Helgaas <bhelgaas@google.com>
>>> Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
>>> Cc: Tomasz Nowicki <tn@semihalf.com>
>>> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
>>> ---
>>>   drivers/acpi/arm64/iort.c   |  5 ++++-
>>>   drivers/base/platform-msi.c | 15 ++++++++++++++-
>>>   drivers/base/platform.c     |  2 ++
>>>   include/linux/msi.h         |  1 +
>>>   4 files changed, 21 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
>>> index 13a1905..bccd3cc 100644
>>> --- a/drivers/acpi/arm64/iort.c
>>> +++ b/drivers/acpi/arm64/iort.c
>>> @@ -478,6 +478,7 @@ struct irq_domain *iort_get_device_domain(struct device *dev, u32 req_id)
>>>   {
>>>   	struct fwnode_handle *handle;
>>>   	int its_id;
>>> +	enum irq_domain_bus_token bus_token;
>>>
>>>   	if (iort_dev_find_its_id(dev, req_id, 0, &its_id))
>>>   		return NULL;
>>> @@ -486,7 +487,9 @@ struct irq_domain *iort_get_device_domain(struct device *dev, u32 req_id)
>>>   	if (!handle)
>>>   		return NULL;
>>>
>>> -	return irq_find_matching_fwnode(handle, DOMAIN_BUS_PCI_MSI);
>>> +	bus_token = dev_is_pci(dev) ?
>>> +			DOMAIN_BUS_PCI_MSI : DOMAIN_BUS_PLATFORM_MSI;
>>> +	return irq_find_matching_fwnode(handle, bus_token);
>>>   }
>>>
>>>   static int __get_pci_rid(struct pci_dev *pdev, u16 alias, void *data)
>>> diff --git a/drivers/base/platform-msi.c b/drivers/base/platform-msi.c
>>> index 279e539..f6eae18 100644
>>> --- a/drivers/base/platform-msi.c
>>> +++ b/drivers/base/platform-msi.c
>>> @@ -17,8 +17,8 @@
>>>    * along with this program.  If not, see <http://www.gnu.org/licenses/>.
>>>    */
>>>
>>> +#include <linux/acpi_iort.h>
>>>   #include <linux/device.h>
>>> -#include <linux/idr.h>
>>>   #include <linux/irq.h>
>>>   #include <linux/irqdomain.h>
>>>   #include <linux/msi.h>
>>> @@ -416,3 +416,16 @@ int platform_msi_domain_alloc(struct irq_domain *domain, unsigned int virq,
>>>
>>>   	return err;
>>>   }
>>> +
>>> +int acpi_configure_msi_domain(struct device *dev)
>>> +{
>>> +	struct irq_domain *d = NULL;
>>> +
>>> +	d = iort_get_device_domain(dev, 0);
>>
>> This looks completely wrong. Why RID 0? As far as I can see, 0 is not a
>> special value, and could be something else.
> 
> You are right. I tried to reuse the API of get irqdomain in IORT for
> PCI devices, but for platform device, we don't have req id in named
> component, so I just pass 0 here, I think I need to prepare another
> API for platform devices.
> 
>>
>>> +	if (d) {
>>> +		dev_set_msi_domain(dev, d);
>>> +		return 0;
>>> +	}
>>> +
>>> +	return -EINVAL;
>>> +}
>>
>> I really hate this, as the platform MSI code is intentionally free of
>> any firmware reference. This should live in the ACPI code.
> 
> Will do, I think locate it in iort.c is better.
> 
>>
>>> diff --git a/drivers/base/platform.c b/drivers/base/platform.c
>>> index 6482d47..ea01a37 100644
>>> --- a/drivers/base/platform.c
>>> +++ b/drivers/base/platform.c
>>> @@ -24,6 +24,7 @@
>>>   #include <linux/pm_domain.h>
>>>   #include <linux/idr.h>
>>>   #include <linux/acpi.h>
>>> +#include <linux/msi.h>
>>>   #include <linux/clk/clk-conf.h>
>>>   #include <linux/limits.h>
>>>   #include <linux/property.h>
>>> @@ -500,6 +501,7 @@ struct platform_device *platform_device_register_full(
>>>   	pdev->dev.parent = pdevinfo->parent;
>>>   	pdev->dev.fwnode = pdevinfo->fwnode;
>>>
>>> +	acpi_configure_msi_domain(&pdev->dev);
>>
>> It feels odd to put this in the generic code, while you could perfectly
>> put the call into acpi_platform.c and keep the firmware stuff away from
>> the generic code.
> 
> My feeling is the same, I'm still trying to find a new way to do it,
> but I can't simply put that in acpi_platform.c, because
> 
> acpi_create_platform_device()
>     platform_device_register_full()
> 	platform_device_alloc()  --> dev is alloced
>          ...
>          dev.fwnode  is set
> 	(I get the msi domain by the fwnode in acpi_configure_msi_domain)
>          ...
>          platform_device_add()  --> which the device is probed.
> 
> For devices like irqchip which needs the dev->msi_domain to be
> set before it's really probed, because it needs the msi domain
> to be the parent domain.
> 
> If I call the function in acpi_create_platform_device() before
> platform_device_register_full(), we just can't set dev's msi
> domain, but if call it after platform_device_register_full(),
> the irqchip like mbigen will not get its parent domain...
> 
> DT is using another API for platform device probe, so has no
> problems like I said above, any suggestions to do it right in
> ACPI?

How about having something that's completely generic and solves
the problem once and for all? Something like this:

diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index 6482d47..6f0f90b 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -533,6 +533,9 @@ struct platform_device *platform_device_register_full(
 			goto err;
 	}
 
+	if (pdevinfo->pre_add_cb)
+		pdevinfo->pre_add_cb(&pdev->dev);
+
 	ret = platform_device_add(pdev);
 	if (ret) {
 err:
diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h
index 98c2a7c..44ea133 100644
--- a/include/linux/platform_device.h
+++ b/include/linux/platform_device.h
@@ -74,6 +74,7 @@ struct platform_device_info {
 		u64 dma_mask;
 
 		struct property_entry *properties;
+		void (*pre_add_cb)(struct device *);
 };
 extern struct platform_device *platform_device_register_full(
 		const struct platform_device_info *pdevinfo);

Plug pre_add_cb with your ACPI callback where you can do all the
processing you want before the device is actually added.

Thanks,

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

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

* Re: [RFC PATCH v2 11/11] irqchip: mbigen: promote mbigen init
  2016-09-14 14:21   ` Hanjun Guo
@ 2016-09-15 15:24     ` Marc Zyngier
  -1 siblings, 0 replies; 58+ messages in thread
From: Marc Zyngier @ 2016-09-15 15:24 UTC (permalink / raw)
  To: Hanjun Guo, Rafael J. Wysocki, Lorenzo Pieralisi
  Cc: linux-acpi, linux-arm-kernel, linux-kernel, Thomas Gleixner,
	Bjorn Helgaas, Greg KH, Tomasz Nowicki, Ma Jun, Kefeng Wang,
	Charles Garcia-Tobin, linuxarm, Hanjun Guo

On 14/09/16 15:21, Hanjun Guo wrote:
> From: Hanjun Guo <hanjun.guo@linaro.org>
> 
> mbigen is an irqchip and it needs to be probed before
> devices, same logic is used for SMMU and etc., let's
> use arch_initcall instead of platform init for mbigen.
> 
> Cc: Marc Zyngier <marc.zyngier@arm.com>
> Cc: Thomas Gleixner <tglx@linutronix.de>
> Cc: Ma Jun <majun258@huawei.com>
> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
> ---
>  drivers/irqchip/irq-mbigen.c | 6 +++++-
>  1 file changed, 5 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/irqchip/irq-mbigen.c b/drivers/irqchip/irq-mbigen.c
> index ca6add1..3a33de6 100644
> --- a/drivers/irqchip/irq-mbigen.c
> +++ b/drivers/irqchip/irq-mbigen.c
> @@ -374,7 +374,11 @@ static struct platform_driver mbigen_platform_driver = {
>  	.probe			= mbigen_device_probe,
>  };
>  
> -module_platform_driver(mbigen_platform_driver);
> +static __init int mbigen_init(void)
> +{
> +	return platform_driver_register(&mbigen_platform_driver);
> +}
> +arch_initcall(mbigen_init);
>  
>  MODULE_AUTHOR("Jun Ma <majun258@huawei.com>");
>  MODULE_AUTHOR("Yun Wu <wuyun.wu@huawei.com>");
> 

I've already NACKed such a patch in the past, and I will carry on
NACKing it until all the other avenues (like properly tracking device
dependencies) have been explored and have been proven not to be fit for
purpose.

Rafael had proposed something around this subject last year, and I've
been repeatedly advising you to work with him and others to make it
happen. You can choose to ignore this advise, but that doesn't make this
patch an acceptable approach.

Thanks,

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

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

* [RFC PATCH v2 11/11] irqchip: mbigen: promote mbigen init
@ 2016-09-15 15:24     ` Marc Zyngier
  0 siblings, 0 replies; 58+ messages in thread
From: Marc Zyngier @ 2016-09-15 15:24 UTC (permalink / raw)
  To: linux-arm-kernel

On 14/09/16 15:21, Hanjun Guo wrote:
> From: Hanjun Guo <hanjun.guo@linaro.org>
> 
> mbigen is an irqchip and it needs to be probed before
> devices, same logic is used for SMMU and etc., let's
> use arch_initcall instead of platform init for mbigen.
> 
> Cc: Marc Zyngier <marc.zyngier@arm.com>
> Cc: Thomas Gleixner <tglx@linutronix.de>
> Cc: Ma Jun <majun258@huawei.com>
> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
> ---
>  drivers/irqchip/irq-mbigen.c | 6 +++++-
>  1 file changed, 5 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/irqchip/irq-mbigen.c b/drivers/irqchip/irq-mbigen.c
> index ca6add1..3a33de6 100644
> --- a/drivers/irqchip/irq-mbigen.c
> +++ b/drivers/irqchip/irq-mbigen.c
> @@ -374,7 +374,11 @@ static struct platform_driver mbigen_platform_driver = {
>  	.probe			= mbigen_device_probe,
>  };
>  
> -module_platform_driver(mbigen_platform_driver);
> +static __init int mbigen_init(void)
> +{
> +	return platform_driver_register(&mbigen_platform_driver);
> +}
> +arch_initcall(mbigen_init);
>  
>  MODULE_AUTHOR("Jun Ma <majun258@huawei.com>");
>  MODULE_AUTHOR("Yun Wu <wuyun.wu@huawei.com>");
> 

I've already NACKed such a patch in the past, and I will carry on
NACKing it until all the other avenues (like properly tracking device
dependencies) have been explored and have been proven not to be fit for
purpose.

Rafael had proposed something around this subject last year, and I've
been repeatedly advising you to work with him and others to make it
happen. You can choose to ignore this advise, but that doesn't make this
patch an acceptable approach.

Thanks,

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

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

* Re: [RFC PATCH v2 10/11] irqchip: mbigen: Add ACPI support
  2016-09-15  8:49     ` Marc Zyngier
@ 2016-09-19  9:28       ` Hanjun Guo
  -1 siblings, 0 replies; 58+ messages in thread
From: Hanjun Guo @ 2016-09-19  9:28 UTC (permalink / raw)
  To: Marc Zyngier, Hanjun Guo, Rafael J. Wysocki, Lorenzo Pieralisi
  Cc: linux-acpi, linux-arm-kernel, linux-kernel, Thomas Gleixner,
	Bjorn Helgaas, Greg KH, Tomasz Nowicki, Ma Jun, Kefeng Wang,
	Charles Garcia-Tobin, linuxarm

Hi Marc,

On 2016/9/15 16:49, Marc Zyngier wrote:
> On 14/09/16 15:21, Hanjun Guo wrote:
>> From: Hanjun Guo <hanjun.guo@linaro.org>
>>
>> With the preparation of platform msi support and interrupt producer
>> in DSDT, we can add mbigen ACPI support now.
>>
>> We are using _PRS methd to indicate number of irq pins instead
>> of num_pins in DT.
>>
>> For mbi-gen,
>>     Device(MBI0) {
>>           Name(_HID, "HISI0152")
>>           Name(_UID, Zero)
>>           Name(_CRS, ResourceTemplate() {
>>                   Memory32Fixed(ReadWrite, 0xa0080000, 0x10000)
>>           })
>>
>>           Name (_PRS, ResourceTemplate() {
>> 		  Interrupt(ResourceProducer,...) {12,14,....}
>>           })
>
> Since I know next to nothing about all of this, I'm going to play the
> village idiot. What makes it legal to use _PRS as a way to describe the
> interrupts that are exposed by MBI0? Looking at the 6.0 spec, I do not
> see why the interrupts would be put there instead of _CRS, and why you'd
> have a _PRS at all.

_PRS describes possible resource settings for the device, which returns
a list of a device's possible resource settings such as memory range,
interrupt descriptors, and the format of the data in a _PRS object
follows the same format as _CRS object (ACPI 6.1, section 6.2.12),
so Interrupts can be put in the _PRS.

And in ACPI 6.1, section 6.2, it describes the _PRS usage:

"Some resources, however, may be shared amongst several devices. To
describe this, devices that share a resource (resource consumers) must
use the extended resource descriptors (0x7-0xA) described in Section
6.4.3, “Large Resource Data Type.” These descriptors point to a single
device object (resource producer) that claims the shared resource in
its _PRS."

As mbigen is a interrupt producer which provide interrupt resoures
for devices, which matches the usage of _PRS in the spec.

>
> Also, are you going to exhaustively describe all the possible interrupts
> via this method? Knowing that the mbigen can expose thousands of
> interrupts, I find it slightly mad. Can't you express a range?

Yes, a little bit mad. I can't express a interrupt range in ACPI at
least in current version of spec. But that just adding more lines
of ACPI DSDT code, it's fine to me. or we need to use _DSD to present
similar property "num_pins" in ACPI which I avoid using.

Thanks
Hanjun

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

* [RFC PATCH v2 10/11] irqchip: mbigen: Add ACPI support
@ 2016-09-19  9:28       ` Hanjun Guo
  0 siblings, 0 replies; 58+ messages in thread
From: Hanjun Guo @ 2016-09-19  9:28 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Marc,

On 2016/9/15 16:49, Marc Zyngier wrote:
> On 14/09/16 15:21, Hanjun Guo wrote:
>> From: Hanjun Guo <hanjun.guo@linaro.org>
>>
>> With the preparation of platform msi support and interrupt producer
>> in DSDT, we can add mbigen ACPI support now.
>>
>> We are using _PRS methd to indicate number of irq pins instead
>> of num_pins in DT.
>>
>> For mbi-gen,
>>     Device(MBI0) {
>>           Name(_HID, "HISI0152")
>>           Name(_UID, Zero)
>>           Name(_CRS, ResourceTemplate() {
>>                   Memory32Fixed(ReadWrite, 0xa0080000, 0x10000)
>>           })
>>
>>           Name (_PRS, ResourceTemplate() {
>> 		  Interrupt(ResourceProducer,...) {12,14,....}
>>           })
>
> Since I know next to nothing about all of this, I'm going to play the
> village idiot. What makes it legal to use _PRS as a way to describe the
> interrupts that are exposed by MBI0? Looking at the 6.0 spec, I do not
> see why the interrupts would be put there instead of _CRS, and why you'd
> have a _PRS at all.

_PRS describes possible resource settings for the device, which returns
a list of a device's possible resource settings such as memory range,
interrupt descriptors, and the format of the data in a _PRS object
follows the same format as _CRS object (ACPI 6.1, section 6.2.12),
so Interrupts can be put in the _PRS.

And in ACPI 6.1, section 6.2, it describes the _PRS usage:

"Some resources, however, may be shared amongst several devices. To
describe this, devices that share a resource (resource consumers) must
use the extended resource descriptors (0x7-0xA) described in Section
6.4.3, ?Large Resource Data Type.? These descriptors point to a single
device object (resource producer) that claims the shared resource in
its _PRS."

As mbigen is a interrupt producer which provide interrupt resoures
for devices, which matches the usage of _PRS in the spec.

>
> Also, are you going to exhaustively describe all the possible interrupts
> via this method? Knowing that the mbigen can expose thousands of
> interrupts, I find it slightly mad. Can't you express a range?

Yes, a little bit mad. I can't express a interrupt range in ACPI at
least in current version of spec. But that just adding more lines
of ACPI DSDT code, it's fine to me. or we need to use _DSD to present
similar property "num_pins" in ACPI which I avoid using.

Thanks
Hanjun

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

* Re: [RFC PATCH v2 05/11] ACPI: platform: setup MSI domain for ACPI based platform device
  2016-09-15 15:18         ` Marc Zyngier
@ 2016-09-19  9:42           ` Hanjun Guo
  -1 siblings, 0 replies; 58+ messages in thread
From: Hanjun Guo @ 2016-09-19  9:42 UTC (permalink / raw)
  To: Marc Zyngier, Hanjun Guo, Rafael J. Wysocki, Lorenzo Pieralisi
  Cc: linux-acpi, linux-arm-kernel, linux-kernel, Thomas Gleixner,
	Bjorn Helgaas, Greg KH, Tomasz Nowicki, Ma Jun, Kefeng Wang,
	Charles Garcia-Tobin, linuxarm

On 2016/9/15 23:18, Marc Zyngier wrote:
> On 15/09/16 15:05, Hanjun Guo wrote:
>> Hi Marc,
[...]
>>>> diff --git a/drivers/base/platform.c b/drivers/base/platform.c
>>>> index 6482d47..ea01a37 100644
>>>> --- a/drivers/base/platform.c
>>>> +++ b/drivers/base/platform.c
>>>> @@ -24,6 +24,7 @@
>>>>   #include <linux/pm_domain.h>
>>>>   #include <linux/idr.h>
>>>>   #include <linux/acpi.h>
>>>> +#include <linux/msi.h>
>>>>   #include <linux/clk/clk-conf.h>
>>>>   #include <linux/limits.h>
>>>>   #include <linux/property.h>
>>>> @@ -500,6 +501,7 @@ struct platform_device *platform_device_register_full(
>>>>   	pdev->dev.parent = pdevinfo->parent;
>>>>   	pdev->dev.fwnode = pdevinfo->fwnode;
>>>>
>>>> +	acpi_configure_msi_domain(&pdev->dev);
>>>
>>> It feels odd to put this in the generic code, while you could perfectly
>>> put the call into acpi_platform.c and keep the firmware stuff away from
>>> the generic code.
>>
>> My feeling is the same, I'm still trying to find a new way to do it,
>> but I can't simply put that in acpi_platform.c, because
>>
>> acpi_create_platform_device()
>>     platform_device_register_full()
>> 	platform_device_alloc()  --> dev is alloced
>>          ...
>>          dev.fwnode  is set
>> 	(I get the msi domain by the fwnode in acpi_configure_msi_domain)
>>          ...
>>          platform_device_add()  --> which the device is probed.
>>
>> For devices like irqchip which needs the dev->msi_domain to be
>> set before it's really probed, because it needs the msi domain
>> to be the parent domain.
>>
>> If I call the function in acpi_create_platform_device() before
>> platform_device_register_full(), we just can't set dev's msi
>> domain, but if call it after platform_device_register_full(),
>> the irqchip like mbigen will not get its parent domain...
>>
>> DT is using another API for platform device probe, so has no
>> problems like I said above, any suggestions to do it right in
>> ACPI?
>
> How about having something that's completely generic and solves
> the problem once and for all? Something like this:
>
> diff --git a/drivers/base/platform.c b/drivers/base/platform.c
> index 6482d47..6f0f90b 100644
> --- a/drivers/base/platform.c
> +++ b/drivers/base/platform.c
> @@ -533,6 +533,9 @@ struct platform_device *platform_device_register_full(
>  			goto err;
>  	}
>
> +	if (pdevinfo->pre_add_cb)
> +		pdevinfo->pre_add_cb(&pdev->dev);
> +
>  	ret = platform_device_add(pdev);
>  	if (ret) {
>  err:
> diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h
> index 98c2a7c..44ea133 100644
> --- a/include/linux/platform_device.h
> +++ b/include/linux/platform_device.h
> @@ -74,6 +74,7 @@ struct platform_device_info {
>  		u64 dma_mask;
>
>  		struct property_entry *properties;
> +		void (*pre_add_cb)(struct device *);
>  };
>  extern struct platform_device *platform_device_register_full(
>  		const struct platform_device_info *pdevinfo);
>
> Plug pre_add_cb with your ACPI callback where you can do all the
> processing you want before the device is actually added.

Great, will do, thank you very much!

Hanjun

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

* [RFC PATCH v2 05/11] ACPI: platform: setup MSI domain for ACPI based platform device
@ 2016-09-19  9:42           ` Hanjun Guo
  0 siblings, 0 replies; 58+ messages in thread
From: Hanjun Guo @ 2016-09-19  9:42 UTC (permalink / raw)
  To: linux-arm-kernel

On 2016/9/15 23:18, Marc Zyngier wrote:
> On 15/09/16 15:05, Hanjun Guo wrote:
>> Hi Marc,
[...]
>>>> diff --git a/drivers/base/platform.c b/drivers/base/platform.c
>>>> index 6482d47..ea01a37 100644
>>>> --- a/drivers/base/platform.c
>>>> +++ b/drivers/base/platform.c
>>>> @@ -24,6 +24,7 @@
>>>>   #include <linux/pm_domain.h>
>>>>   #include <linux/idr.h>
>>>>   #include <linux/acpi.h>
>>>> +#include <linux/msi.h>
>>>>   #include <linux/clk/clk-conf.h>
>>>>   #include <linux/limits.h>
>>>>   #include <linux/property.h>
>>>> @@ -500,6 +501,7 @@ struct platform_device *platform_device_register_full(
>>>>   	pdev->dev.parent = pdevinfo->parent;
>>>>   	pdev->dev.fwnode = pdevinfo->fwnode;
>>>>
>>>> +	acpi_configure_msi_domain(&pdev->dev);
>>>
>>> It feels odd to put this in the generic code, while you could perfectly
>>> put the call into acpi_platform.c and keep the firmware stuff away from
>>> the generic code.
>>
>> My feeling is the same, I'm still trying to find a new way to do it,
>> but I can't simply put that in acpi_platform.c, because
>>
>> acpi_create_platform_device()
>>     platform_device_register_full()
>> 	platform_device_alloc()  --> dev is alloced
>>          ...
>>          dev.fwnode  is set
>> 	(I get the msi domain by the fwnode in acpi_configure_msi_domain)
>>          ...
>>          platform_device_add()  --> which the device is probed.
>>
>> For devices like irqchip which needs the dev->msi_domain to be
>> set before it's really probed, because it needs the msi domain
>> to be the parent domain.
>>
>> If I call the function in acpi_create_platform_device() before
>> platform_device_register_full(), we just can't set dev's msi
>> domain, but if call it after platform_device_register_full(),
>> the irqchip like mbigen will not get its parent domain...
>>
>> DT is using another API for platform device probe, so has no
>> problems like I said above, any suggestions to do it right in
>> ACPI?
>
> How about having something that's completely generic and solves
> the problem once and for all? Something like this:
>
> diff --git a/drivers/base/platform.c b/drivers/base/platform.c
> index 6482d47..6f0f90b 100644
> --- a/drivers/base/platform.c
> +++ b/drivers/base/platform.c
> @@ -533,6 +533,9 @@ struct platform_device *platform_device_register_full(
>  			goto err;
>  	}
>
> +	if (pdevinfo->pre_add_cb)
> +		pdevinfo->pre_add_cb(&pdev->dev);
> +
>  	ret = platform_device_add(pdev);
>  	if (ret) {
>  err:
> diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h
> index 98c2a7c..44ea133 100644
> --- a/include/linux/platform_device.h
> +++ b/include/linux/platform_device.h
> @@ -74,6 +74,7 @@ struct platform_device_info {
>  		u64 dma_mask;
>
>  		struct property_entry *properties;
> +		void (*pre_add_cb)(struct device *);
>  };
>  extern struct platform_device *platform_device_register_full(
>  		const struct platform_device_info *pdevinfo);
>
> Plug pre_add_cb with your ACPI callback where you can do all the
> processing you want before the device is actually added.

Great, will do, thank you very much!

Hanjun

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

* Re: [RFC PATCH v2 11/11] irqchip: mbigen: promote mbigen init
  2016-09-15 15:24     ` Marc Zyngier
@ 2016-09-19  9:49       ` Hanjun Guo
  -1 siblings, 0 replies; 58+ messages in thread
From: Hanjun Guo @ 2016-09-19  9:49 UTC (permalink / raw)
  To: Marc Zyngier, Hanjun Guo, Rafael J. Wysocki, Lorenzo Pieralisi
  Cc: linux-acpi, linux-arm-kernel, linux-kernel, Thomas Gleixner,
	Bjorn Helgaas, Greg KH, Tomasz Nowicki, Ma Jun, Kefeng Wang,
	Charles Garcia-Tobin, linuxarm

On 2016/9/15 23:24, Marc Zyngier wrote:
> On 14/09/16 15:21, Hanjun Guo wrote:
>> From: Hanjun Guo <hanjun.guo@linaro.org>
>>
>> mbigen is an irqchip and it needs to be probed before
>> devices, same logic is used for SMMU and etc., let's
>> use arch_initcall instead of platform init for mbigen.
>>
>> Cc: Marc Zyngier <marc.zyngier@arm.com>
>> Cc: Thomas Gleixner <tglx@linutronix.de>
>> Cc: Ma Jun <majun258@huawei.com>
>> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
>> ---
>>  drivers/irqchip/irq-mbigen.c | 6 +++++-
>>  1 file changed, 5 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/irqchip/irq-mbigen.c b/drivers/irqchip/irq-mbigen.c
>> index ca6add1..3a33de6 100644
>> --- a/drivers/irqchip/irq-mbigen.c
>> +++ b/drivers/irqchip/irq-mbigen.c
>> @@ -374,7 +374,11 @@ static struct platform_driver mbigen_platform_driver = {
>>  	.probe			= mbigen_device_probe,
>>  };
>>
>> -module_platform_driver(mbigen_platform_driver);
>> +static __init int mbigen_init(void)
>> +{
>> +	return platform_driver_register(&mbigen_platform_driver);
>> +}
>> +arch_initcall(mbigen_init);
>>
>>  MODULE_AUTHOR("Jun Ma <majun258@huawei.com>");
>>  MODULE_AUTHOR("Yun Wu <wuyun.wu@huawei.com>");
>>
>
> I've already NACKed such a patch in the past, and I will carry on
> NACKing it until all the other avenues (like properly tracking device
> dependencies) have been explored and have been proven not to be fit for
> purpose.

I'd happy to work on this to make progress.

>
> Rafael had proposed something around this subject last year, and I've

Sorry, obviously I missed something, could you give me the link about
Rafael's patches? I will pull back and test it on our hardware.

> been repeatedly advising you to work with him and others to make it
> happen. You can choose to ignore this advise, but that doesn't make this
> patch an acceptable approach.

OK, I will drop this patch in next version, and work on the generic
solution instead.

Thanks
Hanjun

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

* [RFC PATCH v2 11/11] irqchip: mbigen: promote mbigen init
@ 2016-09-19  9:49       ` Hanjun Guo
  0 siblings, 0 replies; 58+ messages in thread
From: Hanjun Guo @ 2016-09-19  9:49 UTC (permalink / raw)
  To: linux-arm-kernel

On 2016/9/15 23:24, Marc Zyngier wrote:
> On 14/09/16 15:21, Hanjun Guo wrote:
>> From: Hanjun Guo <hanjun.guo@linaro.org>
>>
>> mbigen is an irqchip and it needs to be probed before
>> devices, same logic is used for SMMU and etc., let's
>> use arch_initcall instead of platform init for mbigen.
>>
>> Cc: Marc Zyngier <marc.zyngier@arm.com>
>> Cc: Thomas Gleixner <tglx@linutronix.de>
>> Cc: Ma Jun <majun258@huawei.com>
>> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
>> ---
>>  drivers/irqchip/irq-mbigen.c | 6 +++++-
>>  1 file changed, 5 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/irqchip/irq-mbigen.c b/drivers/irqchip/irq-mbigen.c
>> index ca6add1..3a33de6 100644
>> --- a/drivers/irqchip/irq-mbigen.c
>> +++ b/drivers/irqchip/irq-mbigen.c
>> @@ -374,7 +374,11 @@ static struct platform_driver mbigen_platform_driver = {
>>  	.probe			= mbigen_device_probe,
>>  };
>>
>> -module_platform_driver(mbigen_platform_driver);
>> +static __init int mbigen_init(void)
>> +{
>> +	return platform_driver_register(&mbigen_platform_driver);
>> +}
>> +arch_initcall(mbigen_init);
>>
>>  MODULE_AUTHOR("Jun Ma <majun258@huawei.com>");
>>  MODULE_AUTHOR("Yun Wu <wuyun.wu@huawei.com>");
>>
>
> I've already NACKed such a patch in the past, and I will carry on
> NACKing it until all the other avenues (like properly tracking device
> dependencies) have been explored and have been proven not to be fit for
> purpose.

I'd happy to work on this to make progress.

>
> Rafael had proposed something around this subject last year, and I've

Sorry, obviously I missed something, could you give me the link about
Rafael's patches? I will pull back and test it on our hardware.

> been repeatedly advising you to work with him and others to make it
> happen. You can choose to ignore this advise, but that doesn't make this
> patch an acceptable approach.

OK, I will drop this patch in next version, and work on the generic
solution instead.

Thanks
Hanjun

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

* Re: [RFC PATCH v2 11/11] irqchip: mbigen: promote mbigen init
  2016-09-19  9:49       ` Hanjun Guo
@ 2016-09-19 10:12         ` Marc Zyngier
  -1 siblings, 0 replies; 58+ messages in thread
From: Marc Zyngier @ 2016-09-19 10:12 UTC (permalink / raw)
  To: Hanjun Guo, Hanjun Guo, Rafael J. Wysocki, Lorenzo Pieralisi
  Cc: linux-acpi, linux-arm-kernel, linux-kernel, Thomas Gleixner,
	Bjorn Helgaas, Greg KH, Tomasz Nowicki, Ma Jun, Kefeng Wang,
	Charles Garcia-Tobin, linuxarm

On 19/09/16 10:49, Hanjun Guo wrote:
> On 2016/9/15 23:24, Marc Zyngier wrote:
>> On 14/09/16 15:21, Hanjun Guo wrote:
>>> From: Hanjun Guo <hanjun.guo@linaro.org>
>>>
>>> mbigen is an irqchip and it needs to be probed before
>>> devices, same logic is used for SMMU and etc., let's
>>> use arch_initcall instead of platform init for mbigen.
>>>
>>> Cc: Marc Zyngier <marc.zyngier@arm.com>
>>> Cc: Thomas Gleixner <tglx@linutronix.de>
>>> Cc: Ma Jun <majun258@huawei.com>
>>> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
>>> ---
>>>  drivers/irqchip/irq-mbigen.c | 6 +++++-
>>>  1 file changed, 5 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/drivers/irqchip/irq-mbigen.c b/drivers/irqchip/irq-mbigen.c
>>> index ca6add1..3a33de6 100644
>>> --- a/drivers/irqchip/irq-mbigen.c
>>> +++ b/drivers/irqchip/irq-mbigen.c
>>> @@ -374,7 +374,11 @@ static struct platform_driver mbigen_platform_driver = {
>>>  	.probe			= mbigen_device_probe,
>>>  };
>>>
>>> -module_platform_driver(mbigen_platform_driver);
>>> +static __init int mbigen_init(void)
>>> +{
>>> +	return platform_driver_register(&mbigen_platform_driver);
>>> +}
>>> +arch_initcall(mbigen_init);
>>>
>>>  MODULE_AUTHOR("Jun Ma <majun258@huawei.com>");
>>>  MODULE_AUTHOR("Yun Wu <wuyun.wu@huawei.com>");
>>>
>>
>> I've already NACKed such a patch in the past, and I will carry on
>> NACKing it until all the other avenues (like properly tracking device
>> dependencies) have been explored and have been proven not to be fit for
>> purpose.
> 
> I'd happy to work on this to make progress.
> 
>>
>> Rafael had proposed something around this subject last year, and I've
> 
> Sorry, obviously I missed something, could you give me the link about
> Rafael's patches? I will pull back and test it on our hardware.

Please see this discussion from almost a year ago:

https://patchwork.kernel.org/patch/7407401/

in which I give the existing pointers and explain why I'm pushing back
on things like this patch.

> 
>> been repeatedly advising you to work with him and others to make it
>> happen. You can choose to ignore this advise, but that doesn't make this
>> patch an acceptable approach.
> 
> OK, I will drop this patch in next version, and work on the generic
> solution instead.

That'd be the ideal thing, and that's what I suggested when we did meet
in BKK earlier this year. Obviously, I didn't convey my point clearly
enough.

Thanks,

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

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

* [RFC PATCH v2 11/11] irqchip: mbigen: promote mbigen init
@ 2016-09-19 10:12         ` Marc Zyngier
  0 siblings, 0 replies; 58+ messages in thread
From: Marc Zyngier @ 2016-09-19 10:12 UTC (permalink / raw)
  To: linux-arm-kernel

On 19/09/16 10:49, Hanjun Guo wrote:
> On 2016/9/15 23:24, Marc Zyngier wrote:
>> On 14/09/16 15:21, Hanjun Guo wrote:
>>> From: Hanjun Guo <hanjun.guo@linaro.org>
>>>
>>> mbigen is an irqchip and it needs to be probed before
>>> devices, same logic is used for SMMU and etc., let's
>>> use arch_initcall instead of platform init for mbigen.
>>>
>>> Cc: Marc Zyngier <marc.zyngier@arm.com>
>>> Cc: Thomas Gleixner <tglx@linutronix.de>
>>> Cc: Ma Jun <majun258@huawei.com>
>>> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
>>> ---
>>>  drivers/irqchip/irq-mbigen.c | 6 +++++-
>>>  1 file changed, 5 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/drivers/irqchip/irq-mbigen.c b/drivers/irqchip/irq-mbigen.c
>>> index ca6add1..3a33de6 100644
>>> --- a/drivers/irqchip/irq-mbigen.c
>>> +++ b/drivers/irqchip/irq-mbigen.c
>>> @@ -374,7 +374,11 @@ static struct platform_driver mbigen_platform_driver = {
>>>  	.probe			= mbigen_device_probe,
>>>  };
>>>
>>> -module_platform_driver(mbigen_platform_driver);
>>> +static __init int mbigen_init(void)
>>> +{
>>> +	return platform_driver_register(&mbigen_platform_driver);
>>> +}
>>> +arch_initcall(mbigen_init);
>>>
>>>  MODULE_AUTHOR("Jun Ma <majun258@huawei.com>");
>>>  MODULE_AUTHOR("Yun Wu <wuyun.wu@huawei.com>");
>>>
>>
>> I've already NACKed such a patch in the past, and I will carry on
>> NACKing it until all the other avenues (like properly tracking device
>> dependencies) have been explored and have been proven not to be fit for
>> purpose.
> 
> I'd happy to work on this to make progress.
> 
>>
>> Rafael had proposed something around this subject last year, and I've
> 
> Sorry, obviously I missed something, could you give me the link about
> Rafael's patches? I will pull back and test it on our hardware.

Please see this discussion from almost a year ago:

https://patchwork.kernel.org/patch/7407401/

in which I give the existing pointers and explain why I'm pushing back
on things like this patch.

> 
>> been repeatedly advising you to work with him and others to make it
>> happen. You can choose to ignore this advise, but that doesn't make this
>> patch an acceptable approach.
> 
> OK, I will drop this patch in next version, and work on the generic
> solution instead.

That'd be the ideal thing, and that's what I suggested when we did meet
in BKK earlier this year. Obviously, I didn't convey my point clearly
enough.

Thanks,

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

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

* Re: [RFC PATCH v2 11/11] irqchip: mbigen: promote mbigen init
  2016-09-19 10:12         ` Marc Zyngier
  (?)
@ 2016-09-20  2:43           ` Hanjun Guo
  -1 siblings, 0 replies; 58+ messages in thread
From: Hanjun Guo @ 2016-09-20  2:43 UTC (permalink / raw)
  To: Marc Zyngier, Hanjun Guo, Rafael J. Wysocki, Lorenzo Pieralisi
  Cc: linux-acpi, linux-arm-kernel, linux-kernel, Thomas Gleixner,
	Bjorn Helgaas, Greg KH, Tomasz Nowicki, Ma Jun, Kefeng Wang,
	Charles Garcia-Tobin, linuxarm

On 2016/9/19 18:12, Marc Zyngier wrote:
> On 19/09/16 10:49, Hanjun Guo wrote:
>> On 2016/9/15 23:24, Marc Zyngier wrote:
>>> On 14/09/16 15:21, Hanjun Guo wrote:
>>>> From: Hanjun Guo <hanjun.guo@linaro.org>
>>>>
>>>> mbigen is an irqchip and it needs to be probed before
>>>> devices, same logic is used for SMMU and etc., let's
>>>> use arch_initcall instead of platform init for mbigen.
>>>>
>>>> Cc: Marc Zyngier <marc.zyngier@arm.com>
>>>> Cc: Thomas Gleixner <tglx@linutronix.de>
>>>> Cc: Ma Jun <majun258@huawei.com>
>>>> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
>>>> ---
>>>>  drivers/irqchip/irq-mbigen.c | 6 +++++-
>>>>  1 file changed, 5 insertions(+), 1 deletion(-)
>>>>
>>>> diff --git a/drivers/irqchip/irq-mbigen.c b/drivers/irqchip/irq-mbigen.c
>>>> index ca6add1..3a33de6 100644
>>>> --- a/drivers/irqchip/irq-mbigen.c
>>>> +++ b/drivers/irqchip/irq-mbigen.c
>>>> @@ -374,7 +374,11 @@ static struct platform_driver mbigen_platform_driver = {
>>>>  	.probe			= mbigen_device_probe,
>>>>  };
>>>>
>>>> -module_platform_driver(mbigen_platform_driver);
>>>> +static __init int mbigen_init(void)
>>>> +{
>>>> +	return platform_driver_register(&mbigen_platform_driver);
>>>> +}
>>>> +arch_initcall(mbigen_init);
>>>>
>>>>  MODULE_AUTHOR("Jun Ma <majun258@huawei.com>");
>>>>  MODULE_AUTHOR("Yun Wu <wuyun.wu@huawei.com>");
>>>>
>>> I've already NACKed such a patch in the past, and I will carry on
>>> NACKing it until all the other avenues (like properly tracking device
>>> dependencies) have been explored and have been proven not to be fit for
>>> purpose.
>> I'd happy to work on this to make progress.
>>
>>> Rafael had proposed something around this subject last year, and I've
>> Sorry, obviously I missed something, could you give me the link about
>> Rafael's patches? I will pull back and test it on our hardware.
> Please see this discussion from almost a year ago:
>
> https://patchwork.kernel.org/patch/7407401/
>
> in which I give the existing pointers and explain why I'm pushing back
> on things like this patch.

We (Majun and me ) will look into it, thanks!

Hanjun


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

* Re: [RFC PATCH v2 11/11] irqchip: mbigen: promote mbigen init
@ 2016-09-20  2:43           ` Hanjun Guo
  0 siblings, 0 replies; 58+ messages in thread
From: Hanjun Guo @ 2016-09-20  2:43 UTC (permalink / raw)
  To: Marc Zyngier, Hanjun Guo, Rafael J. Wysocki, Lorenzo Pieralisi
  Cc: linux-acpi, linux-arm-kernel, linux-kernel, Thomas Gleixner,
	Bjorn Helgaas, Greg KH, Tomasz Nowicki, Ma Jun, Kefeng Wang,
	Charles Garcia-Tobin, linuxarm

On 2016/9/19 18:12, Marc Zyngier wrote:
> On 19/09/16 10:49, Hanjun Guo wrote:
>> On 2016/9/15 23:24, Marc Zyngier wrote:
>>> On 14/09/16 15:21, Hanjun Guo wrote:
>>>> From: Hanjun Guo <hanjun.guo@linaro.org>
>>>>
>>>> mbigen is an irqchip and it needs to be probed before
>>>> devices, same logic is used for SMMU and etc., let's
>>>> use arch_initcall instead of platform init for mbigen.
>>>>
>>>> Cc: Marc Zyngier <marc.zyngier@arm.com>
>>>> Cc: Thomas Gleixner <tglx@linutronix.de>
>>>> Cc: Ma Jun <majun258@huawei.com>
>>>> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
>>>> ---
>>>>  drivers/irqchip/irq-mbigen.c | 6 +++++-
>>>>  1 file changed, 5 insertions(+), 1 deletion(-)
>>>>
>>>> diff --git a/drivers/irqchip/irq-mbigen.c b/drivers/irqchip/irq-mbigen.c
>>>> index ca6add1..3a33de6 100644
>>>> --- a/drivers/irqchip/irq-mbigen.c
>>>> +++ b/drivers/irqchip/irq-mbigen.c
>>>> @@ -374,7 +374,11 @@ static struct platform_driver mbigen_platform_driver = {
>>>>  	.probe			= mbigen_device_probe,
>>>>  };
>>>>
>>>> -module_platform_driver(mbigen_platform_driver);
>>>> +static __init int mbigen_init(void)
>>>> +{
>>>> +	return platform_driver_register(&mbigen_platform_driver);
>>>> +}
>>>> +arch_initcall(mbigen_init);
>>>>
>>>>  MODULE_AUTHOR("Jun Ma <majun258@huawei.com>");
>>>>  MODULE_AUTHOR("Yun Wu <wuyun.wu@huawei.com>");
>>>>
>>> I've already NACKed such a patch in the past, and I will carry on
>>> NACKing it until all the other avenues (like properly tracking device
>>> dependencies) have been explored and have been proven not to be fit for
>>> purpose.
>> I'd happy to work on this to make progress.
>>
>>> Rafael had proposed something around this subject last year, and I've
>> Sorry, obviously I missed something, could you give me the link about
>> Rafael's patches? I will pull back and test it on our hardware.
> Please see this discussion from almost a year ago:
>
> https://patchwork.kernel.org/patch/7407401/
>
> in which I give the existing pointers and explain why I'm pushing back
> on things like this patch.

We (Majun and me ) will look into it, thanks!

Hanjun

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

* [RFC PATCH v2 11/11] irqchip: mbigen: promote mbigen init
@ 2016-09-20  2:43           ` Hanjun Guo
  0 siblings, 0 replies; 58+ messages in thread
From: Hanjun Guo @ 2016-09-20  2:43 UTC (permalink / raw)
  To: linux-arm-kernel

On 2016/9/19 18:12, Marc Zyngier wrote:
> On 19/09/16 10:49, Hanjun Guo wrote:
>> On 2016/9/15 23:24, Marc Zyngier wrote:
>>> On 14/09/16 15:21, Hanjun Guo wrote:
>>>> From: Hanjun Guo <hanjun.guo@linaro.org>
>>>>
>>>> mbigen is an irqchip and it needs to be probed before
>>>> devices, same logic is used for SMMU and etc., let's
>>>> use arch_initcall instead of platform init for mbigen.
>>>>
>>>> Cc: Marc Zyngier <marc.zyngier@arm.com>
>>>> Cc: Thomas Gleixner <tglx@linutronix.de>
>>>> Cc: Ma Jun <majun258@huawei.com>
>>>> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
>>>> ---
>>>>  drivers/irqchip/irq-mbigen.c | 6 +++++-
>>>>  1 file changed, 5 insertions(+), 1 deletion(-)
>>>>
>>>> diff --git a/drivers/irqchip/irq-mbigen.c b/drivers/irqchip/irq-mbigen.c
>>>> index ca6add1..3a33de6 100644
>>>> --- a/drivers/irqchip/irq-mbigen.c
>>>> +++ b/drivers/irqchip/irq-mbigen.c
>>>> @@ -374,7 +374,11 @@ static struct platform_driver mbigen_platform_driver = {
>>>>  	.probe			= mbigen_device_probe,
>>>>  };
>>>>
>>>> -module_platform_driver(mbigen_platform_driver);
>>>> +static __init int mbigen_init(void)
>>>> +{
>>>> +	return platform_driver_register(&mbigen_platform_driver);
>>>> +}
>>>> +arch_initcall(mbigen_init);
>>>>
>>>>  MODULE_AUTHOR("Jun Ma <majun258@huawei.com>");
>>>>  MODULE_AUTHOR("Yun Wu <wuyun.wu@huawei.com>");
>>>>
>>> I've already NACKed such a patch in the past, and I will carry on
>>> NACKing it until all the other avenues (like properly tracking device
>>> dependencies) have been explored and have been proven not to be fit for
>>> purpose.
>> I'd happy to work on this to make progress.
>>
>>> Rafael had proposed something around this subject last year, and I've
>> Sorry, obviously I missed something, could you give me the link about
>> Rafael's patches? I will pull back and test it on our hardware.
> Please see this discussion from almost a year ago:
>
> https://patchwork.kernel.org/patch/7407401/
>
> in which I give the existing pointers and explain why I'm pushing back
> on things like this patch.

We (Majun and me ) will look into it, thanks!

Hanjun

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

end of thread, other threads:[~2016-09-20  2:43 UTC | newest]

Thread overview: 58+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-09-14 14:21 [RFC PATCH v2 00/11] ACPI platform MSI, interrupt producer/consumer and its example mbi-gen Hanjun Guo
2016-09-14 14:21 ` Hanjun Guo
2016-09-14 14:21 ` Hanjun Guo
2016-09-14 14:21 ` [RFC PATCH v2 01/11] irqchip: gicv3-its: platform-msi: refactor its_pmsi_prepare() Hanjun Guo
2016-09-14 14:21   ` Hanjun Guo
2016-09-14 14:21   ` Hanjun Guo
2016-09-14 14:21 ` [RFC PATCH v2 02/11] ACPI: platform-msi: retrieve dev id from IORT Hanjun Guo
2016-09-14 14:21   ` Hanjun Guo
2016-09-14 14:21   ` Hanjun Guo
2016-09-14 14:21 ` [RFC PATCH v2 03/11] irqchip: gicv3-its: platform-msi: refactor its_pmsi_init() to prepare for ACPI Hanjun Guo
2016-09-14 14:21   ` Hanjun Guo
2016-09-14 14:21   ` Hanjun Guo
2016-09-14 14:21 ` [RFC PATCH v2 04/11] irqchip: gicv3-its: platform-msi: scan MADT to create platform msi domain Hanjun Guo
2016-09-14 14:21   ` Hanjun Guo
2016-09-14 14:21   ` Hanjun Guo
2016-09-14 14:21 ` [RFC PATCH v2 05/11] ACPI: platform: setup MSI domain for ACPI based platform device Hanjun Guo
2016-09-14 14:21   ` Hanjun Guo
2016-09-14 14:21   ` Hanjun Guo
2016-09-14 15:45   ` Marc Zyngier
2016-09-14 15:45     ` Marc Zyngier
2016-09-15 14:05     ` Hanjun Guo
2016-09-15 14:05       ` Hanjun Guo
2016-09-15 15:18       ` Marc Zyngier
2016-09-15 15:18         ` Marc Zyngier
2016-09-19  9:42         ` Hanjun Guo
2016-09-19  9:42           ` Hanjun Guo
2016-09-14 14:21 ` [RFC PATCH v2 06/11] msi: platform: make platform_msi_create_device_domain() ACPI aware Hanjun Guo
2016-09-14 14:21   ` Hanjun Guo
2016-09-14 14:21   ` Hanjun Guo
2016-09-14 14:21 ` [RFC PATCH v2 07/11] ACPI: irq: introduce interrupt producer Hanjun Guo
2016-09-14 14:21   ` Hanjun Guo
2016-09-14 14:21   ` Hanjun Guo
2016-09-14 14:21 ` [RFC PATCH v2 08/11] irqchip: mbigen: drop module owner Hanjun Guo
2016-09-14 14:21   ` Hanjun Guo
2016-09-14 14:21   ` Hanjun Guo
2016-09-14 14:21 ` [RFC PATCH v2 09/11] irqchip: mbigen: introduce mbigen_of_create_domain() Hanjun Guo
2016-09-14 14:21   ` Hanjun Guo
2016-09-14 14:21   ` Hanjun Guo
2016-09-14 14:21 ` [RFC PATCH v2 10/11] irqchip: mbigen: Add ACPI support Hanjun Guo
2016-09-14 14:21   ` Hanjun Guo
2016-09-14 14:21   ` Hanjun Guo
2016-09-15  8:49   ` Marc Zyngier
2016-09-15  8:49     ` Marc Zyngier
2016-09-15  8:49     ` Marc Zyngier
2016-09-19  9:28     ` Hanjun Guo
2016-09-19  9:28       ` Hanjun Guo
2016-09-14 14:21 ` [RFC PATCH v2 11/11] irqchip: mbigen: promote mbigen init Hanjun Guo
2016-09-14 14:21   ` Hanjun Guo
2016-09-14 14:21   ` Hanjun Guo
2016-09-15 15:24   ` Marc Zyngier
2016-09-15 15:24     ` Marc Zyngier
2016-09-19  9:49     ` Hanjun Guo
2016-09-19  9:49       ` Hanjun Guo
2016-09-19 10:12       ` Marc Zyngier
2016-09-19 10:12         ` Marc Zyngier
2016-09-20  2:43         ` Hanjun Guo
2016-09-20  2:43           ` Hanjun Guo
2016-09-20  2:43           ` 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.