From: David Kershner <david.kershner@xxxxxxxxxx> Instead of rescheduling the work queue after we have called the channel interrupt, start it when the driver has finished processing the queue. This patch introduces the visorbus_rearm_channel_interrupts function that must get called when the driver decides that it is done processing its queue. Visorinput, visorhba, and visornic were all updated to call the new function. Signed-off-by: David Kershner <david.kershner@xxxxxxxxxx> Signed-off-by: Benjamin Romer <benjamin.romer@xxxxxxxxxx> --- drivers/staging/unisys/include/visorbus.h | 2 ++ drivers/staging/unisys/visorbus/visorbus_main.c | 9 +++++++-- drivers/staging/unisys/visorhba/visorhba_main.c | 6 +++++- drivers/staging/unisys/visorinput/visorinput.c | 5 ++++- drivers/staging/unisys/visornic/visornic_main.c | 6 +++++- 5 files changed, 23 insertions(+), 5 deletions(-) diff --git a/drivers/staging/unisys/include/visorbus.h b/drivers/staging/unisys/include/visorbus.h index 644ca30..5f44289 100644 --- a/drivers/staging/unisys/include/visorbus.h +++ b/drivers/staging/unisys/include/visorbus.h @@ -178,6 +178,8 @@ int visorbus_registerdevnode(struct visor_device *dev, const char *name, int major, int minor); void visorbus_enable_channel_interrupts(struct visor_device *dev); void visorbus_disable_channel_interrupts(struct visor_device *dev); +void visorbus_rearm_channel_interrupts(struct visor_device *dev); + #endif /* Note that for visorchannel_create() diff --git a/drivers/staging/unisys/visorbus/visorbus_main.c b/drivers/staging/unisys/visorbus/visorbus_main.c index 4304ca0..afbb9bc 100644 --- a/drivers/staging/unisys/visorbus/visorbus_main.c +++ b/drivers/staging/unisys/visorbus/visorbus_main.c @@ -715,6 +715,13 @@ unregister_driver_attributes(struct visor_driver *drv) driver_remove_file(&drv->driver, &drv->version_attr); } +visorbus_rearm_channel_interrupts(struct visor_device *dev) +{ + if (!visor_periodic_work_nextperiod(dev->periodic_work)) + put_device(&dev->device); +} +EXPORT_SYMBOL_GPL(visorbus_rearm_channel_interrupts); + static void dev_periodic_work(void *xdev) { @@ -725,8 +732,6 @@ dev_periodic_work(void *xdev) if (drv->channel_interrupt) drv->channel_interrupt(dev); up(&dev->visordriver_callback_lock); - if (!visor_periodic_work_nextperiod(dev->periodic_work)) - put_device(&dev->device); } static void diff --git a/drivers/staging/unisys/visorhba/visorhba_main.c b/drivers/staging/unisys/visorhba/visorhba_main.c index 70bc878..0f6bb26 100644 --- a/drivers/staging/unisys/visorhba/visorhba_main.c +++ b/drivers/staging/unisys/visorhba/visorhba_main.c @@ -1008,12 +1008,16 @@ static void process_incoming_rsps(unsigned long v) const int size = sizeof(*cmdrsp); cmdrsp = kmalloc(size, GFP_ATOMIC); - if (!cmdrsp) + if (!cmdrsp) { + visorbus_rearm_channel_interrupts(devdata->dev); return; + } /* drain queue */ drain_queue(cmdrsp, devdata); + visorbus_rearm_channel_interrupts(devdata->dev); + kfree(cmdrsp); return; } diff --git a/drivers/staging/unisys/visorinput/visorinput.c b/drivers/staging/unisys/visorinput/visorinput.c index 1c2a210..84d0511 100644 --- a/drivers/staging/unisys/visorinput/visorinput.c +++ b/drivers/staging/unisys/visorinput/visorinput.c @@ -673,7 +673,7 @@ visorinput_channel_interrupt(struct visor_device *dev) devdata_get(dev_get_drvdata(&dev->device)); if (!devdata) - return; + goto rearm_interrupts; spin_lock(&devdata->lock_isr); if (devdata->paused) /* don't touch device/channel when paused */ @@ -782,6 +782,9 @@ visorinput_channel_interrupt(struct visor_device *dev) out_locked: devdata_put(devdata); spin_unlock(&devdata->lock_isr); + +rearm_interrupts: + visorbus_rearm_channel_interrupts(dev); } static int diff --git a/drivers/staging/unisys/visornic/visornic_main.c b/drivers/staging/unisys/visornic/visornic_main.c index 9566b91..e8ad219 100644 --- a/drivers/staging/unisys/visornic/visornic_main.c +++ b/drivers/staging/unisys/visornic/visornic_main.c @@ -1712,8 +1712,10 @@ static int visornic_poll(struct napi_struct *napi, int budget) * If there aren't any more packets to receive * stop the poll */ - if (rx_count < budget) + if (rx_count < budget) { napi_complete(napi); + visorbus_rearm_channel_interrupts(devdata->dev); + } return rx_count; } @@ -1734,6 +1736,8 @@ visornic_irq(struct visor_device *v) if (!visorchannel_signalempty(devdata->dev->visorchannel, IOCHAN_FROM_IOPART)) napi_schedule(&devdata->napi); + else + visorbus_rearm_channel_interrupts(v); } /** -- 2.5.0 _______________________________________________ devel mailing list devel@xxxxxxxxxxxxxxxxxxxxxx http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel