From 5c6c84ee673ddb82c7670aa44a98a3ba9190dc7f Mon Sep 17 00:00:00 2001 From: hanwckf Date: Thu, 31 Aug 2023 18:52:10 +0800 Subject: [PATCH] uboot-202307: add poller support --- uboot-mtk-20230718-09eda825/common/Kconfig | 4 + uboot-mtk-20230718-09eda825/common/Makefile | 1 + uboot-mtk-20230718-09eda825/common/console.c | 2 + uboot-mtk-20230718-09eda825/common/poller.c | 119 ++++++++++++++++++ .../drivers/button/button-uclass.c | 3 + .../drivers/mmc/mmc_write.c | 3 + .../drivers/mtd/nmbm/nmbm-core.c | 6 + .../drivers/mtd/nmbm/nmbm-mtd.c | 3 + uboot-mtk-20230718-09eda825/include/poller.h | 56 +++++++++ 9 files changed, 197 insertions(+) create mode 100644 uboot-mtk-20230718-09eda825/common/poller.c create mode 100644 uboot-mtk-20230718-09eda825/include/poller.h diff --git a/uboot-mtk-20230718-09eda825/common/Kconfig b/uboot-mtk-20230718-09eda825/common/Kconfig index e6ba47ecd..6bccf2f38 100644 --- a/uboot-mtk-20230718-09eda825/common/Kconfig +++ b/uboot-mtk-20230718-09eda825/common/Kconfig @@ -1183,3 +1183,7 @@ config SPL_BMP depends on SPL_VIDEO help Enable bmp functions to display bmp image and get bmp info at SPL. + +config POLLER + bool "generic polling infrastructure" + default n diff --git a/uboot-mtk-20230718-09eda825/common/Makefile b/uboot-mtk-20230718-09eda825/common/Makefile index c87bb2e78..c611c38db 100644 --- a/uboot-mtk-20230718-09eda825/common/Makefile +++ b/uboot-mtk-20230718-09eda825/common/Makefile @@ -113,3 +113,4 @@ obj-$(CONFIG_$(SPL_TPL_)STACKPROTECTOR) += stackprot.o obj-$(CONFIG_SCP03) += scp03.o obj-$(CONFIG_QFW) += qfw.o +obj-$(CONFIG_POLLER) += poller.o diff --git a/uboot-mtk-20230718-09eda825/common/console.c b/uboot-mtk-20230718-09eda825/common/console.c index 71ad8efd6..8d2c68f43 100644 --- a/uboot-mtk-20230718-09eda825/common/console.c +++ b/uboot-mtk-20230718-09eda825/common/console.c @@ -22,6 +22,7 @@ #include #include #include +#include DECLARE_GLOBAL_DATA_PTR; @@ -602,6 +603,7 @@ int getchar(void) int tstc(void) { + poller_call(); if (IS_ENABLED(CONFIG_DISABLE_CONSOLE) && (gd->flags & GD_FLG_DISABLE_CONSOLE)) return 0; diff --git a/uboot-mtk-20230718-09eda825/common/poller.c b/uboot-mtk-20230718-09eda825/common/poller.c new file mode 100644 index 000000000..12b419060 --- /dev/null +++ b/uboot-mtk-20230718-09eda825/common/poller.c @@ -0,0 +1,119 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2010 Marc Kleine-Budde + */ + +#include +#include +#include + +static LIST_HEAD(poller_list); +static int __poller_active; + +bool poller_active(void) +{ + return __poller_active; +} + +int poller_register(struct poller_struct *poller, const char *name) +{ + if (poller->registered) + return -EBUSY; + + poller->name = strdup(name); + list_add_tail(&poller->list, &poller_list); + poller->registered = 1; + + return 0; +} + +int poller_unregister(struct poller_struct *poller) +{ + if (!poller->registered) + return -ENODEV; + + + list_del(&poller->list); + poller->registered = 0; + free(poller->name); + + return 0; +} + +static void poller_async_callback(struct poller_struct *poller) +{ + struct poller_async *pa = container_of(poller, struct poller_async, poller); + + if (!pa->active) + return; + + if (timer_get_us() < pa->end) + return; + + pa->active = 0; + pa->fn(pa->ctx); +} + +/* + * Cancel an outstanding asynchronous function call + * + * @pa the poller that has been scheduled + * + * Cancel an outstanding function call. Returns 0 if the call + * has actually been cancelled or -ENODEV when the call wasn't + * scheduled. + * + */ +int poller_async_cancel(struct poller_async *pa) +{ + pa->active = 0; + + return 0; +} + +/* + * Call a function asynchronously + * + * @pa the poller to be used + * @delay The delay in nanoseconds + * @fn The function to call + * @ctx context pointer passed to the function + * + * This calls the passed function after a delay of delay_us. Returns + * a pointer which can be used as a cookie to cancel a scheduled call. + */ +int poller_call_async(struct poller_async *pa, uint64_t delay_us, + void (*fn)(void *), void *ctx) +{ + pa->ctx = ctx; + pa->end = timer_get_us() + delay_us; + pa->fn = fn; + pa->active = 1; + + return 0; +} + +int poller_async_register(struct poller_async *pa, const char *name) +{ + pa->poller.func = poller_async_callback; + pa->active = 0; + + return poller_register(&pa->poller, name); +} + +int poller_async_unregister(struct poller_async *pa) +{ + return poller_unregister(&pa->poller); +} + +void poller_call(void) +{ + struct poller_struct *poller, *tmp; + + __poller_active = 1; + + list_for_each_entry_safe(poller, tmp, &poller_list, list) + poller->func(poller); + + __poller_active = 0; +} diff --git a/uboot-mtk-20230718-09eda825/drivers/button/button-uclass.c b/uboot-mtk-20230718-09eda825/drivers/button/button-uclass.c index 032191d61..2a5a78525 100644 --- a/uboot-mtk-20230718-09eda825/drivers/button/button-uclass.c +++ b/uboot-mtk-20230718-09eda825/drivers/button/button-uclass.c @@ -11,6 +11,7 @@ #include #include #include +#include int button_get_by_label(const char *label, struct udevice **devp) { @@ -32,6 +33,8 @@ enum button_state_t button_get_state(struct udevice *dev) { struct button_ops *ops = button_get_ops(dev); + poller_call(); + if (!ops->get_state) return -ENOSYS; diff --git a/uboot-mtk-20230718-09eda825/drivers/mmc/mmc_write.c b/uboot-mtk-20230718-09eda825/drivers/mmc/mmc_write.c index a6f93380d..e0a98a78e 100644 --- a/uboot-mtk-20230718-09eda825/drivers/mmc/mmc_write.c +++ b/uboot-mtk-20230718-09eda825/drivers/mmc/mmc_write.c @@ -13,6 +13,7 @@ #include #include #include +#include #include "mmc_private.h" static ulong mmc_erase_t(struct mmc *mmc, ulong start, lbaint_t blkcnt, u32 args) @@ -118,6 +119,7 @@ ulong mmc_berase(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt) } while (blk < blkcnt) { + poller_call(); if (IS_SD(mmc) && mmc->ssr.au) { blk_r = ((blkcnt - blk) > mmc->ssr.au) ? mmc->ssr.au : (blkcnt - blk); @@ -223,6 +225,7 @@ ulong mmc_bwrite(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt, return 0; do { + poller_call(); cur = (blocks_todo > mmc->cfg->b_max) ? mmc->cfg->b_max : blocks_todo; if (mmc_write_blocks(mmc, start, cur, src) != cur) diff --git a/uboot-mtk-20230718-09eda825/drivers/mtd/nmbm/nmbm-core.c b/uboot-mtk-20230718-09eda825/drivers/mtd/nmbm/nmbm-core.c index 5e8b945ed..19397352d 100644 --- a/uboot-mtk-20230718-09eda825/drivers/mtd/nmbm/nmbm-core.c +++ b/uboot-mtk-20230718-09eda825/drivers/mtd/nmbm/nmbm-core.c @@ -9,6 +9,8 @@ #include "nmbm-debug.h" +#include + #define NMBM_VER_MAJOR 1 #define NMBM_VER_MINOR 0 #define NMBM_VER NMBM_VERSION_MAKE(NMBM_VER_MAJOR, \ @@ -2535,6 +2537,8 @@ int nmbm_erase_block_range(struct nmbm_instance *ni, uint64_t addr, while (start_ba <= end_ba) { WATCHDOG_RESET(); + poller_call(); + ret = nmbm_erase_logic_block(ni, start_ba); if (ret) { if (failed_addr) @@ -2907,6 +2911,8 @@ int nmbm_write_range(struct nmbm_instance *ni, uint64_t addr, size_t size, while (sizeremain) { WATCHDOG_RESET(); + poller_call(); + leading = off & ni->writesize_mask; chunksize = ni->lower.writesize - leading; if (chunksize > sizeremain) diff --git a/uboot-mtk-20230718-09eda825/drivers/mtd/nmbm/nmbm-mtd.c b/uboot-mtk-20230718-09eda825/drivers/mtd/nmbm/nmbm-mtd.c index 434cbd5b6..72f3b1d85 100644 --- a/uboot-mtk-20230718-09eda825/drivers/mtd/nmbm/nmbm-mtd.c +++ b/uboot-mtk-20230718-09eda825/drivers/mtd/nmbm/nmbm-mtd.c @@ -12,6 +12,7 @@ #include #include #include +#include #include "nmbm-debug.h" @@ -377,6 +378,8 @@ static int nmbm_mtd_write_data(struct nmbm_mtd *nm, uint64_t addr, while (len || ooblen) { schedule(); + poller_call(); + if (len) { /* Move data */ chklen = nm->lower->writesize - col; diff --git a/uboot-mtk-20230718-09eda825/include/poller.h b/uboot-mtk-20230718-09eda825/include/poller.h new file mode 100644 index 000000000..6c9af9e7f --- /dev/null +++ b/uboot-mtk-20230718-09eda825/include/poller.h @@ -0,0 +1,56 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2010 Marc Kleine-Budde + */ + +#ifndef POLLER_H +#define POLLER_H + +#include +#include + +struct poller_struct { + void (*func)(struct poller_struct *poller); + int registered; + struct list_head list; + char *name; +}; + +int poller_register(struct poller_struct *poller, const char *name); +int poller_unregister(struct poller_struct *poller); + +struct poller_async; + +struct poller_async { + struct poller_struct poller; + void (*fn)(void *); + void *ctx; + uint64_t end; + int active; +}; + +int poller_async_register(struct poller_async *pa, const char *name); +int poller_async_unregister(struct poller_async *pa); + +int poller_call_async(struct poller_async *pa, uint64_t delay_us, + void (*fn)(void *), void *ctx); +int poller_async_cancel(struct poller_async *pa); +static inline bool poller_async_active(struct poller_async *pa) +{ + return pa->active; +} + +#ifdef CONFIG_POLLER +bool poller_active(void); +void poller_call(void); +#else +static inline bool poller_active(void) +{ + return false; +} +static inline void poller_call(void) +{ +} +#endif /* CONFIG_POLLER */ + +#endif /* !POLLER_H */