Re: [RFC PATCH] mmc: sdio: Allow sdio code to be build time disabled

Ulf Hansson
2026-01-22T12:09:04Z

On Mon, 5 Jan 2026 at 07:46, Daniel Palmer <daniel@thingy.jp> wrote:
>
> In some cases the sdio support is not needed but the compiler
> cannot tell this and it ends up in your binary.
>
> This might not matter so much on generic kernels for systems
> with gigabytes of memory but in situations with megabytes
> of memory that just have an SD card attached via bitbanged SPI
> over GPIO this is wasteful.
>
> For amd64 disabling SDIO reduces the size of the kernel by ~26KiB.
>
> Signed-off-by: Daniel Palmer <daniel@thingy.jp>
> ---
>
> RFC because this is probably incomplete, maybe not a good idea,..
> I have only tested that this removes the unneeded SDIO code on my
> machine with 8MB of RAM and its still able to enumerate and access
> a 64GB SD card it has connected over SPI.

Hmm, in principle I don't mind this. Although, I assume there are lots
of other subsystems that can be split up using additional Kconfigs in
the similar manner.

Doing this for MMC/SD/SDIO alone seems silly unless we have a broader
consensus to do things like this. Do we have that?

In regards to the implementation and from a very brief review, I
observed two issues.
1) We don't want "#ifdef"-s sprinkled all over the place in the c-code
(headers are fine), then better to use stub-functions.
2) We need to be careful about Kconfig dependencies. The SDIO func
drivers are implemented across various subsystems (bluetooth, wifi,
etc), those corresponding Kconfigs probably need a "depends on SDIO"
too.

Kind regards
Uffe

>
> drivers/mmc/core/Kconfig | 12 +++++++++++-
> drivers/mmc/core/Makefile | 6 +++---
> drivers/mmc/core/core.h | 7 +++++++
> drivers/mmc/core/host.c | 2 ++
> drivers/mmc/core/sdio_bus.h | 5 +++++
> drivers/mmc/core/sdio_cis.h | 4 ++++
> drivers/mmc/core/sdio_ops.h | 14 ++++++++++++++
> 7 files changed, 46 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/mmc/core/Kconfig b/drivers/mmc/core/Kconfig
> index 14d2ecbb04d3..4112242a6c98 100644
> --- a/drivers/mmc/core/Kconfig
> +++ b/drivers/mmc/core/Kconfig
> @@ -64,9 +64,19 @@ config MMC_BLOCK_MINORS
>
> If unsure, say 8 here.
>
> +config MMC_SDIO
> + bool "Support SDIO in MMC core" if EXPERT
> + default y
> + help
> + Enable SDIO support in the MMC core. If you will never use
> + SDIO because your hardware can't support it or your usecase
> + will never need it i.e. you have one SD host and it has fixed
> + eMMC attached to it you can set this to N and remove some
> + unneeded code.
> +
> config SDIO_UART
> tristate "SDIO UART/GPS class support"
> - depends on TTY
> + depends on MMC_SDIO && TTY
> help
> SDIO function driver for SDIO cards that implements the UART
> class, as well as the GPS class which appears like a UART.
> diff --git a/drivers/mmc/core/Makefile b/drivers/mmc/core/Makefile
> index 15b067e8b0d1..efc354150e8a 100644
> --- a/drivers/mmc/core/Makefile
> +++ b/drivers/mmc/core/Makefile
> @@ -6,9 +6,9 @@
> obj-$(CONFIG_MMC) += mmc_core.o
> mmc_core-y := core.o bus.o host.o \
> mmc.o mmc_ops.o sd.o sd_ops.o \
> - sdio.o sdio_ops.o sdio_bus.o \
> - sdio_cis.o sdio_io.o sdio_irq.o sd_uhs2.o\
> - slot-gpio.o regulator.o
> + sd_uhs2.o slot-gpio.o regulator.o
> +mmc_core-$(CONFIG_MMC_SDIO) += sdio.o sdio_ops.o sdio_bus.o \
> + sdio_cis.o sdio_io.o sdio_irq.o
> mmc_core-$(CONFIG_OF) += pwrseq.o
> obj-$(CONFIG_PWRSEQ_SIMPLE) += pwrseq_simple.o
> obj-$(CONFIG_PWRSEQ_SD8787) += pwrseq_sd8787.o
> diff --git a/drivers/mmc/core/core.h b/drivers/mmc/core/core.h
> index a028b48be164..8e2a1abc5523 100644
> --- a/drivers/mmc/core/core.h
> +++ b/drivers/mmc/core/core.h
> @@ -85,7 +85,14 @@ int mmc_detect_card_removed(struct mmc_host *host);
>
> int mmc_attach_mmc(struct mmc_host *host);
> int mmc_attach_sd(struct mmc_host *host);
> +#ifdef CONFIG_MMC_SDIO
> int mmc_attach_sdio(struct mmc_host *host);
> +#else
> +static inline int mmc_attach_sdio(struct mmc_host *host)
> +{
> + return -EOPNOTSUPP;
> +}
> +#endif
> int mmc_attach_sd_uhs2(struct mmc_host *host);
>
> /* Module parameters */
> diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c
> index 88c95dbfd9cf..0216953b8906 100644
> --- a/drivers/mmc/core/host.c
> +++ b/drivers/mmc/core/host.c
> @@ -563,7 +563,9 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev)
> spin_lock_init(&host->lock);
> init_waitqueue_head(&host->wq);
> INIT_DELAYED_WORK(&host->detect, mmc_rescan);
> +#ifdef CONFIG_MMC_SDIO
> INIT_WORK(&host->sdio_irq_work, sdio_irq_work);
> +#endif
> timer_setup(&host->retune_timer, mmc_retune_timer, 0);
>
> INIT_WORK(&host->supply.uv_work, mmc_undervoltage_workfn);
> diff --git a/drivers/mmc/core/sdio_bus.h b/drivers/mmc/core/sdio_bus.h
> index 27b8069a72ab..ad14784b37d1 100644
> --- a/drivers/mmc/core/sdio_bus.h
> +++ b/drivers/mmc/core/sdio_bus.h
> @@ -14,8 +14,13 @@ struct sdio_func *sdio_alloc_func(struct mmc_card *card);
> int sdio_add_func(struct sdio_func *func);
> void sdio_remove_func(struct sdio_func *func);
>
> +#ifdef CONFIG_MMC_SDIO
> int sdio_register_bus(void);
> void sdio_unregister_bus(void);
> +#else
> +#define sdio_register_bus() 0
> +#define sdio_unregister_bus()
> +#endif
>
> #endif
>
> diff --git a/drivers/mmc/core/sdio_cis.h b/drivers/mmc/core/sdio_cis.h
> index 6d76f6fa608c..486eeb802162 100644
> --- a/drivers/mmc/core/sdio_cis.h
> +++ b/drivers/mmc/core/sdio_cis.h
> @@ -13,10 +13,14 @@
> struct mmc_card;
> struct sdio_func;
>
> +#ifdef CONFIG_MMC_SDIO
> int sdio_read_common_cis(struct mmc_card *card);
> void sdio_free_common_cis(struct mmc_card *card);
>
> int sdio_read_func_cis(struct sdio_func *func);
> void sdio_free_func_cis(struct sdio_func *func);
> +#else
> +#define sdio_free_common_cis(card)
> +#endif
>
> #endif
> diff --git a/drivers/mmc/core/sdio_ops.h b/drivers/mmc/core/sdio_ops.h
> index 37f79732a206..dc16e80aa361 100644
> --- a/drivers/mmc/core/sdio_ops.h
> +++ b/drivers/mmc/core/sdio_ops.h
> @@ -12,6 +12,7 @@
> #include <linux/mmc/sdio.h>
>
> struct mmc_host;
> +#ifdef CONFIG_MMC_SDIO
> struct mmc_card;
> struct work_struct;
>
> @@ -33,6 +34,19 @@ static inline bool sdio_is_io_busy(u32 opcode, u32 arg)
> (opcode == SD_IO_RW_DIRECT &&
> !(addr == SDIO_CCCR_ABORT || addr == SDIO_CCCR_SUSPEND)));
> }
> +#else
> +/* These are referenced in code outside of the sdio files so define dummy versions */
> +static inline int sdio_reset(struct mmc_host *host)
> +{
> + return 0;
> +}
> +
> +static inline bool sdio_is_io_busy(u32 opcode, u32 arg)
> +{
> + return false;
> +}
> +#endif
> +
>
> #endif
>
> --
> 2.51.0
>