[PATCH v5] mmc: Poll CD in case cyclic framework is enabled

In case the cyclic framework is enabled, poll the card detect of already initialized cards and deinitialize them in case they are removed. Since the card initialization is a longer process and card initialization is done on first access to an uninitialized card anyway, avoid initializing newly detected uninitialized cards in the cyclic callback.
Signed-off-by: Marek Vasut marek.vasut+renesas@mailbox.org --- Cc: Jaehoon Chung jh80.chung@samsung.com Cc: Peng Fan peng.fan@nxp.com Cc: Simon Glass sjg@chromium.org --- V2: Move the cyclic registration/unregistration into mmc init/deinit V3: Replace if (CONFIG_IS_ENABLED(CYCLIC)...) with #if as the former does not work with structure members V4: Stuff the code with CONFIG_IS_ENABLED() variants to avoid #ifdefs V5: Rebase on u-boot/next --- drivers/mmc/mmc.c | 32 ++++++++++++++++++++++++++++++++ include/mmc.h | 3 +++ 2 files changed, 35 insertions(+)
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index b18dc331f78..7cf64535b68 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -3005,6 +3005,20 @@ static int mmc_complete_init(struct mmc *mmc) return err; }
+static void __maybe_unused mmc_cyclic_cd_poll(void *ctx) +{ + struct mmc *m = ctx; + + if (!m->has_init) + return; + + if (mmc_getcd(m)) + return; + + mmc_deinit(m); + m->has_init = 0; +} + int mmc_init(struct mmc *mmc) { int err = 0; @@ -3027,6 +3041,19 @@ int mmc_init(struct mmc *mmc) if (err) pr_info("%s: %d, time %lu\n", __func__, err, get_timer(start));
+ if (CONFIG_IS_ENABLED(CYCLIC, (!mmc->cyclic), (NULL))) { + /* Register cyclic function for card detect polling */ + CONFIG_IS_ENABLED(CYCLIC, + (mmc->cyclic = cyclic_register(mmc_cyclic_cd_poll, + 100 * 1000, + mmc->cfg->name, mmc))); + if (CONFIG_IS_ENABLED(CYCLIC, (!mmc->cyclic), (NULL))) { + printf("Failed to register %s CD poll function\n", + mmc->cfg->name); + err = -EINVAL; + } + } + return err; }
@@ -3034,6 +3061,11 @@ int mmc_deinit(struct mmc *mmc) { u32 caps_filtered;
+ if (CONFIG_IS_ENABLED(CYCLIC, (mmc->cyclic), (NULL))) { + cyclic_unregister(CONFIG_IS_ENABLED(CYCLIC, (mmc->cyclic), NULL)); + CONFIG_IS_ENABLED(CYCLIC, (mmc->cyclic = NULL)); + } + if (!CONFIG_IS_ENABLED(MMC_UHS_SUPPORT) && !CONFIG_IS_ENABLED(MMC_HS200_SUPPORT) && !CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)) diff --git a/include/mmc.h b/include/mmc.h index 7f1900363b9..7c98ace5346 100644 --- a/include/mmc.h +++ b/include/mmc.h @@ -14,6 +14,7 @@ #include <linux/sizes.h> #include <linux/compiler.h> #include <linux/dma-direction.h> +#include <cyclic.h> #include <part.h>
struct bd_info; @@ -733,6 +734,8 @@ struct mmc { bool hs400_tuning:1;
enum bus_mode user_speed_mode; /* input speed mode from user */ + + CONFIG_IS_ENABLED(CYCLIC, (struct cyclic_info *cyclic)); };
#if CONFIG_IS_ENABLED(DM_MMC)

On Sun, Jun 16, 2024 at 04:58:49PM +0200, Marek Vasut wrote:
In case the cyclic framework is enabled, poll the card detect of already initialized cards and deinitialize them in case they are removed. Since the card initialization is a longer process and card initialization is done on first access to an uninitialized card anyway, avoid initializing newly detected uninitialized cards in the cyclic callback.
Signed-off-by: Marek Vasut marek.vasut+renesas@mailbox.org
Cc: Jaehoon Chung jh80.chung@samsung.com Cc: Peng Fan peng.fan@nxp.com Cc: Simon Glass sjg@chromium.org
V2: Move the cyclic registration/unregistration into mmc init/deinit V3: Replace if (CONFIG_IS_ENABLED(CYCLIC)...) with #if as the former does not work with structure members V4: Stuff the code with CONFIG_IS_ENABLED() variants to avoid #ifdefs V5: Rebase on u-boot/next
Sorry for the delay here, this no longer builds: sandbox: + sandbox +(sandbox) drivers/mmc/mmc.c: In function ‘mmc_init’: +(sandbox) drivers/mmc/mmc.c:3081:56: error: passing argument 1 of ‘cyclic_register’ from incompatible pointer type [-Werror=incompatible-pointer-types] +(sandbox) 3081 | (mmc->cyclic = cyclic_register(mmc_cyclic_cd_poll, +(sandbox) | ^~~~~~~~~~~~~~~~~~ +(sandbox) | | +(sandbox) | void (*)(void *) +(sandbox) include/linux/kconfig.h:97:23: note: in definition of macro ‘__unwrap’ +(sandbox) 97 | #define __unwrap(...) __VA_ARGS__ +(sandbox) | ^~~~~~~~~~~ +(sandbox) include/linux/kconfig.h:95:26: note: in expansion of macro ‘__unwrap1’ +(sandbox) 95 | #define ___concat(a, b) a ## b +(sandbox) | ^ +(sandbox) include/linux/kconfig.h:102:46: note: in expansion of macro ‘__CONFIG_IS_ENABLED_3’ +(sandbox) 102 | #define __CONFIG_IS_ENABLED_2(option, case1) __CONFIG_IS_ENABLED_3(option, case1, ()) +(sandbox) | ^~~~~~~~~~~~~~~~~~~~~ +(sandbox) include/linux/kconfig.h:95:26: note: in expansion of macro ‘__CONFIG_IS_ENABLED_2’ +(sandbox) drivers/mmc/mmc.c:3080:17: note: in expansion of macro ‘CONFIG_IS_ENABLED’ +(sandbox) 3080 | CONFIG_IS_ENABLED(CYCLIC, +(sandbox) | ^~~~~~~~~~~~~~~~~ +(sandbox) In file included from include/asm-generic/global_data.h:24, +(sandbox) from arch/sandbox/include/asm/global_data.h:26, +(sandbox) from include/dm/of.h:10, +(sandbox) from include/dm/ofnode.h:12, +(sandbox) from include/dm/device.h:13, +(sandbox) from include/dm.h:13, +(sandbox) from drivers/mmc/mmc.c:13: +(sandbox) include/cyclic.h:63:42: note: expected ‘struct cyclic_info *’ but argument is of type ‘void (*)(void *)’ +(sandbox) 63 | void cyclic_register(struct cyclic_info *cyclic, cyclic_func_t func, +(sandbox) | ~~~~~~~~~~~~~~~~~~~~^~~~~~ +(sandbox) In file included from <command-line>: +(sandbox) drivers/mmc/mmc.c:3082:56: error: passing argument 2 of ‘cyclic_register’ makes pointer from integer without a cast [-Werror=int-conversion] +(sandbox) 3082 | 100 * 1000, +(sandbox) | ^~~~~~~~~~ +(sandbox) | int +(sandbox) include/cyclic.h:63:64: note: expected ‘cyclic_func_t’ {aka ‘void (*)(struct cyclic_info *)’} but argument is of type ‘int’ +(sandbox) | ~~~~~~~~~~~~~~^~~~ +(sandbox) drivers/mmc/mmc.c:3083:64: error: passing argument 3 of ‘cyclic_register’ makes integer from pointer without a cast [-Werror=int-conversion] +(sandbox) 3083 | mmc->cfg->name, mmc))); +(sandbox) | ~~~~~~~~^~~~~~ +(sandbox) | | +(sandbox) | const char * +(sandbox) include/cyclic.h:64:31: note: expected ‘uint64_t’ {aka ‘long long unsigned int’} but argument is of type ‘const char *’ +(sandbox) 64 | uint64_t delay_us, const char *name); +(sandbox) | ~~~~~~~~~^~~~~~~~ +(sandbox) drivers/mmc/mmc.c:3083:72: error: passing argument 4 of ‘cyclic_register’ from incompatible pointer type [-Werror=incompatible-pointer-types] +(sandbox) | ^~~ +(sandbox) | | +(sandbox) | struct mmc * +(sandbox) include/cyclic.h:64:53: note: expected ‘const char *’ but argument is of type ‘struct mmc *’ +(sandbox) | ~~~~~~~~~~~~^~~~ +(sandbox) drivers/mmc/mmc.c:3081:38: error: void value not ignored as it ought to be +(sandbox) | ^ +(sandbox) cc1: all warnings being treated as errors +(sandbox) make[3]: *** [scripts/Makefile.build:256: drivers/mmc/mmc.o] Error 1 +(sandbox) make[2]: *** [scripts/Makefile.build:397: drivers/mmc] Error 2 +(sandbox) make[1]: *** [Makefile:1897: drivers] Error 2 +(sandbox) make: *** [Makefile:177: sub-make] Error 2

On 9/6/24 12:02 AM, Tom Rini wrote:
On Sun, Jun 16, 2024 at 04:58:49PM +0200, Marek Vasut wrote:
In case the cyclic framework is enabled, poll the card detect of already initialized cards and deinitialize them in case they are removed. Since the card initialization is a longer process and card initialization is done on first access to an uninitialized card anyway, avoid initializing newly detected uninitialized cards in the cyclic callback.
Signed-off-by: Marek Vasut marek.vasut+renesas@mailbox.org
Cc: Jaehoon Chung jh80.chung@samsung.com Cc: Peng Fan peng.fan@nxp.com Cc: Simon Glass sjg@chromium.org
V2: Move the cyclic registration/unregistration into mmc init/deinit V3: Replace if (CONFIG_IS_ENABLED(CYCLIC)...) with #if as the former does not work with structure members V4: Stuff the code with CONFIG_IS_ENABLED() variants to avoid #ifdefs V5: Rebase on u-boot/next
Sorry for the delay here, this no longer builds: sandbox: + sandbox
Fixed in V6, sigh
participants (3)
-
Marek Vasut
-
Marek Vasut
-
Tom Rini