All of lore.kernel.org
 help / color / mirror / Atom feed
From: Christian Gromm <christian.gromm@microchip.com>
To: gregkh@linuxfoundation.org
Cc: Christian Gromm <christian.gromm@microchip.com>,
	driverdev-devel@linuxdriverproject.org
Subject: [PATCH 08/28] staging: most: i2c: do not wait in work function
Date: Tue, 8 May 2018 11:44:56 +0200	[thread overview]
Message-ID: <1525772716-15742-9-git-send-email-christian.gromm@microchip.com> (raw)
In-Reply-To: <1525772716-15742-1-git-send-email-christian.gromm@microchip.com>

This patch removes the function wait_event_interruptible from the
work function to avoid waiting.

Signed-off-by: Christian Gromm <christian.gromm@microchip.com>
---
 drivers/staging/most/i2c/i2c.c | 54 ++++++++++++++++--------------------------
 1 file changed, 21 insertions(+), 33 deletions(-)

diff --git a/drivers/staging/most/i2c/i2c.c b/drivers/staging/most/i2c/i2c.c
index b382f09..a993e8e 100644
--- a/drivers/staging/most/i2c/i2c.c
+++ b/drivers/staging/most/i2c/i2c.c
@@ -11,7 +11,6 @@
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/i2c.h>
-#include <linux/sched.h>
 #include <linux/interrupt.h>
 #include <linux/err.h>
 
@@ -47,9 +46,9 @@ struct hdm_i2c {
 	struct i2c_client *client;
 	struct rx {
 		struct delayed_work dwork;
-		wait_queue_head_t waitq;
 		struct list_head list;
 		struct mutex list_mutex;
+		bool int_disabled;
 	} rx;
 	char name[64];
 };
@@ -57,6 +56,7 @@ struct hdm_i2c {
 #define to_hdm(iface) container_of(iface, struct hdm_i2c, most_iface)
 
 static irqreturn_t most_irq_handler(int, void *);
+static void pending_rx_work(struct work_struct *);
 
 /**
  * configure_channel - called from MOST core to configure a channel
@@ -93,6 +93,7 @@ static int configure_channel(struct most_interface *most_iface,
 		dev->polling_mode = polling_req || dev->client->irq <= 0;
 		if (!dev->polling_mode) {
 			pr_info("Requesting IRQ: %d\n", dev->client->irq);
+			dev->rx.int_disabled = false;
 			ret = request_irq(dev->client->irq, most_irq_handler, 0,
 					  dev->client->name, dev);
 			if (ret) {
@@ -104,8 +105,6 @@ static int configure_channel(struct most_interface *most_iface,
 	}
 	if ((channel_config->direction == MOST_CH_RX) && (dev->polling_mode)) {
 		pr_info("Using polling at rate: %d times/sec\n", scan_rate);
-		schedule_delayed_work(&dev->rx.dwork,
-				      msecs_to_jiffies(MSEC_PER_SEC / 4));
 	}
 	dev->is_open[ch_idx] = true;
 
@@ -134,10 +133,16 @@ static int enqueue(struct most_interface *most_iface,
 
 	if (ch_idx == CH_RX) {
 		/* RX */
+		if (!dev->polling_mode)
+			disable_irq(dev->client->irq);
+		cancel_delayed_work_sync(&dev->rx.dwork);
 		mutex_lock(&dev->rx.list_mutex);
 		list_add_tail(&mbo->list, &dev->rx.list);
 		mutex_unlock(&dev->rx.list_mutex);
-		wake_up_interruptible(&dev->rx.waitq);
+		if (dev->rx.int_disabled || dev->polling_mode)
+			pending_rx_work(&dev->rx.dwork.work);
+		if (!dev->polling_mode)
+			enable_irq(dev->client->irq);
 	} else {
 		/* TX */
 		ret = i2c_master_send(dev->client, mbo->virt_address,
@@ -194,7 +199,6 @@ static int poison_channel(struct most_interface *most_iface,
 			mutex_lock(&dev->rx.list_mutex);
 		}
 		mutex_unlock(&dev->rx.list_mutex);
-		wake_up_interruptible(&dev->rx.waitq);
 	}
 
 	return 0;
@@ -204,7 +208,7 @@ static void do_rx_work(struct hdm_i2c *dev)
 {
 	struct mbo *mbo;
 	unsigned char msg[MAX_BUF_SIZE_CONTROL];
-	int ret, ch_idx = CH_RX;
+	int ret;
 	u16 pml, data_size;
 
 	/* Read PML (2 bytes) */
@@ -227,29 +231,7 @@ static void do_rx_work(struct hdm_i2c *dev)
 		return;
 	}
 
-	for (;;) {
-		/* Conditions to wait for: poisoned channel or free buffer
-		 * available for reading
-		 */
-		if (wait_event_interruptible(dev->rx.waitq,
-					     !dev->is_open[ch_idx] ||
-					     !list_empty(&dev->rx.list))) {
-			pr_err("wait_event_interruptible() failed\n");
-			return;
-		}
-
-		if (!dev->is_open[ch_idx])
-			return;
-
-		mutex_lock(&dev->rx.list_mutex);
-
-		/* list may be empty if poison or remove is called */
-		if (!list_empty(&dev->rx.list))
-			break;
-
-		mutex_unlock(&dev->rx.list_mutex);
-	}
-
+	mutex_lock(&dev->rx.list_mutex);
 	mbo = list_first_mbo(&dev->rx.list);
 	list_del(&mbo->list);
 	mutex_unlock(&dev->rx.list_mutex);
@@ -269,6 +251,13 @@ static void do_rx_work(struct hdm_i2c *dev)
 static void pending_rx_work(struct work_struct *work)
 {
 	struct hdm_i2c *dev = container_of(work, struct hdm_i2c, rx.dwork.work);
+	bool empty;
+
+	mutex_lock(&dev->rx.list_mutex);
+	empty = list_empty(&dev->rx.list);
+	mutex_unlock(&dev->rx.list_mutex);
+	if (empty)
+		return;
 
 	do_rx_work(dev);
 
@@ -278,6 +267,7 @@ static void pending_rx_work(struct work_struct *work)
 					      msecs_to_jiffies(MSEC_PER_SEC
 							       / scan_rate));
 	} else {
+		dev->rx.int_disabled = false;
 		enable_irq(dev->client->irq);
 	}
 }
@@ -305,7 +295,7 @@ static irqreturn_t most_irq_handler(int irq, void *_dev)
 	struct hdm_i2c *dev = _dev;
 
 	disable_irq_nosync(irq);
-
+	dev->rx.int_disabled = true;
 	schedule_delayed_work(&dev->rx.dwork, 0);
 
 	return IRQ_HANDLED;
@@ -354,7 +344,6 @@ static int i2c_probe(struct i2c_client *client, const struct i2c_device_id *id)
 
 	INIT_LIST_HEAD(&dev->rx.list);
 	mutex_init(&dev->rx.list_mutex);
-	init_waitqueue_head(&dev->rx.waitq);
 
 	INIT_DELAYED_WORK(&dev->rx.dwork, pending_rx_work);
 
@@ -407,7 +396,6 @@ static struct i2c_driver i2c_driver = {
 
 module_i2c_driver(i2c_driver);
 
-MODULE_AUTHOR("Jain Roy Ambi <JainRoy.Ambi@microchip.com>");
 MODULE_AUTHOR("Andrey Shvetsov <andrey.shvetsov@k2l.de>");
 MODULE_DESCRIPTION("I2C Hardware Dependent Module");
 MODULE_LICENSE("GPL");
-- 
2.7.4

_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

  parent reply	other threads:[~2018-05-08  9:46 UTC|newest]

Thread overview: 39+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-05-08  9:44 [PATCH 00/28] staging: most: fix issues Christian Gromm
2018-05-08  9:44 ` [PATCH 01/28] staging: most: allocate only all requested memory Christian Gromm
2018-05-09 13:19   ` Dan Carpenter
2018-05-09 14:09     ` Christian Gromm
2018-05-09 14:54       ` Dan Carpenter
2018-05-09 15:18         ` Christian Gromm
2018-05-09 15:29           ` Greg KH
2018-05-11  7:36             ` Christian Gromm
2018-05-08  9:44 ` [PATCH 02/28] staging: most: dim2: remove clock speed processing from the HDM Christian Gromm
2018-05-08  9:44 ` [PATCH 03/28] staging: most: i2c: prevent division by zero Christian Gromm
2018-05-08  9:44 ` [PATCH 04/28] staging: most: i2c: remove unnecessary poison_channel call Christian Gromm
2018-05-08  9:44 ` [PATCH 05/28] staging: most: add channel property dbr_size Christian Gromm
2018-05-08  9:44 ` [PATCH 06/28] staging: most: aim-sound: add flexible format support Christian Gromm
2018-05-08  9:44 ` [PATCH 07/28] staging: most: i2c: shorten lifetime of IRQ handler Christian Gromm
2018-05-08  9:44 ` Christian Gromm [this message]
2018-05-08  9:44 ` [PATCH 09/28] staging: most: i2c: avoid polling in case of misconfig Christian Gromm
2018-05-09 13:46   ` Dan Carpenter
2018-05-09 14:20     ` Christian Gromm
2018-05-08  9:44 ` [PATCH 10/28] staging: most: i2c: prevent zero delay polling Christian Gromm
2018-05-08  9:44 ` [PATCH 11/28] staging: most: i2c: trace real polling rate Christian Gromm
2018-05-08  9:45 ` [PATCH 12/28] staging: most: i2c: remove redundant is_open Christian Gromm
2018-05-08  9:45 ` [PATCH 13/28] staging: most: i2c: remove redundant list_mutex Christian Gromm
2018-05-08  9:45 ` [PATCH 14/28] staging: most: i2c: reduce parameters inconsistency Christian Gromm
2018-05-08  9:45 ` [PATCH 15/28] staging: most: make interface drivers allocate coherent memory Christian Gromm
2018-05-08  9:45 ` [PATCH 16/28] staging: most: sound: call snd_card_new with struct device Christian Gromm
2018-05-08  9:45 ` [PATCH 17/28] staging: most: cdev: avoid warning about potentially uninitialized variable Christian Gromm
2018-05-08  9:45 ` [PATCH 18/28] staging: most: cdev: fix chrdev_region leak Christian Gromm
2018-05-08  9:45 ` [PATCH 19/28] staging: most: usb: add ep number to log Christian Gromm
2018-05-08  9:45 ` [PATCH 20/28] staging: most: cdev: fix function return value Christian Gromm
2018-05-08  9:45 ` [PATCH 21/28] staging: most: dim2: fix startup sequence Christian Gromm
2018-05-08  9:45 ` [PATCH 22/28] staging: most: cdev: fix race condition Christian Gromm
2018-05-08  9:45 ` [PATCH 23/28] staging: most: dim2: use device tree Christian Gromm
2021-10-12 18:14   ` Geert Uytterhoeven
2021-10-13 12:24     ` Greg KH
2018-05-08  9:45 ` [PATCH 24/28] staging: most: dim2: read clock speed from the device Christian Gromm
2018-05-08  9:45 ` [PATCH 25/28] staging: most: dim2: use device to allocate coherent memory Christian Gromm
2018-05-08  9:45 ` [PATCH 26/28] staging: most: usb: don't set URB_ZERO_PACKET flag for synchronous data Christian Gromm
2018-05-08  9:45 ` [PATCH 27/28] staging: most: usb: fix usb_disconnect race condition Christian Gromm
2018-05-08  9:45 ` [PATCH 28/28] staging: most: usb: remove local variable Christian Gromm

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1525772716-15742-9-git-send-email-christian.gromm@microchip.com \
    --to=christian.gromm@microchip.com \
    --cc=driverdev-devel@linuxdriverproject.org \
    --cc=gregkh@linuxfoundation.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.