Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'i2c-embedded/for-3.3' of git://git.pengutronix.de/git/wsa/linux-2.6

i2c bugfix from Wolfram Sang:
"This patch fixes a wrong assumption in the mxs-i2c-driver about a
command queue being done. Without it, we have seen races when the
bus was under load."

* 'i2c-embedded/for-3.3' of git://git.pengutronix.de/git/wsa/linux-2.6:
i2c: mxs: only flag completion when queue is completely done

+10 -3
+10 -3
drivers/i2c/busses/i2c-mxs.c
··· 72 72 73 73 #define MXS_I2C_QUEUESTAT (0x70) 74 74 #define MXS_I2C_QUEUESTAT_RD_QUEUE_EMPTY 0x00002000 75 + #define MXS_I2C_QUEUESTAT_WRITE_QUEUE_CNT_MASK 0x0000001F 75 76 76 77 #define MXS_I2C_QUEUECMD (0x80) 77 78 ··· 220 219 int ret; 221 220 int flags; 222 221 223 - init_completion(&i2c->cmd_complete); 224 - 225 222 dev_dbg(i2c->dev, "addr: 0x%04x, len: %d, flags: 0x%x, stop: %d\n", 226 223 msg->addr, msg->len, msg->flags, stop); 227 224 228 225 if (msg->len == 0) 229 226 return -EINVAL; 227 + 228 + init_completion(&i2c->cmd_complete); 230 229 231 230 flags = stop ? MXS_I2C_CTRL0_POST_SEND_STOP : 0; 232 231 ··· 287 286 { 288 287 struct mxs_i2c_dev *i2c = dev_id; 289 288 u32 stat = readl(i2c->regs + MXS_I2C_CTRL1) & MXS_I2C_IRQ_MASK; 289 + bool is_last_cmd; 290 290 291 291 if (!stat) 292 292 return IRQ_NONE; ··· 302 300 else 303 301 i2c->cmd_err = 0; 304 302 305 - complete(&i2c->cmd_complete); 303 + is_last_cmd = (readl(i2c->regs + MXS_I2C_QUEUESTAT) & 304 + MXS_I2C_QUEUESTAT_WRITE_QUEUE_CNT_MASK) == 0; 305 + 306 + if (is_last_cmd || i2c->cmd_err) 307 + complete(&i2c->cmd_complete); 306 308 307 309 writel(stat, i2c->regs + MXS_I2C_CTRL1_CLR); 310 + 308 311 return IRQ_HANDLED; 309 312 } 310 313