uboot-202307: add poller support

This commit is contained in:
hanwckf
2023-08-31 18:52:10 +08:00
parent 0d797b3381
commit 5c6c84ee67
9 changed files with 197 additions and 0 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -22,6 +22,7 @@
#include <watchdog.h>
#include <asm/global_data.h>
#include <linux/delay.h>
#include <poller.h>
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;

View 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;
}

View File

@@ -11,6 +11,7 @@
#include <button.h>
#include <dm.h>
#include <dm/uclass-internal.h>
#include <poller.h>
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;

View File

@@ -13,6 +13,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)
@@ -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)

View File

@@ -9,6 +9,8 @@
#include "nmbm-debug.h"
#include <poller.h>
#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)

View File

@@ -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;

View 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 */