Commit bd0c7d75 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull i2c fixes from Wolfram Sang:
 "Regular set of fixes for drivers and the dev-interface"

* 'i2c/for-current' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux:
  i2c: ismt: Fix undefined behavior due to shift overflowing the constant
  i2c: dev: Force case user pointers in compat_i2cdev_ioctl()
  i2c: dev: check return value when calling dev_set_name()
  i2c: qcom-geni: Use dev_err_probe() for GPI DMA error
  i2c: imx: Implement errata ERR007805 or e7805 bus frequency limit
  i2c: pasemi: Wait for write xfers to finish
parents a2c29ccd e35c9369
Loading
Loading
Loading
Loading
+33 −0
Original line number Diff line number Diff line
@@ -179,6 +179,12 @@ struct imx_i2c_hwdata {
	unsigned int		ndivs;
	unsigned int		i2sr_clr_opcode;
	unsigned int		i2cr_ien_opcode;
	/*
	 * Errata ERR007805 or e7805:
	 * I2C: When the I2C clock speed is configured for 400 kHz,
	 * the SCL low period violates the I2C spec of 1.3 uS min.
	 */
	bool			has_err007805;
};

struct imx_i2c_dma {
@@ -240,6 +246,16 @@ static const struct imx_i2c_hwdata imx21_i2c_hwdata = {

};

static const struct imx_i2c_hwdata imx6_i2c_hwdata = {
	.devtype		= IMX21_I2C,
	.regshift		= IMX_I2C_REGSHIFT,
	.clk_div		= imx_i2c_clk_div,
	.ndivs			= ARRAY_SIZE(imx_i2c_clk_div),
	.i2sr_clr_opcode	= I2SR_CLR_OPCODE_W0C,
	.i2cr_ien_opcode	= I2CR_IEN_OPCODE_1,
	.has_err007805		= true,
};

static struct imx_i2c_hwdata vf610_i2c_hwdata = {
	.devtype		= VF610_I2C,
	.regshift		= VF610_I2C_REGSHIFT,
@@ -266,6 +282,16 @@ MODULE_DEVICE_TABLE(platform, imx_i2c_devtype);
static const struct of_device_id i2c_imx_dt_ids[] = {
	{ .compatible = "fsl,imx1-i2c", .data = &imx1_i2c_hwdata, },
	{ .compatible = "fsl,imx21-i2c", .data = &imx21_i2c_hwdata, },
	{ .compatible = "fsl,imx6q-i2c", .data = &imx6_i2c_hwdata, },
	{ .compatible = "fsl,imx6sl-i2c", .data = &imx6_i2c_hwdata, },
	{ .compatible = "fsl,imx6sll-i2c", .data = &imx6_i2c_hwdata, },
	{ .compatible = "fsl,imx6sx-i2c", .data = &imx6_i2c_hwdata, },
	{ .compatible = "fsl,imx6ul-i2c", .data = &imx6_i2c_hwdata, },
	{ .compatible = "fsl,imx7s-i2c", .data = &imx6_i2c_hwdata, },
	{ .compatible = "fsl,imx8mm-i2c", .data = &imx6_i2c_hwdata, },
	{ .compatible = "fsl,imx8mn-i2c", .data = &imx6_i2c_hwdata, },
	{ .compatible = "fsl,imx8mp-i2c", .data = &imx6_i2c_hwdata, },
	{ .compatible = "fsl,imx8mq-i2c", .data = &imx6_i2c_hwdata, },
	{ .compatible = "fsl,vf610-i2c", .data = &vf610_i2c_hwdata, },
	{ /* sentinel */ }
};
@@ -551,6 +577,13 @@ static void i2c_imx_set_clk(struct imx_i2c_struct *i2c_imx,
	unsigned int div;
	int i;

	if (i2c_imx->hwdata->has_err007805 && i2c_imx->bitrate > 384000) {
		dev_dbg(&i2c_imx->adapter.dev,
			"SoC errata ERR007805 or e7805 applies, bus frequency limited from %d Hz to 384000 Hz.\n",
			i2c_imx->bitrate);
		i2c_imx->bitrate = 384000;
	}

	/* Divider value calculation */
	if (i2c_imx->cur_clk == i2c_clk_rate)
		return;
+2 −2
Original line number Diff line number Diff line
@@ -145,8 +145,8 @@
#define ISMT_SPGT_SPD_MASK	0xc0000000	/* SMBus Speed mask */
#define ISMT_SPGT_SPD_80K	0x00		/* 80 kHz */
#define ISMT_SPGT_SPD_100K	(0x1 << 30)	/* 100 kHz */
#define ISMT_SPGT_SPD_400K	(0x2 << 30)	/* 400 kHz */
#define ISMT_SPGT_SPD_1M	(0x3 << 30)	/* 1 MHz */
#define ISMT_SPGT_SPD_400K	(0x2U << 30)	/* 400 kHz */
#define ISMT_SPGT_SPD_1M	(0x3U << 30)	/* 1 MHz */


/* MSI Control Register (MSICTL) bit definitions */
+6 −0
Original line number Diff line number Diff line
@@ -137,6 +137,12 @@ static int pasemi_i2c_xfer_msg(struct i2c_adapter *adapter,

		TXFIFO_WR(smbus, msg->buf[msg->len-1] |
			  (stop ? MTXFIFO_STOP : 0));

		if (stop) {
			err = pasemi_smb_waitready(smbus);
			if (err)
				goto reset_out;
		}
	}

	return 0;
+2 −4
Original line number Diff line number Diff line
@@ -843,10 +843,8 @@ static int geni_i2c_probe(struct platform_device *pdev)
		/* FIFO is disabled, so we can only use GPI DMA */
		gi2c->gpi_mode = true;
		ret = setup_gpi_dma(gi2c);
		if (ret) {
			dev_err(dev, "Failed to setup GPI DMA mode:%d ret\n", ret);
			return ret;
		}
		if (ret)
			return dev_err_probe(dev, ret, "Failed to setup GPI DMA mode\n");

		dev_dbg(dev, "Using GPI DMA mode for I2C\n");
	} else {
+11 −6
Original line number Diff line number Diff line
@@ -557,7 +557,7 @@ static long compat_i2cdev_ioctl(struct file *file, unsigned int cmd, unsigned lo
				.addr = umsg.addr,
				.flags = umsg.flags,
				.len = umsg.len,
				.buf = compat_ptr(umsg.buf)
				.buf = (__force __u8 *)compat_ptr(umsg.buf),
			};
		}

@@ -668,16 +668,21 @@ static int i2cdev_attach_adapter(struct device *dev, void *dummy)
	i2c_dev->dev.class = i2c_dev_class;
	i2c_dev->dev.parent = &adap->dev;
	i2c_dev->dev.release = i2cdev_dev_release;
	dev_set_name(&i2c_dev->dev, "i2c-%d", adap->nr);

	res = dev_set_name(&i2c_dev->dev, "i2c-%d", adap->nr);
	if (res)
		goto err_put_i2c_dev;

	res = cdev_device_add(&i2c_dev->cdev, &i2c_dev->dev);
	if (res) {
		put_i2c_dev(i2c_dev, false);
		return res;
	}
	if (res)
		goto err_put_i2c_dev;

	pr_debug("adapter [%s] registered as minor %d\n", adap->name, adap->nr);
	return 0;

err_put_i2c_dev:
	put_i2c_dev(i2c_dev, false);
	return res;
}

static int i2cdev_detach_adapter(struct device *dev, void *dummy)