From b953296de73ac75bb380a609f9f30e9fe34e7622 Mon Sep 17 00:00:00 2001 From: xueyanhong Date: Thu, 27 Jan 2022 19:02:06 +0800 Subject: [PATCH] input/buttons: Fix the event lose between the invocation of poll Signed-off-by: xueyanhong --- drivers/input/button_upper.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/drivers/input/button_upper.c b/drivers/input/button_upper.c index ecb669a6e6..3d84c0abd1 100644 --- a/drivers/input/button_upper.c +++ b/drivers/input/button_upper.c @@ -95,6 +95,7 @@ struct btn_open_s * driver events. */ + bool bo_pending; FAR struct pollfd *bo_fds[CONFIG_INPUT_BUTTONS_NPOLLWAITERS]; }; @@ -281,6 +282,10 @@ static void btn_sample(FAR struct btn_upperhalf_s *priv) for (opriv = priv->bu_open; opriv; opriv = opriv->bo_flink) { + /* Always set bo_pending true, only clear it after button read */ + + opriv->bo_pending = true; + /* Have any poll events occurred? */ if ((press & opriv->bo_pollevents.bp_press) != 0 || @@ -488,11 +493,13 @@ static ssize_t btn_read(FAR struct file *filep, FAR char *buffer, size_t len) { FAR struct inode *inode; + FAR struct btn_open_s *opriv; FAR struct btn_upperhalf_s *priv; FAR const struct btn_lowerhalf_s *lower; int ret; DEBUGASSERT(filep && filep->f_inode); + opriv = filep->f_priv; inode = filep->f_inode; DEBUGASSERT(inode->i_private); priv = (FAR struct btn_upperhalf_s *)inode->i_private; @@ -523,6 +530,7 @@ static ssize_t btn_read(FAR struct file *filep, FAR char *buffer, lower = priv->bu_lower; DEBUGASSERT(lower && lower->bl_buttons); *(FAR btn_buttonset_t *)buffer = lower->bl_buttons(lower); + opriv->bo_pending = false; btn_givesem(&priv->bu_exclsem); return (ssize_t)sizeof(btn_buttonset_t); @@ -759,6 +767,19 @@ static int btn_poll(FAR struct file *filep, FAR struct pollfd *fds, opriv->bo_fds[i] = fds; fds->priv = &opriv->bo_fds[i]; + + /* Report if the event is pending */ + + if (opriv->bo_pending) + { + fds->revents |= (fds->events & POLLIN); + if (fds->revents != 0) + { + iinfo("Report events: %02x\n", fds->revents); + nxsem_post(fds->sem); + } + } + break; } }