From: Neil Horman Date: Fri, 31 Jul 2015 22:56:32 +0000 (-0400) Subject: staging: unisys: visorchannel: Add peek function X-Git-Tag: v4.14-rc1~4839^2~269 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=fdc792cd1b5c86cb34770707aa1b04edce5288cf;p=platform%2Fkernel%2Flinux-rpi.git staging: unisys: visorchannel: Add peek function According to unisys, the s_par hypervisor has a bug in which it never triggers an interrupt. That makes the visornic effectively a 2ms poll loop. In order to just have the rx thread shceduling a napi poll every 2ms, lets instead give it the chance to check the response queue for data before we schedule. This helper provides that functionality Signed-off-by: Neil Horman Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- diff --git a/drivers/staging/unisys/include/visorbus.h b/drivers/staging/unisys/include/visorbus.h index a0144c6..9235536 100644 --- a/drivers/staging/unisys/include/visorbus.h +++ b/drivers/staging/unisys/include/visorbus.h @@ -201,6 +201,8 @@ bool visorchannel_signalremove(struct visorchannel *channel, u32 queue, void *msg); bool visorchannel_signalinsert(struct visorchannel *channel, u32 queue, void *msg); +bool visorchannel_signalempty(struct visorchannel *channel, u32 queue); + int visorchannel_signalqueue_slots_avail(struct visorchannel *channel, u32 queue); int visorchannel_signalqueue_max_slots(struct visorchannel *channel, u32 queue); diff --git a/drivers/staging/unisys/visorbus/visorchannel.c b/drivers/staging/unisys/visorbus/visorchannel.c index 2422464..6da7e49 100644 --- a/drivers/staging/unisys/visorbus/visorchannel.c +++ b/drivers/staging/unisys/visorbus/visorchannel.c @@ -430,6 +430,27 @@ visorchannel_signalremove(struct visorchannel *channel, u32 queue, void *msg) } EXPORT_SYMBOL_GPL(visorchannel_signalremove); +bool +visorchannel_signalempty(struct visorchannel *channel, u32 queue) +{ + unsigned long flags = 0; + struct signal_queue_header sig_hdr; + bool rc = false; + + if (channel->needs_lock) + spin_lock_irqsave(&channel->remove_lock, flags); + + if (!sig_read_header(channel, queue, &sig_hdr)) + rc = true; + if (sig_hdr.head == sig_hdr.tail) + rc = true; + if (channel->needs_lock) + spin_unlock_irqrestore(&channel->remove_lock, flags); + + return rc; +} +EXPORT_SYMBOL_GPL(visorchannel_signalempty); + static bool signalinsert_inner(struct visorchannel *channel, u32 queue, void *msg) {