phy: marvell: phy-mvebu-cp110-comphy: link failure and lockup built as module (=M)

Josua Mayer josua at solid-run.com
Tue Oct 28 11:09:41 PDT 2025


Am 27.10.25 um 03:06 schrieb Andrew Lunn:
> On Sat, Oct 25, 2025 at 12:45:52PM +0000, Josua Mayer wrote:
>> Dear Maintainers,
>>
>> I came across a bug srelating to cp110 comphy driver.
>>
>> On a board with CN9130 SoC + 2 external CPs Debian 13 freezes during boot,
>> at some point after initramfs and kernel module loading has started.
>>
>> This occurs only when a pci card is present and had link-up from u-boot, e.g.:
>>
>> PCIE-0: Link up (Gen3-x4, Bus0)
>> PCIE-12: Link up (Gen3-x1, Bus12)
>>
>> The issue is reproducible with a generic rootfs, kernel built with arm64 defconfig,
>> no initramfs, but a single kernel configuration change:
>>
>> CONFIG_PHY_MVEBU_CP110_COMPHY=y -> m
>>
>> i.e. building the comphy driver as a module.
>>
>> The problem shows up usually by the console freezing during boot,
>> before eventually the system watchdog hard resets SoC.
> Do you know at what point the comphy driver module is loaded?
By making it a module, loading is delayed till after rootfs mount in my case.
That is after udev has started.
>
> Do you get the same behaviour if the comphy module is not built/not
> available?

In this case the system does not lock up, but pci is not functional either.

With CONFIG_DEBUG_DRIVER=y I can see that pci probe is pending,
waiting for the phys.

>
> I _guess_ that there is some missing EPROBE_DEFER code. It could be
> when the PCIE code tries to get the PHY and fails, it just keeps
> going, when in fact it needs to return EPROBE_DEFER, so that the core
> will try again later, once the module has been loaded.
>
> Actually
>
> static int armada8k_pcie_setup_phys(struct armada8k_pcie *pcie)
> {
>         struct dw_pcie *pci = pcie->pci;
>         struct device *dev = pci->dev;
>         struct device_node *node = dev->of_node;
>         int ret = 0;
>         int i;
>
>         for (i = 0; i < ARMADA8K_PCIE_MAX_LANES; i++) {
>                 pcie->phy[i] = devm_of_phy_get_by_index(dev, node, i);
>                 if (IS_ERR(pcie->phy[i])) {
>                         if (PTR_ERR(pcie->phy[i]) != -ENODEV)
>                                 return PTR_ERR(pcie->phy[i]);
>
>                         pcie->phy[i] = NULL;
>                         continue;
>                 }
>
>                 pcie->phy_count++;
>         }
>
> Do you see devm_of_phy_get_by_index() return -ENODEV? If i'm reading
> this code correctly, it will just continue without the PHY.
This code will return from probe with any error except ENODEV.
So if get_phy returned EDEFER, probe should return EDEFER.

From new boot-log with DEBUG_DRIVER=y, this is the first invocation of pci driver probe:

[   23.091031] platform f2600000.pcie: bus: 'platform': __driver_probe_device: matched device with driver armada8k-pcie
[   23.101921] platform f2600000.pcie: error -EPROBE_DEFER: wait for supplier /cp0-bus/bus at f2000000/phy at 120000/phy at 3
[   23.112436] platform f2600000.pcie: Added to deferred list

And it defers because of fourth lane phy.
Actually that was before the clock driver probed ...

[   24.491274] marvell-cp110-clock f2440000.system-controller:clock: bus: 'platform': really_probe: bound device to driver marvell-cp110-clock

The pci clock is only disabled much later:

[   40.676931] cp110-clk: disabling enabled clock "f2440000-pcie_x4"

At that point pci probe had been deferred 5 times in total.

sincerely
Josua Mayer



More information about the linux-phy mailing list