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

Daniel Palmer
2026-01-05T06:46:15Z

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.

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