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
This commit is contained in:
commit
4e78f00261
4 changed files with 15 additions and 8 deletions
|
@ -324,7 +324,7 @@ static s32 pch_i2c_wait_for_xfer_complete(struct i2c_algo_pch_data *adap)
|
|||
{
|
||||
long ret;
|
||||
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) {
|
||||
pch_err(adap, "timeout: %x\n", adap->pch_event_flag);
|
||||
|
@ -1063,6 +1063,6 @@ module_exit(pch_pci_exit);
|
|||
|
||||
MODULE_DESCRIPTION("Intel EG20T PCH/LAPIS Semico ML7213/ML7223/ML7831 IOH I2C");
|
||||
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_clk, int, (S_IRUSR | S_IWUSR));
|
||||
|
|
|
@ -227,6 +227,7 @@ static int mxs_i2c_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg,
|
|||
return -EINVAL;
|
||||
|
||||
init_completion(&i2c->cmd_complete);
|
||||
i2c->cmd_err = 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,
|
|||
|
||||
if (i2c->cmd_err == -ENXIO)
|
||||
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);
|
||||
|
||||
|
@ -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_OVERSIZE_XFER_TERM_IRQ is only for slaves */
|
||||
i2c->cmd_err = -EIO;
|
||||
else
|
||||
i2c->cmd_err = 0;
|
||||
|
||||
is_last_cmd = (readl(i2c->regs + MXS_I2C_QUEUESTAT) &
|
||||
MXS_I2C_QUEUESTAT_WRITE_QUEUE_CNT_MASK) == 0;
|
||||
|
@ -384,8 +386,6 @@ static int __devexit mxs_i2c_remove(struct platform_device *pdev)
|
|||
if (ret)
|
||||
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);
|
||||
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
|
|
|
@ -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);
|
||||
|
||||
/* FIXME: shouldn't this be clk_disable? */
|
||||
clk_enable(alg_data->clk);
|
||||
clk_disable(alg_data->clk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -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))
|
||||
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);
|
||||
if (i2c_dev->msg_err == I2C_ERR_NO_ACK) {
|
||||
if (msg->flags & I2C_M_IGNORE_NAK)
|
||||
|
|
Loading…
Reference in a new issue