input/djoystick: Fix the event lose between the invocation of poll

Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
This commit is contained in:
Xiang Xiao
2022-02-27 02:52:47 +08:00
committed by Petro Karashchenko
parent 9436a78a5f
commit 2c8437151f
+26 -17
View File
@@ -99,6 +99,7 @@ struct djoy_open_s
* driver events. * driver events.
*/ */
bool do_pollpending;
FAR struct pollfd *do_fds[CONFIG_INPUT_DJOYSTICK_NPOLLWAITERS]; FAR struct pollfd *do_fds[CONFIG_INPUT_DJOYSTICK_NPOLLWAITERS];
}; };
@@ -174,7 +175,6 @@ static void djoy_enable(FAR struct djoy_upperhalf_s *priv)
djoy_buttonset_t press; djoy_buttonset_t press;
djoy_buttonset_t release; djoy_buttonset_t release;
irqstate_t flags; irqstate_t flags;
int i;
DEBUGASSERT(priv); DEBUGASSERT(priv);
lower = priv->du_lower; lower = priv->du_lower;
@@ -193,19 +193,8 @@ static void djoy_enable(FAR struct djoy_upperhalf_s *priv)
for (opriv = priv->du_open; opriv; opriv = opriv->do_flink) for (opriv = priv->du_open; opriv; opriv = opriv->do_flink)
{ {
/* Are there any poll waiters? */ press |= opriv->do_pollevents.dp_press;
release |= opriv->do_pollevents.dp_release;
for (i = 0; i < CONFIG_INPUT_DJOYSTICK_NPOLLWAITERS; i++)
{
if (opriv->do_fds[i])
{
/* Yes.. OR in the poll event buttons */
press |= opriv->do_pollevents.dp_press;
release |= opriv->do_pollevents.dp_release;
break;
}
}
/* OR in the signal events */ /* OR in the signal events */
@@ -285,8 +274,8 @@ static void djoy_sample(FAR struct djoy_upperhalf_s *priv)
* newly released. * newly released.
*/ */
change = sample ^ priv->du_sample; change = sample ^ priv->du_sample;
press = change & sample; press = change & sample;
DEBUGASSERT(lower->dl_supported); DEBUGASSERT(lower->dl_supported);
release = change & (lower->dl_supported(lower) & ~sample); release = change & (lower->dl_supported(lower) & ~sample);
@@ -300,6 +289,8 @@ static void djoy_sample(FAR struct djoy_upperhalf_s *priv)
if ((press & opriv->do_pollevents.dp_press) != 0 || if ((press & opriv->do_pollevents.dp_press) != 0 ||
(release & opriv->do_pollevents.dp_release) != 0) (release & opriv->do_pollevents.dp_release) != 0)
{ {
opriv->do_pollpending = true;
/* Yes.. Notify all waiters */ /* Yes.. Notify all waiters */
for (i = 0; i < CONFIG_INPUT_DJOYSTICK_NPOLLWAITERS; i++) for (i = 0; i < CONFIG_INPUT_DJOYSTICK_NPOLLWAITERS; i++)
@@ -385,6 +376,10 @@ static int djoy_open(FAR struct file *filep)
opriv->do_flink = priv->du_open; opriv->do_flink = priv->du_open;
priv->du_open = opriv; priv->du_open = opriv;
/* Enable/disable interrupt handling */
djoy_enable(priv);
/* Attach the open structure to the file structure */ /* Attach the open structure to the file structure */
filep->f_priv = (FAR void *)opriv; filep->f_priv = (FAR void *)opriv;
@@ -498,11 +493,13 @@ static ssize_t djoy_read(FAR struct file *filep, FAR char *buffer,
size_t len) size_t len)
{ {
FAR struct inode *inode; FAR struct inode *inode;
FAR struct djoy_open_s *opriv;
FAR struct djoy_upperhalf_s *priv; FAR struct djoy_upperhalf_s *priv;
FAR const struct djoy_lowerhalf_s *lower; FAR const struct djoy_lowerhalf_s *lower;
int ret; int ret;
DEBUGASSERT(filep && filep->f_inode); DEBUGASSERT(filep && filep->f_inode);
opriv = filep->f_priv;
inode = filep->f_inode; inode = filep->f_inode;
DEBUGASSERT(inode->i_private); DEBUGASSERT(inode->i_private);
priv = (FAR struct djoy_upperhalf_s *)inode->i_private; priv = (FAR struct djoy_upperhalf_s *)inode->i_private;
@@ -532,6 +529,7 @@ static ssize_t djoy_read(FAR struct file *filep, FAR char *buffer,
DEBUGASSERT(lower && lower->dl_sample); DEBUGASSERT(lower && lower->dl_sample);
priv->du_sample = lower->dl_sample(lower); priv->du_sample = lower->dl_sample(lower);
*(FAR djoy_buttonset_t *)buffer = priv->du_sample; *(FAR djoy_buttonset_t *)buffer = priv->du_sample;
opriv->do_pollpending = false;
ret = sizeof(djoy_buttonset_t); ret = sizeof(djoy_buttonset_t);
djoy_givesem(&priv->du_exclsem); djoy_givesem(&priv->du_exclsem);
@@ -713,6 +711,17 @@ static int djoy_poll(FAR struct file *filep, FAR struct pollfd *fds,
opriv->do_fds[i] = fds; opriv->do_fds[i] = fds;
fds->priv = &opriv->do_fds[i]; fds->priv = &opriv->do_fds[i];
if (opriv->do_pollpending)
{
fds->revents |= (fds->events & POLLIN);
if (fds->revents != 0)
{
iinfo("Report events: %02x\n", fds->revents);
nxsem_post(fds->sem);
}
}
break; break;
} }
} }
@@ -765,7 +774,7 @@ errout_with_dusem:
* *
* Input Parameters: * Input Parameters:
* devname - The name of the discrete joystick device to be registers. * devname - The name of the discrete joystick device to be registers.
* This should be a string of the form "/priv/djoyN" where N is the * This should be a string of the form "/dev/djoyN" where N is the
* minor device number. * minor device number.
* lower - An instance of the platform-specific discrete joystick lower * lower - An instance of the platform-specific discrete joystick lower
* half driver. * half driver.