Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2baf3809 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
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
parents 7c7fba98 806dbb20
Loading
Loading
Loading
Loading
+21 −6
Original line number Diff line number Diff line
@@ -465,6 +465,7 @@ static int brcmstb_i2c_xfer(struct i2c_adapter *adapter,
	u8 *tmp_buf;
	int len = 0;
	int xfersz = brcmstb_i2c_get_xfersz(dev);
	u32 cond, cond_per_msg;

	if (dev->is_suspended)
		return -EBUSY;
@@ -481,10 +482,11 @@ static int brcmstb_i2c_xfer(struct i2c_adapter *adapter,
			pmsg->buf ? pmsg->buf[0] : '0', pmsg->len);

		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
			brcmstb_set_i2c_start_stop(dev,
						   COND_RESTART | COND_NOSTOP);
			cond = COND_RESTART | COND_NOSTOP;

		brcmstb_set_i2c_start_stop(dev, cond);

		/* Send slave address */
		if (!(pmsg->flags & I2C_M_NOSTART)) {
@@ -497,13 +499,24 @@ static int brcmstb_i2c_xfer(struct i2c_adapter *adapter,
			}
		}

		cond_per_msg = cond;

		/* Perform data transfer */
		while (len) {
			bytes_to_xfer = min(len, xfersz);

			if (len <= xfersz && i == (num - 1))
				brcmstb_set_i2c_start_stop(dev,
							   ~(COND_START_STOP));
			if (len <= xfersz) {
				if (i == (num - 1))
					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,
						       bytes_to_xfer, pmsg);
@@ -512,6 +525,8 @@ static int brcmstb_i2c_xfer(struct i2c_adapter *adapter,

			len -=  bytes_to_xfer;
			tmp_buf += bytes_to_xfer;

			cond_per_msg = COND_NOSTART | COND_NOSTOP;
		}
	}

+1 −0
Original line number Diff line number Diff line
@@ -88,6 +88,7 @@ struct dw_i2c_dev {
	void __iomem		*base;
	struct completion	cmd_complete;
	struct clk		*clk;
	struct reset_control	*rst;
	u32			(*get_clk_rate_khz) (struct dw_i2c_dev *dev);
	struct dw_pci_controller *controller;
	int			cmd_err;
+24 −4
Original line number Diff line number Diff line
@@ -38,6 +38,7 @@
#include <linux/pm_runtime.h>
#include <linux/property.h>
#include <linux/io.h>
#include <linux/reset.h>
#include <linux/slab.h>
#include <linux/acpi.h>
#include <linux/platform_data/i2c-designware.h>
@@ -199,6 +200,14 @@ static int dw_i2c_plat_probe(struct platform_device *pdev)
	dev->irq = irq;
	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) {
		dev->clk_freq = pdata->i2c_scl_freq;
	} else {
@@ -235,12 +244,13 @@ static int dw_i2c_plat_probe(struct platform_device *pdev)
	    && dev->clk_freq != 1000000 && dev->clk_freq != 3400000) {
		dev_err(&pdev->dev,
			"Only 100kHz, 400kHz, 1MHz and 3.4MHz supported");
		return -EINVAL;
		r = -EINVAL;
		goto exit_reset;
	}

	r = i2c_dw_eval_lock_support(dev);
	if (r)
		return r;
		goto exit_reset;

	dev->functionality = I2C_FUNC_10BIT_ADDR | DW_IC_DEFAULT_FUNCTIONALITY;

@@ -286,9 +296,17 @@ static int dw_i2c_plat_probe(struct platform_device *pdev)
	}

	r = i2c_dw_probe(dev);
	if (r && !dev->pm_runtime_disabled)
		pm_runtime_disable(&pdev->dev);
	if (r)
		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;
}

@@ -306,6 +324,8 @@ static int dw_i2c_plat_remove(struct platform_device *pdev)
	pm_runtime_put_sync(&pdev->dev);
	if (!dev->pm_runtime_disabled)
		pm_runtime_disable(&pdev->dev);
	if (!IS_ERR_OR_NULL(dev->rst))
		reset_control_assert(dev->rst);

	return 0;
}
+2 −1
Original line number Diff line number Diff line
@@ -457,7 +457,6 @@ static irqreturn_t exynos5_i2c_irq(int irqno, void *dev_id)

	int_status = readl(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 */
	if (i2c->variant->hw == HSI2C_EXYNOS7) {
@@ -482,11 +481,13 @@ static irqreturn_t exynos5_i2c_irq(int irqno, void *dev_id)
			goto stop;
		}

		trans_status = readl(i2c->regs + HSI2C_TRANS_STATUS);
		if ((trans_status & HSI2C_MASTER_ST_MASK) == HSI2C_MASTER_ST_LOSE) {
			i2c->state = -EAGAIN;
			goto stop;
		}
	} else if (int_status & HSI2C_INT_I2C) {
		trans_status = readl(i2c->regs + HSI2C_TRANS_STATUS);
		if (trans_status & HSI2C_NO_DEV_ACK) {
			dev_dbg(i2c->dev, "No ACK from device\n");
			i2c->state = -ENXIO;
+1 −1
Original line number Diff line number Diff line
@@ -175,7 +175,7 @@ static void meson_i2c_put_data(struct meson_i2c *i2c, char *buf, int len)
		wdata1 |= *buf++ << ((i - 4) * 8);

	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__,
		wdata0, wdata1, len);
Loading