Commit 4e78f002 authored by Linus Torvalds's avatar Linus Torvalds

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

Pull i2c embedded fixes from Wolfram Sang:
 "Here are some typical i2c driver bugfixes for 3.4.  Missed clock
  handling, improper timeout fixes, hardware wrokarounds...  All
  patches have been in linux-next for a few days, too."

* 'i2c-embedded/for-current' of git://git.pengutronix.de/git/wsa/linux:
  i2c: mxs: disable QUEUE when sending is done
  i2c: mxs: handle spurious interrupt
  i2c-eg20t: Modify MODULE_AUTHOR's email address
  i2c-eg20t: change timeout value 50msec to 1000msec
  i2c: tegra: Add delay before resetting the controller after NACK
  i2c: pnx: Disable clk in suspend
parents f5645b59 1e4f0b82
...@@ -324,7 +324,7 @@ static s32 pch_i2c_wait_for_xfer_complete(struct i2c_algo_pch_data *adap) ...@@ -324,7 +324,7 @@ static s32 pch_i2c_wait_for_xfer_complete(struct i2c_algo_pch_data *adap)
{ {
long ret; long ret;
ret = wait_event_timeout(pch_event, ret = wait_event_timeout(pch_event,
(adap->pch_event_flag != 0), msecs_to_jiffies(50)); (adap->pch_event_flag != 0), msecs_to_jiffies(1000));
if (ret == 0) { if (ret == 0) {
pch_err(adap, "timeout: %x\n", adap->pch_event_flag); pch_err(adap, "timeout: %x\n", adap->pch_event_flag);
...@@ -1063,6 +1063,6 @@ module_exit(pch_pci_exit); ...@@ -1063,6 +1063,6 @@ module_exit(pch_pci_exit);
MODULE_DESCRIPTION("Intel EG20T PCH/LAPIS Semico ML7213/ML7223/ML7831 IOH I2C"); MODULE_DESCRIPTION("Intel EG20T PCH/LAPIS Semico ML7213/ML7223/ML7831 IOH I2C");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_AUTHOR("Tomoya MORINAGA. <tomoya-linux@dsn.lapis-semi.com>"); MODULE_AUTHOR("Tomoya MORINAGA. <tomoya.rohm@gmail.com>");
module_param(pch_i2c_speed, int, (S_IRUSR | S_IWUSR)); module_param(pch_i2c_speed, int, (S_IRUSR | S_IWUSR));
module_param(pch_clk, int, (S_IRUSR | S_IWUSR)); module_param(pch_clk, int, (S_IRUSR | S_IWUSR));
...@@ -227,6 +227,7 @@ static int mxs_i2c_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, ...@@ -227,6 +227,7 @@ static int mxs_i2c_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg,
return -EINVAL; return -EINVAL;
init_completion(&i2c->cmd_complete); init_completion(&i2c->cmd_complete);
i2c->cmd_err = 0;
flags = stop ? MXS_I2C_CTRL0_POST_SEND_STOP : 0; flags = stop ? MXS_I2C_CTRL0_POST_SEND_STOP : 0;
...@@ -252,6 +253,9 @@ static int mxs_i2c_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, ...@@ -252,6 +253,9 @@ static int mxs_i2c_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg,
if (i2c->cmd_err == -ENXIO) if (i2c->cmd_err == -ENXIO)
mxs_i2c_reset(i2c); mxs_i2c_reset(i2c);
else
writel(MXS_I2C_QUEUECTRL_QUEUE_RUN,
i2c->regs + MXS_I2C_QUEUECTRL_CLR);
dev_dbg(i2c->dev, "Done with err=%d\n", i2c->cmd_err); dev_dbg(i2c->dev, "Done with err=%d\n", i2c->cmd_err);
...@@ -299,8 +303,6 @@ static irqreturn_t mxs_i2c_isr(int this_irq, void *dev_id) ...@@ -299,8 +303,6 @@ static irqreturn_t mxs_i2c_isr(int this_irq, void *dev_id)
MXS_I2C_CTRL1_SLAVE_STOP_IRQ | MXS_I2C_CTRL1_SLAVE_IRQ)) MXS_I2C_CTRL1_SLAVE_STOP_IRQ | MXS_I2C_CTRL1_SLAVE_IRQ))
/* MXS_I2C_CTRL1_OVERSIZE_XFER_TERM_IRQ is only for slaves */ /* MXS_I2C_CTRL1_OVERSIZE_XFER_TERM_IRQ is only for slaves */
i2c->cmd_err = -EIO; i2c->cmd_err = -EIO;
else
i2c->cmd_err = 0;
is_last_cmd = (readl(i2c->regs + MXS_I2C_QUEUESTAT) & is_last_cmd = (readl(i2c->regs + MXS_I2C_QUEUESTAT) &
MXS_I2C_QUEUESTAT_WRITE_QUEUE_CNT_MASK) == 0; MXS_I2C_QUEUESTAT_WRITE_QUEUE_CNT_MASK) == 0;
...@@ -384,8 +386,6 @@ static int __devexit mxs_i2c_remove(struct platform_device *pdev) ...@@ -384,8 +386,6 @@ static int __devexit mxs_i2c_remove(struct platform_device *pdev)
if (ret) if (ret)
return -EBUSY; return -EBUSY;
writel(MXS_I2C_QUEUECTRL_QUEUE_RUN,
i2c->regs + MXS_I2C_QUEUECTRL_CLR);
writel(MXS_I2C_CTRL0_SFTRST, i2c->regs + MXS_I2C_CTRL0_SET); writel(MXS_I2C_CTRL0_SFTRST, i2c->regs + MXS_I2C_CTRL0_SET);
platform_set_drvdata(pdev, NULL); platform_set_drvdata(pdev, NULL);
......
...@@ -546,8 +546,7 @@ static int i2c_pnx_controller_suspend(struct platform_device *pdev, ...@@ -546,8 +546,7 @@ static int i2c_pnx_controller_suspend(struct platform_device *pdev,
{ {
struct i2c_pnx_algo_data *alg_data = platform_get_drvdata(pdev); struct i2c_pnx_algo_data *alg_data = platform_get_drvdata(pdev);
/* FIXME: shouldn't this be clk_disable? */ clk_disable(alg_data->clk);
clk_enable(alg_data->clk);
return 0; return 0;
} }
......
...@@ -516,6 +516,14 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev, ...@@ -516,6 +516,14 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
if (likely(i2c_dev->msg_err == I2C_ERR_NONE)) if (likely(i2c_dev->msg_err == I2C_ERR_NONE))
return 0; return 0;
/*
* NACK interrupt is generated before the I2C controller generates the
* STOP condition on the bus. So wait for 2 clock periods before resetting
* the controller so that STOP condition has been delivered properly.
*/
if (i2c_dev->msg_err == I2C_ERR_NO_ACK)
udelay(DIV_ROUND_UP(2 * 1000000, i2c_dev->bus_clk_rate));
tegra_i2c_init(i2c_dev); tegra_i2c_init(i2c_dev);
if (i2c_dev->msg_err == I2C_ERR_NO_ACK) { if (i2c_dev->msg_err == I2C_ERR_NO_ACK) {
if (msg->flags & I2C_M_IGNORE_NAK) if (msg->flags & I2C_M_IGNORE_NAK)
......
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