[RFC] bcm2837 RPi 3B: sdhci-iproc Wi-Fi probe fails without sdhost (GPIO48-53 left in alt3 by firmware)

From: Martin Wetterwald

Date: Wed Oct 07 2026 - 10:39:19 EST


Hello,
When building a minimal kernel for the Raspberry Pi 3B which doesn't need
sdcard access at all (root filesystem fully lives in RAM), I noticed that the
Wi-Fi doesn't work (kernel 7.2.6 with bcm2837-rpi-3-b.dts).

With:
> CONFIG_MMC_SDHCI_IPROC=y
> CONFIG_MMC_BCM2835=n
Wi-Fi doesn't work with following messages:

> sdhci-iproc 3f300000.mmc: allocated mmc-pwrseq
> mmc0: SDHCI controller on 3f300000.mmc [3f300000.mmc] using PIO
> mmc0: Failed to initialize a non-removable card

With:
> CONFIG_MMC_SDHCI_IPROC=y
> CONFIG_MMC_BCM2835=y
Wi-Fi works:

> sdhci-iproc 3f300000.mmc: allocated mmc-pwrseq
> mmc1: SDHCI controller on 3f300000.mmc [3f300000.mmc] using PIO
> sdhost-bcm2835 3f202000.mmc: loaded - DMA enabled (>1)
> mmc1: new high speed SDIO card at address 0001
> brcmfmac: brcmf_fw_alloc_request: using brcm/brcmfmac43430-sdio for chip BCM43430/1
> mmc0: host does not support reading read-only switch, assuming write-enable
> mmc0: new high speed SDXC card at address d555
> brcmfmac: brcmf_c_process_txcap_blob: no txcap_blob available (err=-2)
> brcmfmac: brcmf_c_preinit_dcmds: Firmware: BCM43430/1 wl0: Mar 30 2021 01:12:21 version 7.45.98.118 (7d96287 CY) FWID 01-32059766

So, just adding CONFIG_MMC_BCM2835 makes Wi-Fi start working.
In my understanding, CONFIG_MMC_BCM2835 should not be needed to use the Wi-Fi.

After analysis, I noticed that the Raspberry Pi firmware leaves GPIO48-53 pins
in the alt3 state when Linux takes over (sdcard pins routed to sdhci-iproc).
When CONFIG_MMC_BCM2835 is not compiled in, the states of those GPIOs won't be
changed by Linux. And we end up with the sdhci-iproc controller electrically
bound to the Wi-Fi chip and the sdcard at the same time, resulting in a probe
error for the Wi-Fi chip.

Here are the states of GPFSEL3 GPFSEL4 and GPFSEL5 tested with devmem:

Register Address GPIOs MMC_BCM2835=y MMC_BCM2835=n
-------- ---------- ------- ------------- -------------
GPFSEL3 0x3f20000c 30-39 0x3FFFF000 0x3FFFF000
GPFSEL4 0x3f200010 40-49 0x24200924 0x3F200924
GPFSEL5 0x3f200014 50-59 0x00000924 0x00000FFF

3 bits per pin: 4 = ALT0 (sdhost), 7 = ALT3 (sdhci-iproc)

In the MMC_BCM2835=n case, we can see that GPIOs 48-53 are left on alt3.

I would like to be able to compile Linux with CONFIG_MMC_SDHCI_IPROC and
without CONFIG_MMC_BCM2835.
What is the best approach here? Is the kernel expected to rely on the GPIO
state left by the firmware? Or should it configure these pins itself?

I tried to have both sdhost and sdhci-iproc claim GPIO48-53 in the same state
to avoid the double routing, but it's not possible because pins can only be
claimed by 1 owner:
> pinctrl-bcm2835 3f200000.gpio: pin gpio48 already requested by 3f202000.mmc; cannot claim for 3f300000.mmc
> pinctrl-bcm2835 3f200000.gpio: error -22: pin-48 (3f300000.mmc)
> pinctrl-bcm2835 3f200000.gpio: error -22: could not request pin 48 (gpio48) from group gpio48 on device pinctrl-bcm2835
> sdhci-iproc 3f300000.mmc: error -22: Error applying setting, reverse things back

1) A solution could be to let the gpio-controller itself own those pins. I can
propose a patch removing:
> pinctrl-names = "default";
> pinctrl-0 = <&sdhost_gpio48>;

from the node &sdhost in the top level DTSes and make the gpio-controller
itself change those pin states, so that no matter which SD controllers are
compiled in, it will work.
I tested this on a 3B in all four combinations (sdhost and sdhci-iproc each
enabled or not), and it works. It adds one message to the dmesg:
> /soc/gpio@7e200000: Fixed dependency cycle(s) with /soc/gpio@7e200000/sdhost-gpio48

2) Or, if we can't support RPi kernels with CONFIG_MMC_SDHCI_IPROC=y and
CONFIG_MMC_BCM2835=n, we could perhaps add a Kconfig restriction selecting
CONFIG_MMC_BCM2835 automatically if that's really required.

3) Another solution could be to ask for a firmware change, so that the states
are cleaned before booting.

What do you think of those proposals?
Martin