[PATCH 1/2] callback: Implement support for registering main loop callbacks

Add initial code for registering callbacks into the main loop. These callbacks should be quick asynchronous functions executed in the background, useful e.g. for polling SD card detect line or for running USB state machine.
Signed-off-by: Marek Vasut marek.vasut+renesas@gmail.com --- common/cli_readline.c | 6 ++++++ common/main.c | 21 +++++++++++++++++++++ include/init.h | 10 ++++++++++ 3 files changed, 37 insertions(+)
diff --git a/common/cli_readline.c b/common/cli_readline.c index 5c158d03b4..5ace4724d2 100644 --- a/common/cli_readline.c +++ b/common/cli_readline.c @@ -266,6 +266,7 @@ static int cread_line(const char *const prompt, char *buf, unsigned int *len, uint64_t etime = endtick(timeout);
while (!tstc()) { /* while no incoming data */ + callback_run(); if (get_ticks() >= etime) return -2; /* timed out */ WATCHDOG_RESET(); @@ -273,6 +274,11 @@ static int cread_line(const char *const prompt, char *buf, unsigned int *len, first = 0; }
+ do { + callback_run(); + WATCHDOG_RESET(); + } while (!tstc()); + ichar = getcmd_getch();
/* ichar=0x0 when error occurs in U-Boot getc */ diff --git a/common/main.c b/common/main.c index ae5bcdb32f..b408e82696 100644 --- a/common/main.c +++ b/common/main.c @@ -18,6 +18,27 @@ #include <version.h> #include <efi_loader.h>
+static LIST_HEAD(callbacks); + +void callback_register(struct callback *cb) +{ + INIT_LIST_HEAD(&cb->list); + list_add_tail(&cb->list, &callbacks); +} + +void callback_unregister(struct callback *cb) +{ + list_del(&cb->list); +} + +void callback_run(void) +{ + struct callback *cb, *pos; + + list_for_each_entry_safe(cb, pos, &callbacks, list) + cb->callback_func(cb); +} + static void run_preboot_environment_command(void) { char *p; diff --git a/include/init.h b/include/init.h index 980be27993..dcc4177316 100644 --- a/include/init.h +++ b/include/init.h @@ -334,6 +334,16 @@ void bdinfo_print_mhz(const char *name, unsigned long hz); /* Show arch-specific information for the 'bd' command */ void arch_print_bdinfo(void);
+struct callback { + struct list_head list; + void (*callback_func)(struct callback *); + void *callback_arg; +}; + +void callback_register(struct callback *cb); +void callback_unregister(struct callback *cb); +void callback_run(void); + #endif /* __ASSEMBLY__ */ /* Put only stuff here that the assembler can digest */

Implement callback for polling the card detect line. This way the driver automatically detects when a card was removed and sets the mmc system state for that particular slot to re-init the card on next use.
Signed-off-by: Marek Vasut marek.vasut+renesas@gmail.com --- drivers/mmc/tmio-common.c | 15 +++++++++++++++ drivers/mmc/tmio-common.h | 3 +++ 2 files changed, 18 insertions(+)
diff --git a/drivers/mmc/tmio-common.c b/drivers/mmc/tmio-common.c index 2c528689bd..57f52af314 100644 --- a/drivers/mmc/tmio-common.c +++ b/drivers/mmc/tmio-common.c @@ -713,6 +713,18 @@ int tmio_sd_bind(struct udevice *dev) return mmc_bind(dev, &plat->mmc, &plat->cfg); }
+static void tmio_sd_poll_cd(struct callback *cb) +{ + struct tmio_sd_plat *plat = container_of(cb, struct tmio_sd_plat, cb_poll_cd); + struct mmc *mmc = &plat->mmc; + struct udevice *dev = mmc->dev; + + if (mmc->has_init && !mmc_getcd(mmc)) { + mmc->has_init = 0; + dev_err(dev, "card removed\n"); + } +} + int tmio_sd_probe(struct udevice *dev, u32 quirks) { struct tmio_sd_plat *plat = dev_get_plat(dev); @@ -775,5 +787,8 @@ int tmio_sd_probe(struct udevice *dev, u32 quirks)
upriv->mmc = &plat->mmc;
+ plat->cb_poll_cd.callback_func = tmio_sd_poll_cd; + callback_register(&plat->cb_poll_cd); + return 0; } diff --git a/drivers/mmc/tmio-common.h b/drivers/mmc/tmio-common.h index 9062300c64..aac3c24e68 100644 --- a/drivers/mmc/tmio-common.h +++ b/drivers/mmc/tmio-common.h @@ -8,6 +8,8 @@ #define __TMIO_COMMON_H__
#include <linux/bitops.h> +#include <init.h> + #define TMIO_SD_CMD 0x000 /* command */ #define TMIO_SD_CMD_NOSTOP BIT(14) /* No automatic CMD12 issue */ #define TMIO_SD_CMD_MULTI BIT(13) /* multiple block transfer */ @@ -114,6 +116,7 @@ struct tmio_sd_plat { struct mmc_config cfg; struct mmc mmc; + struct callback cb_poll_cd; };
struct tmio_sd_priv {
participants (1)
-
Marek Vasut