diff options
Diffstat (limited to 'drivers/i2c')
| -rw-r--r-- | drivers/i2c/busses/i2c-imx.c | 4 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-mxs.c | 13 |
2 files changed, 12 insertions, 5 deletions
diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c index 58832e578fff..8d1ab6fa88e1 100644 --- a/drivers/i2c/busses/i2c-imx.c +++ b/drivers/i2c/busses/i2c-imx.c | |||
| @@ -196,7 +196,7 @@ static int i2c_imx_start(struct imx_i2c_struct *i2c_imx) | |||
| 196 | 196 | ||
| 197 | dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__); | 197 | dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__); |
| 198 | 198 | ||
| 199 | clk_enable(i2c_imx->clk); | 199 | clk_prepare_enable(i2c_imx->clk); |
| 200 | writeb(i2c_imx->ifdr, i2c_imx->base + IMX_I2C_IFDR); | 200 | writeb(i2c_imx->ifdr, i2c_imx->base + IMX_I2C_IFDR); |
| 201 | /* Enable I2C controller */ | 201 | /* Enable I2C controller */ |
| 202 | writeb(0, i2c_imx->base + IMX_I2C_I2SR); | 202 | writeb(0, i2c_imx->base + IMX_I2C_I2SR); |
| @@ -245,7 +245,7 @@ static void i2c_imx_stop(struct imx_i2c_struct *i2c_imx) | |||
| 245 | 245 | ||
| 246 | /* Disable I2C controller */ | 246 | /* Disable I2C controller */ |
| 247 | writeb(0, i2c_imx->base + IMX_I2C_I2CR); | 247 | writeb(0, i2c_imx->base + IMX_I2C_I2CR); |
| 248 | clk_disable(i2c_imx->clk); | 248 | clk_disable_unprepare(i2c_imx->clk); |
| 249 | } | 249 | } |
| 250 | 250 | ||
| 251 | static void __init i2c_imx_set_clk(struct imx_i2c_struct *i2c_imx, | 251 | static void __init i2c_imx_set_clk(struct imx_i2c_struct *i2c_imx, |
diff --git a/drivers/i2c/busses/i2c-mxs.c b/drivers/i2c/busses/i2c-mxs.c index 7e78f7c87857..3d471d56bf15 100644 --- a/drivers/i2c/busses/i2c-mxs.c +++ b/drivers/i2c/busses/i2c-mxs.c | |||
| @@ -72,6 +72,7 @@ | |||
| 72 | 72 | ||
| 73 | #define MXS_I2C_QUEUESTAT (0x70) | 73 | #define MXS_I2C_QUEUESTAT (0x70) |
| 74 | #define MXS_I2C_QUEUESTAT_RD_QUEUE_EMPTY 0x00002000 | 74 | #define MXS_I2C_QUEUESTAT_RD_QUEUE_EMPTY 0x00002000 |
| 75 | #define MXS_I2C_QUEUESTAT_WRITE_QUEUE_CNT_MASK 0x0000001F | ||
| 75 | 76 | ||
| 76 | #define MXS_I2C_QUEUECMD (0x80) | 77 | #define MXS_I2C_QUEUECMD (0x80) |
| 77 | 78 | ||
| @@ -219,14 +220,14 @@ static int mxs_i2c_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, | |||
| 219 | int ret; | 220 | int ret; |
| 220 | int flags; | 221 | int flags; |
| 221 | 222 | ||
| 222 | init_completion(&i2c->cmd_complete); | ||
| 223 | |||
| 224 | dev_dbg(i2c->dev, "addr: 0x%04x, len: %d, flags: 0x%x, stop: %d\n", | 223 | dev_dbg(i2c->dev, "addr: 0x%04x, len: %d, flags: 0x%x, stop: %d\n", |
| 225 | msg->addr, msg->len, msg->flags, stop); | 224 | msg->addr, msg->len, msg->flags, stop); |
| 226 | 225 | ||
| 227 | if (msg->len == 0) | 226 | if (msg->len == 0) |
| 228 | return -EINVAL; | 227 | return -EINVAL; |
| 229 | 228 | ||
| 229 | init_completion(&i2c->cmd_complete); | ||
| 230 | |||
| 230 | flags = stop ? MXS_I2C_CTRL0_POST_SEND_STOP : 0; | 231 | flags = stop ? MXS_I2C_CTRL0_POST_SEND_STOP : 0; |
| 231 | 232 | ||
| 232 | if (msg->flags & I2C_M_RD) | 233 | if (msg->flags & I2C_M_RD) |
| @@ -286,6 +287,7 @@ static irqreturn_t mxs_i2c_isr(int this_irq, void *dev_id) | |||
| 286 | { | 287 | { |
| 287 | struct mxs_i2c_dev *i2c = dev_id; | 288 | struct mxs_i2c_dev *i2c = dev_id; |
| 288 | u32 stat = readl(i2c->regs + MXS_I2C_CTRL1) & MXS_I2C_IRQ_MASK; | 289 | u32 stat = readl(i2c->regs + MXS_I2C_CTRL1) & MXS_I2C_IRQ_MASK; |
| 290 | bool is_last_cmd; | ||
| 289 | 291 | ||
| 290 | if (!stat) | 292 | if (!stat) |
| 291 | return IRQ_NONE; | 293 | return IRQ_NONE; |
| @@ -300,9 +302,14 @@ static irqreturn_t mxs_i2c_isr(int this_irq, void *dev_id) | |||
| 300 | else | 302 | else |
| 301 | i2c->cmd_err = 0; | 303 | i2c->cmd_err = 0; |
| 302 | 304 | ||
| 303 | complete(&i2c->cmd_complete); | 305 | is_last_cmd = (readl(i2c->regs + MXS_I2C_QUEUESTAT) & |
| 306 | MXS_I2C_QUEUESTAT_WRITE_QUEUE_CNT_MASK) == 0; | ||
| 307 | |||
| 308 | if (is_last_cmd || i2c->cmd_err) | ||
| 309 | complete(&i2c->cmd_complete); | ||
| 304 | 310 | ||
| 305 | writel(stat, i2c->regs + MXS_I2C_CTRL1_CLR); | 311 | writel(stat, i2c->regs + MXS_I2C_CTRL1_CLR); |
| 312 | |||
| 306 | return IRQ_HANDLED; | 313 | return IRQ_HANDLED; |
| 307 | } | 314 | } |
| 308 | 315 | ||
