[no subject]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



interrupt-map = <0x10000 0x00 0x00 0x01 0x1f 0x00 0x11e40000 0x00 0x00>

and then the of_irq_parse_raw() goes to the node with phandle 0x1f
(pcie@11e40000) and tries to find a map for IRQ "0x00 0x11e40000 0x00 0x00"
entry but this one is not there.

Updating the interrupt-map property of pcie@11e40000 node by adding
<0x00 0x00 0x00 0x00 0x1f 0x00 0x00 0x00 0x00> entry solves the issue I'm
seeing:

    interrupt-map = <0x00 0x00 0x00 0x00 0x1f 0x00 0x00 0x00 0x00
                     0x00 0x00 0x00 0x01 0x1f 0x00 0x00 0x00 0x00
                     0x00 0x00 0x00 0x02 0x1f 0x00 0x00 0x00 0x01
                     0x00 0x00 0x00 0x03 0x1f 0x00 0x00 0x00 0x02
                     0x00 0x00 0x00 0x04 0x1f 0x00 0x00 0x00 0x03>;

The code that updates the interrupt map for the node created by
of_pci_make_dev_node() is of_pci_prop_intr_map(). This looks in the IRQ
mapping tree for an INTx interrupt match and looks it up to the parent node
than can provide this interrupt. If a match is found it returns the match
for the node that can provide the interrupt. And this information is used
to populate the interrupt-map property of the node that can is created by
of_pci_make_dev_node().

The following diff I tried solves the problem I see:

diff --git a/drivers/pci/of_property.c b/drivers/pci/of_property.c
index 506fcd507113..7d7f469a1db6 100644
--- a/drivers/pci/of_property.c
+++ b/drivers/pci/of_property.c
@@ -243,6 +243,10 @@ static int of_pci_prop_intr_map(struct pci_dev *pdev,
struct of_changeset *ocs,
                }
                of_property_read_u32(out_irq[i].np, "#address-cells",
                                     &addr_sz[i]);
+               /* Restore the arguments of the next level parent if a map
was found. */
+               out_irq[i].np = pnode;
+               out_irq[i].args_count = 1;
+               out_irq[i].args[0] = pin;
        }

        list_for_each_entry(child, &pdev->subordinate->devices, bus_list) {

With this, the live pcie device tree node is as follows:

pcie@11e40000 {
    power-domains = <0x02>;
    dma-ranges = <0x42000000 0x00 0x48000000 0x00 0x48000000 0x00 0x38000000>;
    pinctrl-names = "default";
    #address-cells = <0x03>;
    bus-range = <0x00 0xff>;
    pinctrl-0 = <0x21>;
    clock-names = "aclk\0pm";
    resets = <0x02 0x53 0x02 0x54 0x02 0x55 0x02 0x56 0x02 0x57 0x02 0x58
0x02 0x59>;
    interrupts = <0x00 0x18b 0x04 0x00 0x18c 0x04 0x00 0x18d 0x04 0x00
0x18e 0x04 0x00 0x18f 0x04 0x00 0x190 0x04 0x00 0x191 0x04 0x00 0x192 0x04
0x00 0x193 0x04 0x00 0x194 0x04 0x00 0x195 0x04 0x00 0x196 0x04 0x00 0x197
0x04 0x00 0x198 0x04 0x00 0x199 0x04 0x00 0x19a 0x04>;
    clocks = <0x02 0x01 0x65 0x02 0x01 0x66>;
    interrupt-map = <0x00 0x00 0x00 0x01 0x1f 0x00 0x00 0x00 0x00
                     0x00 0x00 0x00 0x02 0x1f 0x00 0x00 0x00 0x01
                     0x00 0x00 0x00 0x03 0x1f 0x00 0x00 0x00 0x02
                     0x00 0x00 0x00 0x04 0x1f 0x00 0x00 0x00 0x03>;
    #size-cells = <0x02>;
    renesas,sysc = <0x20>;
    device_type = "pci";
    interrupt-map-mask = <0x00 0x00 0x00 0x07>;
    num-lanes = <0x01>;
    compatible = "renesas,r9a08g045s33-pcie";
    ranges = <0x3000000 0x00 0x30000000 0x00 0x30000000 0x00 0x8000000>;
    #interrupt-cells = <0x01>;
    status = "okay";
    vendor-id = <0x1912>;
    interrupt-names =
"serr\0serr_cor\0serr_nonfatal\0serr_fatal\0axi_err\0inta\0intb\0intc\0intd\0msi\0link_bandwidth\0pm_pme\0dma\0pcie_evt\0msg\0all";
    reg = <0x00 0x11e40000 0x00 0x10000>;
    phandle = <0x1f>;
    reset-names =
"aresetn\0rst_b\0rst_gp_b\0rst_ps_b\0rst_rsm_b\0rst_cfg_b\0rst_load_b";
    device-id = <0x33>;
    interrupt-controller;

    pci@0,0 {
        #address-cells = <0x03>;
        bus-range = <0x01 0xff>;
        interrupt-map = <0x10000 0x00 0x00 0x01 0x1f 0x00 0x11e40000 0x00 0x01
                         0x10000 0x00 0x00 0x02 0x1f 0x00 0x11e40000 0x00 0x02
                         0x10000 0x00 0x00 0x03 0x1f 0x00 0x11e40000 0x00 0x03
                         0x10000 0x00 0x00 0x04 0x1f 0x00 0x11e40000 0x00
0x04>;
        #size-cells = <0x02>;
        device_type = "pci";
        interrupt-map-mask = <0xffff00 0x00 0x00 0x07>;
        compatible = "pci1912,33\0pciclass,060400\0pciclass,0604";
        ranges = <0x82000000 0x00 0x30000000 0x82000000 0x00 0x30000000
0x00 0x100000>;
        #interrupt-cells = <0x01>;
        reg = <0x00 0x00 0x00 0x00 0x00>;
    };
};

Note the interrupt-map property of pci@0,0 changes.

This started to reproduce on my side after the CONFIG_PCI_DYNAMIC_OF_NODES
was enabled in ARM64 defconfig through commits:

b8e22cf599d1 ("arm64: defconfig: Enable OF_OVERLAY option")
10c68f40b86e ("arm64: defconfig: Enable RP1 misc/clock/gpio drivers")

Rob, Bjorn, Lizhi, PCI experts,

Can you please let me know your input on this?

Do you consider there is something wrong with the driver I'm working on
(series [1])?

Thank you for your support,
Claudiu

[1]
https://lore.kernel.org/all/20250530111917.1495023-1-claudiu.beznea.uj@xxxxxxxxxxxxxx

>>
>> Rob: do you know some device trees where the interrupt-map points to the
>> node itself as suggested in [2] so that I can check is something is missing
>> on my side?
>>
>> Thank you,
>> Claudiu
>>
>> [2] https://lore.kernel.org/all/20250509210800.GB4080349-robh@xxxxxxxxxx/
>> [3]
>> https://elixir.bootlin.com/linux/v6.15/source/arch/arm64/boot/dts/apple/t8112.dtsi#L951
>>
> 
> Best regards,
> Hervé
> 





[Index of Archives]     [DMA Engine]     [Linux Coverity]     [Linux USB]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Greybus]

  Powered by Linux