Re: [PATCH v2] pci: quirks: Disable native PCIe hotplug on MSI Claw A8 root bridge
From: Derek John Clark
Date: Sat Aug 08 2026 - 23:34:56 EST
On Sat, Aug 8, 2026 at 1:16 AM Lukas Wunner <lukas@xxxxxxxxx> wrote:
>
> On Fri, Aug 07, 2026 at 05:31:04PM -0700, Derek John Clark wrote:
> > [ 25.686128] rtsx_pci 0000:c2:00.0: pciehp: pdev subsystem vendor ID mismatch
> [...]
> > reg=0x525a10ec expected=0x14af1462
>
> The subsystem vendor ID was 0x1462 (MSI) when the card reader was
> enumerated on boot and it is 0x10ec (Realtek) on resume.
>
> Likewise the subystem device ID was 0x14af on boot, 0x525a on resume.
>
> It's another bug in the MSI BIOS (in addition to marking the Root Port
> hotplug-capable): The BIOS neglected to re-initialize the subsystem
> vendor/device ID registers in config space on resume to the same
> values that it set on boot. The card reader was likely reset while
> going through the system sleep transition and its config space
> thus needs to be re-initialized.
>
> What happens is that pciehp marks the card reader disconnected
> because it assumes that it was replaced during system sleep.
> It then synthesizes a Presence Detect Changed event:
>
> https://elixir.bootlin.com/linux/v7.2-rc6/source/drivers/pci/hotplug/pciehp_core.c#L300
>
> So the pciehp interrupt thread pciehp_ist() will remove the
> rtsx_pci driver and de-enumerate the device.
>
> Replacing or removing PCIe devices during system sleep happens
> all the time (e.g. with Thunderbolt) and we haven't seen issues
> with regards to that. The likelihood is higher that the lockup
> is caused by rtsx_pci.
>
> Maybe rtsx_pci_remove() blocks somewhere and prevents forward
> progress of the resume transition. In particular, it calls
> pm_runtime_get_sync() and cancel_delayed_work_sync(), which are
> blocking calls, i.e. they wait for something else to happen.
> You could try commenting those calls out and see if it avoids
> the lockup:
>
> https://elixir.bootlin.com/linux/v7.2-rc6/source/drivers/misc/cardreader/rtsx_pcr.c#L1608
This was good instinct. I was able to drill down and find
approximately where it is hanging.
rtsx_pci_remove() ->mfd_remove_devices() -> mfd_remove_devices_fn() ->
platform_device_unregister() -> platform_device_del() -> device_del()
-> bus_remove_device() -> device_release_driver() ->
device_release_driver_internal() -> __device_release_driver() ->
device_remove()
In device_remove() (drivers/base/dd.c) it gets past
device_remove_groups() and hangs before completing this if block:
if (dev->bus && dev->bus->remove)
dev->bus->remove(dev);
else if (dev->driver->remove)
dev->driver->remove(dev);
After this logging stops.
- Derek
> Another possibility is a crash due to a NULL pointer deref or
> GPF somewhere in that driver. This is pretty difficult to debug
> if there's no possibility to see any dmesg output.
> Even if we manage to find the root cause of the lockup, as long as
> the BIOS isn't fixed, the card reader will always be de-enumerated
> and re-enumerated on resume and consequently the card will briefly
> disappear. This will make it impossible to use the card as root
> filesystem.
I agree. Even if we were to convince them to fix it, there are plenty
of devices in the wild that will likely never get the BIOS update
since MSI isn't using LFVS for this device. (I'm not sure if they do
that for any device)
> > I've been using a SanDisk Ultra 32GB microSDHC UHS-I Card. And yes, it
> > only happens when the card is present.
>
> If you go to sleep and resume without SD card, do you then see in dmesg
> that the card reader was de-enumerated and re-enumerated? Normally
> there should be at least a "Card not present" / "Card present" message
> from pciehp, if it sensed a replaced device. ("Card" refers to PCIe card,
> not SD card.)
i get card not present, then card present, then link up.
>
> Also, what's the subsystem vendor/device ID as seen with lspci after
> a successful system sleep transition (successful = without SD card)?
it reflects the Realtek device VID/PID. I also tested resume after the
1 cycle with it re-inserted and it works fine after the first cycle,
presumably because the device id matches on the second run and beyond
Thanks,
Derek.
> Thanks,
>
> Lukas