diff mbox

[v7,1/4] acpi: pci: Setup MSI domain for ACPI based pci devices

Message ID 1449766530-16935-2-git-send-email-Suravee.Suthikulpanit@amd.com (mailing list archive)
State New, archived
Headers show

Commit Message

Suravee Suthikulpanit Dec. 10, 2015, 4:55 p.m. UTC
This patch introduces pci_msi_register_fwnode_provider() for irqchip
to register a callback, to provide a way to determine appropriate MSI
domain for a pci device.

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

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

Comments

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

Bjorn, Rafael,

Do you have any comment on this?

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

Thanks,

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

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

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

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

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

Thanks,

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

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

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

> ---
>  drivers/pci/pci-acpi.c    | 42 ++++++++++++++++++++++++++++++++++++++++++
>  drivers/pci/probe.c       |  2 ++
>  include/linux/irqdomain.h |  5 +++++
>  include/linux/pci.h       | 10 ++++++++++
>  4 files changed, 59 insertions(+)
> 
> diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
> index a32ba75..d3f32d6 100644
> --- a/drivers/pci/pci-acpi.c
> +++ b/drivers/pci/pci-acpi.c
> @@ -9,7 +9,9 @@
>  
>  #include <linux/delay.h>
>  #include <linux/init.h>
> +#include <linux/irqdomain.h>
>  #include <linux/pci.h>
> +#include <linux/msi.h>
>  #include <linux/pci_hotplug.h>
>  #include <linux/module.h>
>  #include <linux/pci-aspm.h>
> @@ -689,6 +691,46 @@ static struct acpi_bus_type acpi_pci_bus = {
>  	.cleanup = pci_acpi_cleanup,
>  };
>  
> +
> +static struct fwnode_handle *(*pci_msi_get_fwnode_cb)(struct device *dev);
> +
> +/**
> + * pci_msi_register_fwnode_provider - Register callback to retrieve fwnode
> + * @fn:       Callback matching a device to a fwnode that identifies a PCI
> + *            MSI domain.
> + *
> + * This should be called by irqchip driver, which is the parent of
> + * the MSI domain to provide callback interface to query fwnode.
> + */
> +void
> +pci_msi_register_fwnode_provider(struct fwnode_handle *(*fn)(struct device *))
> +{
> +	pci_msi_get_fwnode_cb = fn;
> +}
> +
> +/**
> + * pci_host_bridge_acpi_msi_domain - Retrieve MSI domain of a PCI host bridge
> + * @bus:      The PCI host bridge bus.
> + *
> + * This function uses the callback function registered by
> + * pci_msi_register_fwnode_provider() to retrieve the irq_domain with
> + * type DOMAIN_BUS_PCI_MSI of the specified host bridge bus.
> + * This returns NULL on error or when the domain is not found.
> + */
> +struct irq_domain *pci_host_bridge_acpi_msi_domain(struct pci_bus *bus)
> +{
> +	struct fwnode_handle *fwnode;
> +
> +	if (!pci_msi_get_fwnode_cb)
> +		return NULL;
> +
> +	fwnode = pci_msi_get_fwnode_cb(&bus->dev);
> +	if (!fwnode)
> +		return NULL;
> +
> +	return irq_find_matching_fwnode(fwnode, DOMAIN_BUS_PCI_MSI);
> +}
> +
>  static int __init acpi_pci_init(void)
>  {
>  	int ret;
> diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
> index edb1984..553a029 100644
> --- a/drivers/pci/probe.c
> +++ b/drivers/pci/probe.c
> @@ -672,6 +672,8 @@ static struct irq_domain *pci_host_bridge_msi_domain(struct pci_bus *bus)
>  	 * should be called from here.
>  	 */
>  	d = pci_host_bridge_of_msi_domain(bus);
> +	if (!d)
> +		d = pci_host_bridge_acpi_msi_domain(bus);
>  
>  	return d;
>  }
> diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
> index d5e5c5b..a06feda 100644
> --- a/include/linux/irqdomain.h
> +++ b/include/linux/irqdomain.h
> @@ -410,6 +410,11 @@ static inline bool irq_domain_is_hierarchy(struct irq_domain *domain)
>  static inline void irq_dispose_mapping(unsigned int virq) { }
>  static inline void irq_domain_activate_irq(struct irq_data *data) { }
>  static inline void irq_domain_deactivate_irq(struct irq_data *data) { }
> +static inline struct irq_domain *irq_find_matching_fwnode(
> +	struct fwnode_handle *fwnode, enum irq_domain_bus_token bus_token)
> +{
> +	return NULL;
> +}
>  #endif /* !CONFIG_IRQ_DOMAIN */
>  
>  #endif /* _LINUX_IRQDOMAIN_H */
> diff --git a/include/linux/pci.h b/include/linux/pci.h
> index 6ae25aa..d86378c 100644
> --- a/include/linux/pci.h
> +++ b/include/linux/pci.h
> @@ -1946,6 +1946,16 @@ static inline struct irq_domain *
>  pci_host_bridge_of_msi_domain(struct pci_bus *bus) { return NULL; }
>  #endif  /* CONFIG_OF */
>  
> +#ifdef CONFIG_ACPI
> +struct irq_domain *pci_host_bridge_acpi_msi_domain(struct pci_bus *bus);
> +
> +void
> +pci_msi_register_fwnode_provider(struct fwnode_handle *(*fn)(struct device *));
> +#else
> +static inline struct irq_domain *
> +pci_host_bridge_acpi_msi_domain(struct pci_bus *bus) { return NULL; }
> +#endif
> +
>  #ifdef CONFIG_EEH
>  static inline struct eeh_dev *pci_dev_to_eeh_dev(struct pci_dev *pdev)
>  {
> -- 
> 2.1.0
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-pci" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
Suravee Suthikulpanit Dec. 17, 2015, 12:25 a.m. UTC | #5
On 12/16/2015 4:15 PM, Bjorn Helgaas wrote:
> On Thu, Dec 10, 2015 at 08:55:27AM -0800, Suravee Suthikulpanit wrote:
>> >This patch introduces pci_msi_register_fwnode_provider() for irqchip
>> >to register a callback, to provide a way to determine appropriate MSI
>> >domain for a pci device.
>> >
>> >It also introduces pci_host_bridge_acpi_msi_domain(), which returns
>> >the MSI domain of the specified PCI host bridge with DOMAIN_BUS_PCI_MSI
>> >bus token. Then, it is assigned to pci device.
>> >
>> >Reviewed-by: Marc Zyngier<marc.zyngier@arm.com>
>> >Cc: Bjorn Helgaas<bhelgaas@google.com>
>> >Cc: Rafael J. Wysocki<rjw@rjwysocki.net>
>> >Signed-off-by: Suravee Suthikulpanit<Suravee.Suthikulpanit@amd.com>
> Acked-by: Bjorn Helgaas<bhelgaas@google.com>
>
> I assume the whole series will be queued via a non-PCI tree.
>

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

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

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

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

Patch

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