提交 2baf3809 编写于 作者: L Linus Torvalds

Merge branch 'i2c/for-current' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux

Pull i2c fixes from Wolfram Sang:
 "Here are some driver bugfixes from I2C.

  Unusual this time are the two reverts. One because I accidently picked
  a patch from the list which I should have pulled from my co-maintainer
  instead ("missing of_node_put"). And one which I wrongly assumed to be
  an easy fix but it turned out already that it needs more iterations
  ("copy device properties")"

* 'i2c/for-current' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux:
  Revert "i2c: copy device properties when using i2c_register_board_info()"
  Revert "i2c: add missing of_node_put in i2c_mux_del_adapters"
  i2c: exynos5: Avoid transaction timeouts due TRANSFER_DONE_AUTO not set
  i2c: designware: add reset interface
  i2c: meson: fix wrong variable usage in meson_i2c_put_data
  i2c: copy device properties when using i2c_register_board_info()
  i2c: m65xx: drop superfluous quirk structure
  i2c: brcmstb: Fix START and STOP conditions
  i2c: add missing of_node_put in i2c_mux_del_adapters
  i2c: riic: fix restart condition
  i2c: add missing of_node_put in i2c_mux_del_adapters
...@@ -465,6 +465,7 @@ static int brcmstb_i2c_xfer(struct i2c_adapter *adapter, ...@@ -465,6 +465,7 @@ static int brcmstb_i2c_xfer(struct i2c_adapter *adapter,
u8 *tmp_buf; u8 *tmp_buf;
int len = 0; int len = 0;
int xfersz = brcmstb_i2c_get_xfersz(dev); int xfersz = brcmstb_i2c_get_xfersz(dev);
u32 cond, cond_per_msg;
if (dev->is_suspended) if (dev->is_suspended)
return -EBUSY; return -EBUSY;
...@@ -481,10 +482,11 @@ static int brcmstb_i2c_xfer(struct i2c_adapter *adapter, ...@@ -481,10 +482,11 @@ static int brcmstb_i2c_xfer(struct i2c_adapter *adapter,
pmsg->buf ? pmsg->buf[0] : '0', pmsg->len); pmsg->buf ? pmsg->buf[0] : '0', pmsg->len);
if (i < (num - 1) && (msgs[i + 1].flags & I2C_M_NOSTART)) if (i < (num - 1) && (msgs[i + 1].flags & I2C_M_NOSTART))
brcmstb_set_i2c_start_stop(dev, ~(COND_START_STOP)); cond = ~COND_START_STOP;
else else
brcmstb_set_i2c_start_stop(dev, cond = COND_RESTART | COND_NOSTOP;
COND_RESTART | COND_NOSTOP);
brcmstb_set_i2c_start_stop(dev, cond);
/* Send slave address */ /* Send slave address */
if (!(pmsg->flags & I2C_M_NOSTART)) { if (!(pmsg->flags & I2C_M_NOSTART)) {
...@@ -497,13 +499,24 @@ static int brcmstb_i2c_xfer(struct i2c_adapter *adapter, ...@@ -497,13 +499,24 @@ static int brcmstb_i2c_xfer(struct i2c_adapter *adapter,
} }
} }
cond_per_msg = cond;
/* Perform data transfer */ /* Perform data transfer */
while (len) { while (len) {
bytes_to_xfer = min(len, xfersz); bytes_to_xfer = min(len, xfersz);
if (len <= xfersz && i == (num - 1)) if (len <= xfersz) {
brcmstb_set_i2c_start_stop(dev, if (i == (num - 1))
~(COND_START_STOP)); cond_per_msg = cond_per_msg &
~(COND_RESTART | COND_NOSTOP);
else
cond_per_msg = cond;
} else {
cond_per_msg = (cond_per_msg & ~COND_RESTART) |
COND_NOSTOP;
}
brcmstb_set_i2c_start_stop(dev, cond_per_msg);
rc = brcmstb_i2c_xfer_bsc_data(dev, tmp_buf, rc = brcmstb_i2c_xfer_bsc_data(dev, tmp_buf,
bytes_to_xfer, pmsg); bytes_to_xfer, pmsg);
...@@ -512,6 +525,8 @@ static int brcmstb_i2c_xfer(struct i2c_adapter *adapter, ...@@ -512,6 +525,8 @@ static int brcmstb_i2c_xfer(struct i2c_adapter *adapter,
len -= bytes_to_xfer; len -= bytes_to_xfer;
tmp_buf += bytes_to_xfer; tmp_buf += bytes_to_xfer;
cond_per_msg = COND_NOSTART | COND_NOSTOP;
} }
} }
......
...@@ -88,6 +88,7 @@ struct dw_i2c_dev { ...@@ -88,6 +88,7 @@ struct dw_i2c_dev {
void __iomem *base; void __iomem *base;
struct completion cmd_complete; struct completion cmd_complete;
struct clk *clk; struct clk *clk;
struct reset_control *rst;
u32 (*get_clk_rate_khz) (struct dw_i2c_dev *dev); u32 (*get_clk_rate_khz) (struct dw_i2c_dev *dev);
struct dw_pci_controller *controller; struct dw_pci_controller *controller;
int cmd_err; int cmd_err;
......
...@@ -38,6 +38,7 @@ ...@@ -38,6 +38,7 @@
#include <linux/pm_runtime.h> #include <linux/pm_runtime.h>
#include <linux/property.h> #include <linux/property.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/reset.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/acpi.h> #include <linux/acpi.h>
#include <linux/platform_data/i2c-designware.h> #include <linux/platform_data/i2c-designware.h>
...@@ -199,6 +200,14 @@ static int dw_i2c_plat_probe(struct platform_device *pdev) ...@@ -199,6 +200,14 @@ static int dw_i2c_plat_probe(struct platform_device *pdev)
dev->irq = irq; dev->irq = irq;
platform_set_drvdata(pdev, dev); platform_set_drvdata(pdev, dev);
dev->rst = devm_reset_control_get_optional_exclusive(&pdev->dev, NULL);
if (IS_ERR(dev->rst)) {
if (PTR_ERR(dev->rst) == -EPROBE_DEFER)
return -EPROBE_DEFER;
} else {
reset_control_deassert(dev->rst);
}
if (pdata) { if (pdata) {
dev->clk_freq = pdata->i2c_scl_freq; dev->clk_freq = pdata->i2c_scl_freq;
} else { } else {
...@@ -235,12 +244,13 @@ static int dw_i2c_plat_probe(struct platform_device *pdev) ...@@ -235,12 +244,13 @@ static int dw_i2c_plat_probe(struct platform_device *pdev)
&& dev->clk_freq != 1000000 && dev->clk_freq != 3400000) { && dev->clk_freq != 1000000 && dev->clk_freq != 3400000) {
dev_err(&pdev->dev, dev_err(&pdev->dev,
"Only 100kHz, 400kHz, 1MHz and 3.4MHz supported"); "Only 100kHz, 400kHz, 1MHz and 3.4MHz supported");
return -EINVAL; r = -EINVAL;
goto exit_reset;
} }
r = i2c_dw_eval_lock_support(dev); r = i2c_dw_eval_lock_support(dev);
if (r) if (r)
return r; goto exit_reset;
dev->functionality = I2C_FUNC_10BIT_ADDR | DW_IC_DEFAULT_FUNCTIONALITY; dev->functionality = I2C_FUNC_10BIT_ADDR | DW_IC_DEFAULT_FUNCTIONALITY;
...@@ -286,9 +296,17 @@ static int dw_i2c_plat_probe(struct platform_device *pdev) ...@@ -286,9 +296,17 @@ static int dw_i2c_plat_probe(struct platform_device *pdev)
} }
r = i2c_dw_probe(dev); r = i2c_dw_probe(dev);
if (r && !dev->pm_runtime_disabled) if (r)
pm_runtime_disable(&pdev->dev); goto exit_probe;
return r;
exit_probe:
if (!dev->pm_runtime_disabled)
pm_runtime_disable(&pdev->dev);
exit_reset:
if (!IS_ERR_OR_NULL(dev->rst))
reset_control_assert(dev->rst);
return r; return r;
} }
...@@ -306,6 +324,8 @@ static int dw_i2c_plat_remove(struct platform_device *pdev) ...@@ -306,6 +324,8 @@ static int dw_i2c_plat_remove(struct platform_device *pdev)
pm_runtime_put_sync(&pdev->dev); pm_runtime_put_sync(&pdev->dev);
if (!dev->pm_runtime_disabled) if (!dev->pm_runtime_disabled)
pm_runtime_disable(&pdev->dev); pm_runtime_disable(&pdev->dev);
if (!IS_ERR_OR_NULL(dev->rst))
reset_control_assert(dev->rst);
return 0; return 0;
} }
......
...@@ -457,7 +457,6 @@ static irqreturn_t exynos5_i2c_irq(int irqno, void *dev_id) ...@@ -457,7 +457,6 @@ static irqreturn_t exynos5_i2c_irq(int irqno, void *dev_id)
int_status = readl(i2c->regs + HSI2C_INT_STATUS); int_status = readl(i2c->regs + HSI2C_INT_STATUS);
writel(int_status, i2c->regs + HSI2C_INT_STATUS); writel(int_status, i2c->regs + HSI2C_INT_STATUS);
trans_status = readl(i2c->regs + HSI2C_TRANS_STATUS);
/* handle interrupt related to the transfer status */ /* handle interrupt related to the transfer status */
if (i2c->variant->hw == HSI2C_EXYNOS7) { if (i2c->variant->hw == HSI2C_EXYNOS7) {
...@@ -482,11 +481,13 @@ static irqreturn_t exynos5_i2c_irq(int irqno, void *dev_id) ...@@ -482,11 +481,13 @@ static irqreturn_t exynos5_i2c_irq(int irqno, void *dev_id)
goto stop; goto stop;
} }
trans_status = readl(i2c->regs + HSI2C_TRANS_STATUS);
if ((trans_status & HSI2C_MASTER_ST_MASK) == HSI2C_MASTER_ST_LOSE) { if ((trans_status & HSI2C_MASTER_ST_MASK) == HSI2C_MASTER_ST_LOSE) {
i2c->state = -EAGAIN; i2c->state = -EAGAIN;
goto stop; goto stop;
} }
} else if (int_status & HSI2C_INT_I2C) { } else if (int_status & HSI2C_INT_I2C) {
trans_status = readl(i2c->regs + HSI2C_TRANS_STATUS);
if (trans_status & HSI2C_NO_DEV_ACK) { if (trans_status & HSI2C_NO_DEV_ACK) {
dev_dbg(i2c->dev, "No ACK from device\n"); dev_dbg(i2c->dev, "No ACK from device\n");
i2c->state = -ENXIO; i2c->state = -ENXIO;
......
...@@ -175,7 +175,7 @@ static void meson_i2c_put_data(struct meson_i2c *i2c, char *buf, int len) ...@@ -175,7 +175,7 @@ static void meson_i2c_put_data(struct meson_i2c *i2c, char *buf, int len)
wdata1 |= *buf++ << ((i - 4) * 8); wdata1 |= *buf++ << ((i - 4) * 8);
writel(wdata0, i2c->regs + REG_TOK_WDATA0); writel(wdata0, i2c->regs + REG_TOK_WDATA0);
writel(wdata0, i2c->regs + REG_TOK_WDATA1); writel(wdata1, i2c->regs + REG_TOK_WDATA1);
dev_dbg(i2c->dev, "%s: data %08x %08x len %d\n", __func__, dev_dbg(i2c->dev, "%s: data %08x %08x len %d\n", __func__,
wdata0, wdata1, len); wdata0, wdata1, len);
......
...@@ -172,14 +172,6 @@ static const struct i2c_adapter_quirks mt6577_i2c_quirks = { ...@@ -172,14 +172,6 @@ static const struct i2c_adapter_quirks mt6577_i2c_quirks = {
.max_comb_2nd_msg_len = 31, .max_comb_2nd_msg_len = 31,
}; };
static const struct i2c_adapter_quirks mt8173_i2c_quirks = {
.max_num_msgs = 65535,
.max_write_len = 65535,
.max_read_len = 65535,
.max_comb_1st_msg_len = 65535,
.max_comb_2nd_msg_len = 65535,
};
static const struct mtk_i2c_compatible mt6577_compat = { static const struct mtk_i2c_compatible mt6577_compat = {
.quirks = &mt6577_i2c_quirks, .quirks = &mt6577_i2c_quirks,
.pmic_i2c = 0, .pmic_i2c = 0,
...@@ -199,7 +191,6 @@ static const struct mtk_i2c_compatible mt6589_compat = { ...@@ -199,7 +191,6 @@ static const struct mtk_i2c_compatible mt6589_compat = {
}; };
static const struct mtk_i2c_compatible mt8173_compat = { static const struct mtk_i2c_compatible mt8173_compat = {
.quirks = &mt8173_i2c_quirks,
.pmic_i2c = 0, .pmic_i2c = 0,
.dcm = 1, .dcm = 1,
.auto_restart = 1, .auto_restart = 1,
......
...@@ -218,8 +218,12 @@ static irqreturn_t riic_tend_isr(int irq, void *data) ...@@ -218,8 +218,12 @@ static irqreturn_t riic_tend_isr(int irq, void *data)
} }
if (riic->is_last || riic->err) { if (riic->is_last || riic->err) {
riic_clear_set_bit(riic, 0, ICIER_SPIE, RIIC_ICIER); riic_clear_set_bit(riic, ICIER_TEIE, ICIER_SPIE, RIIC_ICIER);
writeb(ICCR2_SP, riic->base + RIIC_ICCR2); writeb(ICCR2_SP, riic->base + RIIC_ICCR2);
} else {
/* Transfer is complete, but do not send STOP */
riic_clear_set_bit(riic, ICIER_TEIE, 0, RIIC_ICIER);
complete(&riic->msg_done);
} }
return IRQ_HANDLED; return IRQ_HANDLED;
......
...@@ -429,6 +429,7 @@ void i2c_mux_del_adapters(struct i2c_mux_core *muxc) ...@@ -429,6 +429,7 @@ void i2c_mux_del_adapters(struct i2c_mux_core *muxc)
while (muxc->num_adapters) { while (muxc->num_adapters) {
struct i2c_adapter *adap = muxc->adapter[--muxc->num_adapters]; struct i2c_adapter *adap = muxc->adapter[--muxc->num_adapters];
struct i2c_mux_priv *priv = adap->algo_data; struct i2c_mux_priv *priv = adap->algo_data;
struct device_node *np = adap->dev.of_node;
muxc->adapter[muxc->num_adapters] = NULL; muxc->adapter[muxc->num_adapters] = NULL;
...@@ -438,6 +439,7 @@ void i2c_mux_del_adapters(struct i2c_mux_core *muxc) ...@@ -438,6 +439,7 @@ void i2c_mux_del_adapters(struct i2c_mux_core *muxc)
sysfs_remove_link(&priv->adap.dev.kobj, "mux_device"); sysfs_remove_link(&priv->adap.dev.kobj, "mux_device");
i2c_del_adapter(adap); i2c_del_adapter(adap);
of_node_put(np);
kfree(priv); kfree(priv);
} }
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册