diff mbox series

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

Message ID 20240616145857.26833-1-marek.vasut+renesas@mailbox.org
State Changes Requested
Delegated to: Tom Rini
Headers show
Series [v5] mmc: Poll CD in case cyclic framework is enabled | expand

Commit Message

Marek Vasut June 16, 2024, 2:58 p.m. UTC
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(+)

Comments

Tom Rini Sept. 5, 2024, 10:02 p.m. UTC | #1
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
Marek Vasut Sept. 6, 2024, 6:28 p.m. UTC | #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
diff mbox series

Patch

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)