uboot-2025: add poller
This commit is contained in:
@@ -1255,3 +1255,7 @@ config FDT_NO_BOOTARGS_OVERRIDE
|
||||
help
|
||||
Enable this option to avoid bootargs in fdt being overrided by that
|
||||
set in environment.
|
||||
|
||||
config POLLER
|
||||
bool "generic polling infrastructure"
|
||||
default n
|
||||
|
||||
@@ -107,3 +107,4 @@ obj-$(CONFIG_$(PHASE_)STACKPROTECTOR) += stackprot.o
|
||||
obj-$(CONFIG_SCP03) += scp03.o
|
||||
|
||||
obj-$(CONFIG_QFW) += qfw.o
|
||||
obj-$(CONFIG_POLLER) += poller.o
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include <watchdog.h>
|
||||
#include <asm/global_data.h>
|
||||
#include <linux/delay.h>
|
||||
#include <poller.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
@@ -625,6 +626,7 @@ int getchar(void)
|
||||
|
||||
int tstc(void)
|
||||
{
|
||||
poller_call();
|
||||
if (IS_ENABLED(CONFIG_DISABLE_CONSOLE) && (gd->flags & GD_FLG_DISABLE_CONSOLE))
|
||||
return 0;
|
||||
|
||||
|
||||
119
uboot-mtk-20250711/common/poller.c
Normal file
119
uboot-mtk-20250711/common/poller.c
Normal file
@@ -0,0 +1,119 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (C) 2010 Marc Kleine-Budde <mkl@pengutronix.de>
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <malloc.h>
|
||||
#include <poller.h>
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <dm.h>
|
||||
#include <dm/uclass-internal.h>
|
||||
#include <dt-bindings/input/linux-event-codes.h>
|
||||
#include <poller.h>
|
||||
|
||||
int button_get_by_label(const char *label, struct udevice **devp)
|
||||
{
|
||||
@@ -32,6 +33,7 @@ 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;
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <part.h>
|
||||
#include <div64.h>
|
||||
#include <linux/math64.h>
|
||||
#include <poller.h>
|
||||
#include "mmc_private.h"
|
||||
|
||||
static ulong mmc_erase_t(struct mmc *mmc, ulong start, lbaint_t blkcnt, u32 args)
|
||||
@@ -119,6 +120,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);
|
||||
@@ -233,6 +235,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)
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "nmbm-private.h"
|
||||
|
||||
#include "nmbm-debug.h"
|
||||
#include <poller.h>
|
||||
|
||||
#define NMBM_VER_MAJOR 1
|
||||
#define NMBM_VER_MINOR 0
|
||||
@@ -2535,6 +2536,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)
|
||||
@@ -2667,6 +2670,8 @@ int nmbm_read_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)
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <linux/mtd/mtd.h>
|
||||
#include <jffs2/load_kernel.h>
|
||||
#include <watchdog.h>
|
||||
#include <poller.h>
|
||||
|
||||
#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;
|
||||
|
||||
56
uboot-mtk-20250711/include/poller.h
Normal file
56
uboot-mtk-20250711/include/poller.h
Normal file
@@ -0,0 +1,56 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (C) 2010 Marc Kleine-Budde <mkl@pengutronix.de>
|
||||
*/
|
||||
|
||||
#ifndef POLLER_H
|
||||
#define POLLER_H
|
||||
|
||||
#include <linux/list.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
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 */
|
||||
Reference in New Issue
Block a user