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

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
This commit is contained in:
Linus Torvalds 2022-04-17 09:31:27 -07:00
commit bd0c7d755b
5 changed files with 54 additions and 12 deletions

View File

@ -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;

View File

@ -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 */

View File

@ -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;

View File

@ -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 {

View File

@ -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)