Commit 4b83626a authored by Mauro Carvalho Chehab's avatar Mauro Carvalho Chehab

[media] em28xx: convert i2c wait completion logic to use jiffies

The I2C wait completion/timeout logic currently assumes that
msleep(5) will wait exaclty 5 ms. This is not true at all,
as it depends on CONFIG_HZ.

Convert it to use jiffies, in order to not wait for more time
than needed.
Signed-off-by: default avatarMauro Carvalho Chehab <m.chehab@samsung.com>
parent 5022a208
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/usb.h> #include <linux/usb.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/jiffies.h>
#include "em28xx.h" #include "em28xx.h"
#include "tuner-xc2028.h" #include "tuner-xc2028.h"
...@@ -48,8 +49,8 @@ MODULE_PARM_DESC(i2c_debug, "enable debug messages [i2c]"); ...@@ -48,8 +49,8 @@ MODULE_PARM_DESC(i2c_debug, "enable debug messages [i2c]");
*/ */
static int em2800_i2c_send_bytes(struct em28xx *dev, u8 addr, u8 *buf, u16 len) static int em2800_i2c_send_bytes(struct em28xx *dev, u8 addr, u8 *buf, u16 len)
{ {
unsigned long timeout = jiffies + msecs_to_jiffies(EM2800_I2C_XFER_TIMEOUT);
int ret; int ret;
int write_timeout;
u8 b2[6]; u8 b2[6];
if (len < 1 || len > 4) if (len < 1 || len > 4)
...@@ -74,14 +75,14 @@ static int em2800_i2c_send_bytes(struct em28xx *dev, u8 addr, u8 *buf, u16 len) ...@@ -74,14 +75,14 @@ static int em2800_i2c_send_bytes(struct em28xx *dev, u8 addr, u8 *buf, u16 len)
return (ret < 0) ? ret : -EIO; return (ret < 0) ? ret : -EIO;
} }
/* wait for completion */ /* wait for completion */
for (write_timeout = EM2800_I2C_XFER_TIMEOUT; write_timeout > 0; while (time_is_after_jiffies(timeout)) {
write_timeout -= 5) {
ret = dev->em28xx_read_reg(dev, 0x05); ret = dev->em28xx_read_reg(dev, 0x05);
if (ret == 0x80 + len - 1) { if (ret == 0x80 + len - 1)
return len; return len;
} else if (ret == 0x94 + len - 1) { if (ret == 0x94 + len - 1) {
return -ENODEV; return -ENODEV;
} else if (ret < 0) { }
if (ret < 0) {
em28xx_warn("failed to get i2c transfer status from bridge register (error=%i)\n", em28xx_warn("failed to get i2c transfer status from bridge register (error=%i)\n",
ret); ret);
return ret; return ret;
...@@ -98,9 +99,9 @@ static int em2800_i2c_send_bytes(struct em28xx *dev, u8 addr, u8 *buf, u16 len) ...@@ -98,9 +99,9 @@ static int em2800_i2c_send_bytes(struct em28xx *dev, u8 addr, u8 *buf, u16 len)
*/ */
static int em2800_i2c_recv_bytes(struct em28xx *dev, u8 addr, u8 *buf, u16 len) static int em2800_i2c_recv_bytes(struct em28xx *dev, u8 addr, u8 *buf, u16 len)
{ {
unsigned long timeout = jiffies + msecs_to_jiffies(EM2800_I2C_XFER_TIMEOUT);
u8 buf2[4]; u8 buf2[4];
int ret; int ret;
int read_timeout;
int i; int i;
if (len < 1 || len > 4) if (len < 1 || len > 4)
...@@ -117,14 +118,14 @@ static int em2800_i2c_recv_bytes(struct em28xx *dev, u8 addr, u8 *buf, u16 len) ...@@ -117,14 +118,14 @@ static int em2800_i2c_recv_bytes(struct em28xx *dev, u8 addr, u8 *buf, u16 len)
} }
/* wait for completion */ /* wait for completion */
for (read_timeout = EM2800_I2C_XFER_TIMEOUT; read_timeout > 0; while (time_is_after_jiffies(timeout)) {
read_timeout -= 5) {
ret = dev->em28xx_read_reg(dev, 0x05); ret = dev->em28xx_read_reg(dev, 0x05);
if (ret == 0x84 + len - 1) { if (ret == 0x84 + len - 1)
break; break;
} else if (ret == 0x94 + len - 1) { if (ret == 0x94 + len - 1) {
return -ENODEV; return -ENODEV;
} else if (ret < 0) { }
if (ret < 0) {
em28xx_warn("failed to get i2c transfer status from bridge register (error=%i)\n", em28xx_warn("failed to get i2c transfer status from bridge register (error=%i)\n",
ret); ret);
return ret; return ret;
...@@ -168,7 +169,8 @@ static int em2800_i2c_check_for_device(struct em28xx *dev, u8 addr) ...@@ -168,7 +169,8 @@ static int em2800_i2c_check_for_device(struct em28xx *dev, u8 addr)
static int em28xx_i2c_send_bytes(struct em28xx *dev, u16 addr, u8 *buf, static int em28xx_i2c_send_bytes(struct em28xx *dev, u16 addr, u8 *buf,
u16 len, int stop) u16 len, int stop)
{ {
int write_timeout, ret; unsigned long timeout = jiffies + msecs_to_jiffies(EM2800_I2C_XFER_TIMEOUT);
int ret;
if (len < 1 || len > 64) if (len < 1 || len > 64)
return -EOPNOTSUPP; return -EOPNOTSUPP;
...@@ -191,16 +193,16 @@ static int em28xx_i2c_send_bytes(struct em28xx *dev, u16 addr, u8 *buf, ...@@ -191,16 +193,16 @@ static int em28xx_i2c_send_bytes(struct em28xx *dev, u16 addr, u8 *buf,
} }
} }
/* Check success of the i2c operation */ /* wait for completion */
for (write_timeout = EM2800_I2C_XFER_TIMEOUT; write_timeout > 0; while (time_is_after_jiffies(timeout)) {
write_timeout -= 5) {
ret = dev->em28xx_read_reg(dev, 0x05); ret = dev->em28xx_read_reg(dev, 0x05);
if (ret == 0) { /* success */ if (ret == 0) /* success */
return len; return len;
} else if (ret == 0x10) { if (ret == 0x10) {
return -ENODEV; return -ENODEV;
} else if (ret < 0) { }
em28xx_warn("failed to read i2c transfer status from bridge (error=%i)\n", if (ret < 0) {
em28xx_warn("failed to get i2c transfer status from bridge register (error=%i)\n",
ret); ret);
return ret; return ret;
} }
...@@ -211,6 +213,7 @@ static int em28xx_i2c_send_bytes(struct em28xx *dev, u16 addr, u8 *buf, ...@@ -211,6 +213,7 @@ static int em28xx_i2c_send_bytes(struct em28xx *dev, u16 addr, u8 *buf,
* (even with high payload) ... * (even with high payload) ...
*/ */
} }
em28xx_warn("write to i2c device at 0x%x timed out\n", addr); em28xx_warn("write to i2c device at 0x%x timed out\n", addr);
return -EIO; return -EIO;
} }
...@@ -248,20 +251,18 @@ static int em28xx_i2c_recv_bytes(struct em28xx *dev, u16 addr, u8 *buf, u16 len) ...@@ -248,20 +251,18 @@ static int em28xx_i2c_recv_bytes(struct em28xx *dev, u16 addr, u8 *buf, u16 len)
/* Check success of the i2c operation */ /* Check success of the i2c operation */
ret = dev->em28xx_read_reg(dev, 0x05); ret = dev->em28xx_read_reg(dev, 0x05);
if (ret == 0) /* success */
return len;
if (ret < 0) { if (ret < 0) {
em28xx_warn("failed to read i2c transfer status from bridge (error=%i)\n", em28xx_warn("failed to get i2c transfer status from bridge register (error=%i)\n",
ret); ret);
return ret; return ret;
} }
if (ret > 0) { if (ret == 0x10)
if (ret == 0x10) { return -ENODEV;
return -ENODEV;
} else { em28xx_warn("unknown i2c error (status=%i)\n", ret);
em28xx_warn("unknown i2c error (status=%i)\n", ret); return -EIO;
return -EIO;
}
}
return len;
} }
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment