PCIe multiple child-devices

I am writing a Linux kernel driver (kernel 4.9) for our custom setup. We do use a ARM64( nvidia Jetson Xavier) based board with a PCIe interface. Connected to the interface we have an extension board with a FPGA on it.

At this moment I succeed at creating a device that registers my FPGA with some basic functions, like reading the version of the FPGA in a certain register in the FPGA.

In the FPGA we do have some additional “devices” like GPIO, memory regions … that I would like to add as its own chardevice. We do have existing drivers for these. Normally, Linux goes over the DTB and calls the correct driver for our FPGA, following the correct drivers for our child devices. Now I would like to archieve the same with this PCIe interface. To do this, I look for a node in my DTB fpga and add its children.

for_each_available_child_of_node(np, nc) { 
   subdev = kzalloc(sizeof(*subdev), GFP_KERNEL);
   list_add(&subdev->subdev_entry, &priv->subdev_list.subdev_entry);
   ...
}

list_for_each_entry(subdev, &priv->subdev_list.subdev_entry,
                subdev_entry) {

    ret = mfd_add_devices(priv->dev, PLATFORM_DEVID_NONE,
            subdev->mfd_cell, 1, NULL, irq_base, NULL);

    if (ret) {
        dev_err(priv->dev, "Failed to add mfd cell\n");
        goto err_mfd_add;
    }

}

For some reason, the driver is not loaded for its children. print 's in the device drivers probe function shows nothing, not being called. Added print 's to the loops and it shows its children (all properties and values check out with what I set in the DTB).

Yes, the driver is compiled an available in the kernel. I also tried building the driver as a kmod and load it that way, no change in behaviour. The output of lsmod shows the module is loaded but not used.

Somebody got an idea why my driver is not being loaded?

I also can see the “nodes” from my DTB that should be created as a chardevice. They can be found in the expected location /sys/class/my_fpga/fpga/device/ , in this case GPIO . Under the GPIO folder I can see the driver_override (which is (null) ), modalias , power , sybsystem and uevent . So my device (my_fpga) seems to be enumerated, only its children are not created.

A reboot does not solve it, nor a rescan of the PCIe-bus. The extension-board is powered via an external powersupply and is already configured before booting Linux

Hi,

probe function may only gets called after the platform driver is registered.

Take our kernel driver as example,

kernel/nvidia/drivers/pci/host/pcie-tegra-dw.c

You need to register the tegra_pcie_dw_driver to make the probe function callback gets to use.

return platform_driver_register(&tegra_pcie_dw_driver);

Your case sounds like you only have the FPGA driver got registered. However, those child devices are not?

Thanks for the quick reply.

I do have my FPGA driver registered

static struct pci_driver my_pcie_driver = {
	.name = MY_PCI_DRIVER,
	.id_table = my_pcie_driver_id_table,
	.probe = my_pcie_driver_probe,
	.remove = my_pcie_driver_remove
};

static int __init my_pcie_driver_init(void)
{
    /* Register new PCI driver */
	return pci_register_driver(&my_pcie_driver);
}

The FPGA-driver is registered and is accessible to be read from.
The first 2 WORDS are version and buildstamp in our FPGA registers. I can read them succesfully from userspace.

The children, registerbanks in the FPGA, have their own driver my_registerbank_driver.
In the DTB the property compatible is set so the driver should by matched.
The probe of that driver is not called.

No response/information?

Hi,

This is not Tegra issue. Please refer to existing pci_driver in drivers/mfd and see what is missing here.

Thanks,
Manikanta

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.