diff options
author | Mauro Carvalho Chehab <m.chehab@samsung.com> | 2014-01-04 03:42:11 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <m.chehab@samsung.com> | 2014-01-10 03:08:46 -0500 |
commit | 4b83626ac29a66fce15256771dd550e8c4ea2c66 (patch) | |
tree | 09f962cc9d5cddd50bccef8772cceb5f267c6c00 /drivers/media | |
parent | 5022a2088687baeda87b03889d0791b1b908266b (diff) |
[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: Mauro Carvalho Chehab <m.chehab@samsung.com>
Diffstat (limited to 'drivers/media')
-rw-r--r-- | drivers/media/usb/em28xx/em28xx-i2c.c | 61 |
1 files changed, 31 insertions, 30 deletions
diff --git a/drivers/media/usb/em28xx/em28xx-i2c.c b/drivers/media/usb/em28xx/em28xx-i2c.c index f2d5f8a7175b..0af6d790660f 100644 --- a/drivers/media/usb/em28xx/em28xx-i2c.c +++ b/drivers/media/usb/em28xx/em28xx-i2c.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/kernel.h> | 26 | #include <linux/kernel.h> |
27 | #include <linux/usb.h> | 27 | #include <linux/usb.h> |
28 | #include <linux/i2c.h> | 28 | #include <linux/i2c.h> |
29 | #include <linux/jiffies.h> | ||
29 | 30 | ||
30 | #include "em28xx.h" | 31 | #include "em28xx.h" |
31 | #include "tuner-xc2028.h" | 32 | #include "tuner-xc2028.h" |
@@ -48,8 +49,8 @@ MODULE_PARM_DESC(i2c_debug, "enable debug messages [i2c]"); | |||
48 | */ | 49 | */ |
49 | static int em2800_i2c_send_bytes(struct em28xx *dev, u8 addr, u8 *buf, u16 len) | 50 | static int em2800_i2c_send_bytes(struct em28xx *dev, u8 addr, u8 *buf, u16 len) |
50 | { | 51 | { |
52 | unsigned long timeout = jiffies + msecs_to_jiffies(EM2800_I2C_XFER_TIMEOUT); | ||
51 | int ret; | 53 | int ret; |
52 | int write_timeout; | ||
53 | u8 b2[6]; | 54 | u8 b2[6]; |
54 | 55 | ||
55 | if (len < 1 || len > 4) | 56 | 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 | return (ret < 0) ? ret : -EIO; | 75 | return (ret < 0) ? ret : -EIO; |
75 | } | 76 | } |
76 | /* wait for completion */ | 77 | /* wait for completion */ |
77 | for (write_timeout = EM2800_I2C_XFER_TIMEOUT; write_timeout > 0; | 78 | while (time_is_after_jiffies(timeout)) { |
78 | write_timeout -= 5) { | ||
79 | ret = dev->em28xx_read_reg(dev, 0x05); | 79 | ret = dev->em28xx_read_reg(dev, 0x05); |
80 | if (ret == 0x80 + len - 1) { | 80 | if (ret == 0x80 + len - 1) |
81 | return len; | 81 | return len; |
82 | } else if (ret == 0x94 + len - 1) { | 82 | if (ret == 0x94 + len - 1) { |
83 | return -ENODEV; | 83 | return -ENODEV; |
84 | } else if (ret < 0) { | 84 | } |
85 | if (ret < 0) { | ||
85 | em28xx_warn("failed to get i2c transfer status from bridge register (error=%i)\n", | 86 | em28xx_warn("failed to get i2c transfer status from bridge register (error=%i)\n", |
86 | ret); | 87 | ret); |
87 | return ret; | 88 | return ret; |
@@ -98,9 +99,9 @@ static int em2800_i2c_send_bytes(struct em28xx *dev, u8 addr, u8 *buf, u16 len) | |||
98 | */ | 99 | */ |
99 | static int em2800_i2c_recv_bytes(struct em28xx *dev, u8 addr, u8 *buf, u16 len) | 100 | static int em2800_i2c_recv_bytes(struct em28xx *dev, u8 addr, u8 *buf, u16 len) |
100 | { | 101 | { |
102 | unsigned long timeout = jiffies + msecs_to_jiffies(EM2800_I2C_XFER_TIMEOUT); | ||
101 | u8 buf2[4]; | 103 | u8 buf2[4]; |
102 | int ret; | 104 | int ret; |
103 | int read_timeout; | ||
104 | int i; | 105 | int i; |
105 | 106 | ||
106 | if (len < 1 || len > 4) | 107 | 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 | } | 118 | } |
118 | 119 | ||
119 | /* wait for completion */ | 120 | /* wait for completion */ |
120 | for (read_timeout = EM2800_I2C_XFER_TIMEOUT; read_timeout > 0; | 121 | while (time_is_after_jiffies(timeout)) { |
121 | read_timeout -= 5) { | ||
122 | ret = dev->em28xx_read_reg(dev, 0x05); | 122 | ret = dev->em28xx_read_reg(dev, 0x05); |
123 | if (ret == 0x84 + len - 1) { | 123 | if (ret == 0x84 + len - 1) |
124 | break; | 124 | break; |
125 | } else if (ret == 0x94 + len - 1) { | 125 | if (ret == 0x94 + len - 1) { |
126 | return -ENODEV; | 126 | return -ENODEV; |
127 | } else if (ret < 0) { | 127 | } |
128 | if (ret < 0) { | ||
128 | em28xx_warn("failed to get i2c transfer status from bridge register (error=%i)\n", | 129 | em28xx_warn("failed to get i2c transfer status from bridge register (error=%i)\n", |
129 | ret); | 130 | ret); |
130 | return ret; | 131 | return ret; |
@@ -168,7 +169,8 @@ static int em2800_i2c_check_for_device(struct em28xx *dev, u8 addr) | |||
168 | static int em28xx_i2c_send_bytes(struct em28xx *dev, u16 addr, u8 *buf, | 169 | static int em28xx_i2c_send_bytes(struct em28xx *dev, u16 addr, u8 *buf, |
169 | u16 len, int stop) | 170 | u16 len, int stop) |
170 | { | 171 | { |
171 | int write_timeout, ret; | 172 | unsigned long timeout = jiffies + msecs_to_jiffies(EM2800_I2C_XFER_TIMEOUT); |
173 | int ret; | ||
172 | 174 | ||
173 | if (len < 1 || len > 64) | 175 | if (len < 1 || len > 64) |
174 | return -EOPNOTSUPP; | 176 | return -EOPNOTSUPP; |
@@ -191,16 +193,16 @@ static int em28xx_i2c_send_bytes(struct em28xx *dev, u16 addr, u8 *buf, | |||
191 | } | 193 | } |
192 | } | 194 | } |
193 | 195 | ||
194 | /* Check success of the i2c operation */ | 196 | /* wait for completion */ |
195 | for (write_timeout = EM2800_I2C_XFER_TIMEOUT; write_timeout > 0; | 197 | while (time_is_after_jiffies(timeout)) { |
196 | write_timeout -= 5) { | ||
197 | ret = dev->em28xx_read_reg(dev, 0x05); | 198 | ret = dev->em28xx_read_reg(dev, 0x05); |
198 | if (ret == 0) { /* success */ | 199 | if (ret == 0) /* success */ |
199 | return len; | 200 | return len; |
200 | } else if (ret == 0x10) { | 201 | if (ret == 0x10) { |
201 | return -ENODEV; | 202 | return -ENODEV; |
202 | } else if (ret < 0) { | 203 | } |
203 | em28xx_warn("failed to read i2c transfer status from bridge (error=%i)\n", | 204 | if (ret < 0) { |
205 | em28xx_warn("failed to get i2c transfer status from bridge register (error=%i)\n", | ||
204 | ret); | 206 | ret); |
205 | return ret; | 207 | return ret; |
206 | } | 208 | } |
@@ -211,6 +213,7 @@ static int em28xx_i2c_send_bytes(struct em28xx *dev, u16 addr, u8 *buf, | |||
211 | * (even with high payload) ... | 213 | * (even with high payload) ... |
212 | */ | 214 | */ |
213 | } | 215 | } |
216 | |||
214 | em28xx_warn("write to i2c device at 0x%x timed out\n", addr); | 217 | em28xx_warn("write to i2c device at 0x%x timed out\n", addr); |
215 | return -EIO; | 218 | return -EIO; |
216 | } | 219 | } |
@@ -248,20 +251,18 @@ static int em28xx_i2c_recv_bytes(struct em28xx *dev, u16 addr, u8 *buf, u16 len) | |||
248 | 251 | ||
249 | /* Check success of the i2c operation */ | 252 | /* Check success of the i2c operation */ |
250 | ret = dev->em28xx_read_reg(dev, 0x05); | 253 | ret = dev->em28xx_read_reg(dev, 0x05); |
254 | if (ret == 0) /* success */ | ||
255 | return len; | ||
251 | if (ret < 0) { | 256 | if (ret < 0) { |
252 | em28xx_warn("failed to read i2c transfer status from bridge (error=%i)\n", | 257 | em28xx_warn("failed to get i2c transfer status from bridge register (error=%i)\n", |
253 | ret); | 258 | ret); |
254 | return ret; | 259 | return ret; |
255 | } | 260 | } |
256 | if (ret > 0) { | 261 | if (ret == 0x10) |
257 | if (ret == 0x10) { | 262 | return -ENODEV; |
258 | return -ENODEV; | 263 | |
259 | } else { | 264 | em28xx_warn("unknown i2c error (status=%i)\n", ret); |
260 | em28xx_warn("unknown i2c error (status=%i)\n", ret); | 265 | return -EIO; |
261 | return -EIO; | ||
262 | } | ||
263 | } | ||
264 | return len; | ||
265 | } | 266 | } |
266 | 267 | ||
267 | /* | 268 | /* |