From: David Kershner <david.kersh...@unisys.com>

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.kersh...@unisys.com>
Signed-off-by: Benjamin Romer <benjamin.ro...@unisys.com>
---
 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
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

Reply via email to