[PATCH 09/14] staging: unisys: Re-enable interrupts after we have done the work

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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



[Index of Archives]     [Linux Driver Backports]     [DMA Engine]     [Linux GPIO]     [Linux SPI]     [Video for Linux]     [Linux USB Devel]     [Linux Coverity]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]
  Powered by Linux