A while back someone posted a similar patch. Unfortunatly some changes raised 
a discussion which stopped the development process in this direction.

This patch is a small attempt to increase performance without loss for certain 
camera types (I think the main problem was SW-AE).

Please test and get more ideas.

GWater
From 3dd0be4ecd1fa84eb337cc0686ef27354d0cba87 Mon Sep 17 00:00:00 2001
From: Josua Grawitter <[email protected]>
Date: Wed, 11 Mar 2009 15:46:56 +0100
Subject: [PATCH] Increase performance with compiler instructions

	The '(un)likely' is used to increase performance
	in some of our most used functions.

	All changes are based on the assumption that usb_ctl
	transfers are always successful. If they are not the
	driver stops in most cases anyway. Performance often
	ceases to be an issue if video output is disabled.

Signed-off-by: Josua Grawitter <[email protected]>
---
 omnivision.c     |    2 +-
 sn9c20x-bridge.c |   14 +++++++-------
 sn9c20x-usb.c    |    4 ++--
 sn9c20x-v4l2.c   |    6 +++---
 4 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/omnivision.c b/omnivision.c
index 77ad59c..24c7b97 100644
--- a/omnivision.c
+++ b/omnivision.c
@@ -836,7 +836,7 @@ int soi968_button_detect(struct usb_sn9c20x *dev)
 
 	usb_sn9c20x_control_read(dev, 0x1005, &buf, 1);
 
-	if (buf & 0x10) {
+	if (unlikely(buf & 0x10)) {
 		/* button pushed */
 		if (dev->vsettings.auto_gain == 0)
 			dev->vsettings.auto_gain = 1;
diff --git a/sn9c20x-bridge.c b/sn9c20x-bridge.c
index ac54af3..bb0f535 100644
--- a/sn9c20x-bridge.c
+++ b/sn9c20x-bridge.c
@@ -281,7 +281,7 @@ int sn9c20x_i2c_ack_wait(struct usb_sn9c20x *dev, bool highspeed, bool *slave_er
 	for (i = 0; i < 5; i++) {
 		ret = usb_sn9c20x_control_read(dev, 0x10c0, &readbuf, 1);
 
-		if (ret < 0)
+		if (unlikely(ret < 0))
 			return ret;
 		else if (readbuf & SN9C20X_I2C_ERROR) {
 			*slave_error = 1;
@@ -318,7 +318,7 @@ int sn9c20x_read_i2c_data(struct usb_sn9c20x *dev, __u8 nbytes,
 
 	/* first, we must do a dummy write of just the address */
 	ret = sn9c20x_write_i2c_data(dev, 0, address, NULL);
-	if (ret < 0)
+	if (unlikely(ret < 0))
 		return ret;
 
 	memset(row, 0, 5);
@@ -327,12 +327,12 @@ int sn9c20x_read_i2c_data(struct usb_sn9c20x *dev, __u8 nbytes,
 	dev->camera.i2c_flags |= SN9C20X_I2C_READ;
 	ret = sn9c20x_write_i2c_data(dev, nbytes - 1, 0, row);
 	dev->camera.i2c_flags &= ~SN9C20X_I2C_READ;
-	if (ret < 0)
+	if (unlikely(ret < 0))
 		return ret;
 
 	/* finally, ask the bridge for the data */
 	ret = usb_sn9c20x_control_read(dev, 0x10c2, row, 5);
-	if (ret < 0)
+	if (unlikely(ret < 0))
 		return ret;
 
 	UDIA_DEBUG("I2C read: %02x %02x %02x %02x %02x %02x\n",
@@ -411,7 +411,7 @@ int sn9c20x_write_i2c_data_ext(struct usb_sn9c20x *dev, __u8 nbytes,
 		row[7]);
 
 	ret = usb_sn9c20x_control_write(dev, 0x10c0, row, 8);
-	if (ret >= 0)
+	if (likely(ret >= 0))
 		ret = sn9c20x_i2c_ack_wait(dev,
 			dev->camera.i2c_flags & SN9C20X_I2C_400KHZ,
 			&slave_error);
@@ -482,7 +482,7 @@ int sn9c20x_write_i2c_array(struct usb_sn9c20x *dev,
 			ret = sn9c20x_write_i2c_data(dev, 1,
 				regs[i].address, &value8);
 		}
-		if (ret < 0)
+		if (unlikely(ret < 0))
 			return ret;
 	}
 	return ret;
@@ -952,7 +952,7 @@ int sn9c20x_initialize(struct usb_sn9c20x *dev)
 		reg = regs[i][0];
 		value = regs[i][1];
 		ret = usb_sn9c20x_control_write(dev, reg, &value, 1);
-		if (ret < 0) {
+		if (unlikely(ret < 0)) {
 			UDIA_INFO("Bridge Init Error (%d). line %d\n", ret, i);
 			goto err;
 		}
diff --git a/sn9c20x-usb.c b/sn9c20x-usb.c
index c08f650..74c1579 100644
--- a/sn9c20x-usb.c
+++ b/sn9c20x-usb.c
@@ -657,7 +657,7 @@ int usb_sn9c20x_control_write(struct usb_sn9c20x *dev, __u16 value, __u8 *data,
 			length,
 			500);
 
-	if (result < 0)
+	if (unlikely(result < 0))
 		UDIA_ERROR("Write register failed index = 0x%02X\n", value);
 
 	return result;
@@ -692,7 +692,7 @@ int usb_sn9c20x_control_read(struct usb_sn9c20x *dev, __u16 index, __u8 *data, _
 			length,
 			500);
 
-	if (result < 0)
+	if (unlikely(result < 0))
 		UDIA_ERROR("Read register failed 0x%02X\n", index);
 
 	return result;
diff --git a/sn9c20x-v4l2.c b/sn9c20x-v4l2.c
index 6b8918f..627c841 100644
--- a/sn9c20x-v4l2.c
+++ b/sn9c20x-v4l2.c
@@ -491,11 +491,11 @@ static ssize_t v4l_sn9c20x_read(struct file *fp, char __user *buf,
 	dev = video_get_drvdata(video_devdata(fp));
 
 	ret = v4l_get_privileges(fp);
-	if (ret < 0)
+	if (unlikely(ret < 0))
 		return ret;
 
-	if (dev->mode != SN9C20X_MODE_IDLE &&
-	    dev->mode != SN9C20X_MODE_READ)
+	if (unlikely(dev->mode != SN9C20X_MODE_IDLE &&
+	    dev->mode != SN9C20X_MODE_READ))
 		return -EBUSY;
 
 	buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-- 
1.6.0.6

Attachment: signature.asc
Description: This is a digitally signed message part.

Reply via email to