diff mbox series

[15/17] pci: of_property: Add the interrupt-controller property in PCI device nodes

Message ID 20240430083730.134918-16-herve.codina@bootlin.com (mailing list archive)
State Changes Requested
Headers show
Series Add support for the LAN966x PCI device using a DT overlay | expand

Commit Message

Herve Codina April 30, 2024, 8:37 a.m. UTC
PCI devices and bridges DT nodes created during the PCI scan are created
with the interrupt-map property set to handle interrupts.

In order to set this interrupt-map property at a specific level, a
phandle to the parent interrupt controller is needed.
On systems that are not fully described by a device-tree, the parent
interrupt controller may be unavailable (i.e. not described by the
device-tree).

As mentioned in the [1], avoiding the use of the interrupt-map property
and considering a PCI device as an interrupt controller itself avoid the
use of a parent interrupt phandle.

In that case, the PCI device itself as an interrupt controller is
responsible for routing the interrupts described in the device-tree
world (DT overlay) to the PCI interrupts.

Add the 'interrupt-controller' property in the PCI device DT node.

[1]: https://lore.kernel.org/lkml/CAL_Jsq+je7+9ATR=B6jXHjEJHjn24vQFs4Tvi9=vhDeK9n42Aw@mail.gmail.com/

Signed-off-by: Herve Codina <herve.codina@bootlin.com>
---
 drivers/pci/of_property.c | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

Comments

Bjorn Helgaas May 1, 2024, 5:38 p.m. UTC | #1
In subject: s/pci:/PCI:/ to match history. s/Add the/Add/ for brevity.

On Tue, Apr 30, 2024 at 10:37:24AM +0200, Herve Codina wrote:
> PCI devices and bridges DT nodes created during the PCI scan are created
> with the interrupt-map property set to handle interrupts.
> 
> In order to set this interrupt-map property at a specific level, a
> phandle to the parent interrupt controller is needed.
> On systems that are not fully described by a device-tree, the parent
> interrupt controller may be unavailable (i.e. not described by the
> device-tree).

Rewrap into one paragraph or add blank line to separate paragraphs.

> As mentioned in the [1], avoiding the use of the interrupt-map property
> and considering a PCI device as an interrupt controller itself avoid the
> use of a parent interrupt phandle.
> 
> In that case, the PCI device itself as an interrupt controller is
> responsible for routing the interrupts described in the device-tree
> world (DT overlay) to the PCI interrupts.
> 
> Add the 'interrupt-controller' property in the PCI device DT node.
> 
> [1]: https://lore.kernel.org/lkml/CAL_Jsq+je7+9ATR=B6jXHjEJHjn24vQFs4Tvi9=vhDeK9n42Aw@mail.gmail.com/
> 
> Signed-off-by: Herve Codina <herve.codina@bootlin.com>
> ---
>  drivers/pci/of_property.c | 24 ++++++++++++++++++++++++
>  1 file changed, 24 insertions(+)
> 
> diff --git a/drivers/pci/of_property.c b/drivers/pci/of_property.c
> index c2c7334152bc..9f8b940029ed 100644
> --- a/drivers/pci/of_property.c
> +++ b/drivers/pci/of_property.c
> @@ -183,6 +183,26 @@ static int of_pci_prop_interrupts(struct pci_dev *pdev,
>  	return of_changeset_add_prop_u32(ocs, np, "interrupts", (u32)pin);
>  }
>  
> +static int of_pci_prop_intr_ctrl(struct pci_dev *pdev, struct of_changeset *ocs,
> +				 struct device_node *np)
> +{
> +	int ret;
> +	u8 pin;
> +
> +	ret = pci_read_config_byte(pdev, PCI_INTERRUPT_PIN, &pin);
> +	if (ret != 0)
> +		return ret;
> +
> +	if (!pin)
> +		return 0;
> +
> +	ret = of_changeset_add_prop_u32(ocs, np, "#interrupt-cells", 1);
> +	if (ret)
> +		return ret;
> +
> +	return of_changeset_add_prop_bool(ocs, np, "interrupt-controller");
> +}
> +
>  static int of_pci_prop_intr_map(struct pci_dev *pdev, struct of_changeset *ocs,
>  				struct device_node *np)
>  {
> @@ -334,6 +354,10 @@ int of_pci_add_properties(struct pci_dev *pdev, struct of_changeset *ocs,
>  		ret = of_pci_prop_intr_map(pdev, ocs, np);
>  		if (ret)
>  			return ret;
> +	} else {
> +		ret = of_pci_prop_intr_ctrl(pdev, ocs, np);
> +		if (ret)
> +			return ret;
>  	}
>  
>  	ret = of_pci_prop_ranges(pdev, ocs, np);
> -- 
> 2.44.0
>
Herve Codina May 3, 2024, 2:40 p.m. UTC | #2
Hi Bjorn,

On Wed, 1 May 2024 12:38:26 -0500
Bjorn Helgaas <helgaas@kernel.org> wrote:

> In subject: s/pci:/PCI:/ to match history. s/Add the/Add/ for brevity.

Will be done in the next iteration.

> 
> On Tue, Apr 30, 2024 at 10:37:24AM +0200, Herve Codina wrote:
> > PCI devices and bridges DT nodes created during the PCI scan are created
> > with the interrupt-map property set to handle interrupts.
> > 
> > In order to set this interrupt-map property at a specific level, a
> > phandle to the parent interrupt controller is needed.
> > On systems that are not fully described by a device-tree, the parent
> > interrupt controller may be unavailable (i.e. not described by the
> > device-tree).  
> 
> Rewrap into one paragraph or add blank line to separate paragraphs.

Will be rewrapped in one paragraph in the next iteration.

Thanks for your review.
Best regards,
Hervé
diff mbox series

Patch

diff --git a/drivers/pci/of_property.c b/drivers/pci/of_property.c
index c2c7334152bc..9f8b940029ed 100644
--- a/drivers/pci/of_property.c
+++ b/drivers/pci/of_property.c
@@ -183,6 +183,26 @@  static int of_pci_prop_interrupts(struct pci_dev *pdev,
 	return of_changeset_add_prop_u32(ocs, np, "interrupts", (u32)pin);
 }
 
+static int of_pci_prop_intr_ctrl(struct pci_dev *pdev, struct of_changeset *ocs,
+				 struct device_node *np)
+{
+	int ret;
+	u8 pin;
+
+	ret = pci_read_config_byte(pdev, PCI_INTERRUPT_PIN, &pin);
+	if (ret != 0)
+		return ret;
+
+	if (!pin)
+		return 0;
+
+	ret = of_changeset_add_prop_u32(ocs, np, "#interrupt-cells", 1);
+	if (ret)
+		return ret;
+
+	return of_changeset_add_prop_bool(ocs, np, "interrupt-controller");
+}
+
 static int of_pci_prop_intr_map(struct pci_dev *pdev, struct of_changeset *ocs,
 				struct device_node *np)
 {
@@ -334,6 +354,10 @@  int of_pci_add_properties(struct pci_dev *pdev, struct of_changeset *ocs,
 		ret = of_pci_prop_intr_map(pdev, ocs, np);
 		if (ret)
 			return ret;
+	} else {
+		ret = of_pci_prop_intr_ctrl(pdev, ocs, np);
+		if (ret)
+			return ret;
 	}
 
 	ret = of_pci_prop_ranges(pdev, ocs, np);