mirror of
https://github.com/torvalds/linux.git
synced 2024-11-24 05:02:12 +00:00
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:
commit
bd0c7d755b
@ -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;
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
@ -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 {
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user