I2C driver bugfixes for mlxbf and imx, a few documentation fixes after

the rework this cycle, and one hardening for the i2c-mux core
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCgAdFiEEOZGx6rniZ1Gk92RdFA3kzBSgKbYFAmMva04ACgkQFA3kzBSg
 KbbyuRAAmdAdL6TR1XzhU8qUuqrpDdX+fk/6ljXveRbJD4OfxokCXQtoSPx6DSNE
 eMDyYhku2X52WpBsIZE2xR2IUiMAGFFKs+jfG7AEznDETlBo6iLlITneR0DT/Tnp
 dbp2+k0X36GZ/Ar6eVnOZs8XA2d2deFbXDPHYV0iGkZJZrsL6KWChXtfqoXe2oSC
 yzt53qT/wiUOcyIuEkp/79EpYcY0xksID6iXQm3YqXJWk04yrM/3kIxwjtkfsZiP
 AMBZtoND2v+rQFP+6OaPyY0Z1xyLPnFKDW1F7PEaYBuCwnOg/MrCHoT2SpxyzmVd
 XBwWEhLVwBBs7qWTlM9nc99MiKdhNcXx9he5BLBzxfxl6DSGFQuo9uu9B6mstjzn
 pbz5DWcfPh2FmSMpCQadEoWjHFHEXMD3b0mpFLUKB9Gqlbt6LkQYlB5wBIb0FTW9
 bg7wSAVLKe58+p3Ui9pG1ZORKKBxYU3ym6Oz6687P8xwRiZw1jJE/O3Ffp3bg636
 JYXc13fQBMjvUCxxp2tyJKzciSMLNgDiuAmBm003vaR6ewvD7cVMYNCO5RXvpeOU
 wdzEGlQ1ZWaERmcNj78+kXHxYbzqBkTZW1dPJ7wZne1Mrm6Zpmwk1xNU2RapQFkC
 Lv0WXkBg/ClahUEJm0AL4BAFbYydaTXmAJPt2quR+IWu4p7Yu+8=
 =LqnL
 -----END PGP SIGNATURE-----

Merge tag 'i2c-for-6.0-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux

Pull i2c fixes from Wolfram Sang:
 "I2C driver bugfixes for mlxbf and imx, a few documentation fixes after
  the rework this cycle, and one hardening for the i2c-mux core"

* tag 'i2c-for-6.0-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux:
  i2c: mux: harden i2c_mux_alloc() against integer overflows
  i2c: mlxbf: Fix frequency calculation
  i2c: mlxbf: prevent stack overflow in mlxbf_i2c_smbus_start_transaction()
  i2c: mlxbf: incorrect base address passed during io write
  Documentation: i2c: fix references to other documents
  MAINTAINERS: remove Nehal Shah from AMD MP2 I2C DRIVER
  i2c: imx: If pm_runtime_get_sync() returned 1 device access is possible
This commit is contained in:
Linus Torvalds 2022-09-25 08:44:46 -07:00
commit f0cc7c0008
7 changed files with 37 additions and 51 deletions

View File

@ -148,7 +148,7 @@ You can do plain I2C transactions by using read(2) and write(2) calls.
You do not need to pass the address byte; instead, set it through
ioctl I2C_SLAVE before you try to access the device.
You can do SMBus level transactions (see documentation file smbus-protocol
You can do SMBus level transactions (see documentation file smbus-protocol.rst
for details) through the following functions::
__s32 i2c_smbus_write_quick(int file, __u8 value);

View File

@ -32,9 +32,9 @@ User manual
===========
I2C slave backends behave like standard I2C clients. So, you can instantiate
them as described in the document 'instantiating-devices'. The only difference
is that i2c slave backends have their own address space. So, you have to add
0x1000 to the address you would originally request. An example for
them as described in the document instantiating-devices.rst. The only
difference is that i2c slave backends have their own address space. So, you
have to add 0x1000 to the address you would originally request. An example for
instantiating the slave-eeprom driver from userspace at the 7 bit address 0x64
on bus 1::

View File

@ -364,7 +364,7 @@ stop condition is issued between transaction. The i2c_msg structure
contains for each message the client address, the number of bytes of the
message and the message data itself.
You can read the file ``i2c-protocol`` for more information about the
You can read the file i2c-protocol.rst for more information about the
actual I2C protocol.
@ -414,7 +414,7 @@ transactions return 0 on success; the 'read' transactions return the read
value, except for block transactions, which return the number of values
read. The block buffers need not be longer than 32 bytes.
You can read the file ``smbus-protocol`` for more information about the
You can read the file smbus-protocol.rst for more information about the
actual SMBus protocol.

View File

@ -1011,7 +1011,6 @@ F: drivers/spi/spi-amd.c
AMD MP2 I2C DRIVER
M: Elie Morisse <syniurge@gmail.com>
M: Nehal Shah <nehal-bakulchandra.shah@amd.com>
M: Shyam Sundar S K <shyam-sundar.s-k@amd.com>
L: linux-i2c@vger.kernel.org
S: Maintained

View File

@ -1583,7 +1583,7 @@ static int i2c_imx_remove(struct platform_device *pdev)
if (i2c_imx->dma)
i2c_imx_dma_free(i2c_imx);
if (ret == 0) {
if (ret >= 0) {
/* setup chip registers to defaults */
imx_i2c_write_reg(0, i2c_imx, IMX_I2C_IADR);
imx_i2c_write_reg(0, i2c_imx, IMX_I2C_IFDR);

View File

@ -6,6 +6,7 @@
*/
#include <linux/acpi.h>
#include <linux/bitfield.h>
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/interrupt.h>
@ -63,13 +64,14 @@
*/
#define MLXBF_I2C_TYU_PLL_OUT_FREQ (400 * 1000 * 1000)
/* Reference clock for Bluefield - 156 MHz. */
#define MLXBF_I2C_PLL_IN_FREQ (156 * 1000 * 1000)
#define MLXBF_I2C_PLL_IN_FREQ 156250000ULL
/* Constant used to determine the PLL frequency. */
#define MLNXBF_I2C_COREPLL_CONST 16384
#define MLNXBF_I2C_COREPLL_CONST 16384ULL
#define MLXBF_I2C_FREQUENCY_1GHZ 1000000000ULL
/* PLL registers. */
#define MLXBF_I2C_CORE_PLL_REG0 0x0
#define MLXBF_I2C_CORE_PLL_REG1 0x4
#define MLXBF_I2C_CORE_PLL_REG2 0x8
@ -181,22 +183,15 @@
#define MLXBF_I2C_COREPLL_FREQ MLXBF_I2C_TYU_PLL_OUT_FREQ
/* Core PLL TYU configuration. */
#define MLXBF_I2C_COREPLL_CORE_F_TYU_MASK GENMASK(12, 0)
#define MLXBF_I2C_COREPLL_CORE_OD_TYU_MASK GENMASK(3, 0)
#define MLXBF_I2C_COREPLL_CORE_R_TYU_MASK GENMASK(5, 0)
#define MLXBF_I2C_COREPLL_CORE_F_TYU_SHIFT 3
#define MLXBF_I2C_COREPLL_CORE_OD_TYU_SHIFT 16
#define MLXBF_I2C_COREPLL_CORE_R_TYU_SHIFT 20
#define MLXBF_I2C_COREPLL_CORE_F_TYU_MASK GENMASK(15, 3)
#define MLXBF_I2C_COREPLL_CORE_OD_TYU_MASK GENMASK(19, 16)
#define MLXBF_I2C_COREPLL_CORE_R_TYU_MASK GENMASK(25, 20)
/* Core PLL YU configuration. */
#define MLXBF_I2C_COREPLL_CORE_F_YU_MASK GENMASK(25, 0)
#define MLXBF_I2C_COREPLL_CORE_OD_YU_MASK GENMASK(3, 0)
#define MLXBF_I2C_COREPLL_CORE_R_YU_MASK GENMASK(5, 0)
#define MLXBF_I2C_COREPLL_CORE_R_YU_MASK GENMASK(31, 26)
#define MLXBF_I2C_COREPLL_CORE_F_YU_SHIFT 0
#define MLXBF_I2C_COREPLL_CORE_OD_YU_SHIFT 1
#define MLXBF_I2C_COREPLL_CORE_R_YU_SHIFT 26
/* Core PLL frequency. */
static u64 mlxbf_i2c_corepll_frequency;
@ -479,8 +474,6 @@ static struct mutex mlxbf_i2c_bus_lock;
#define MLXBF_I2C_MASK_8 GENMASK(7, 0)
#define MLXBF_I2C_MASK_16 GENMASK(15, 0)
#define MLXBF_I2C_FREQUENCY_1GHZ 1000000000
/*
* Function to poll a set of bits at a specific address; it checks whether
* the bits are equal to zero when eq_zero is set to 'true', and not equal
@ -669,7 +662,7 @@ static int mlxbf_i2c_smbus_enable(struct mlxbf_i2c_priv *priv, u8 slave,
/* Clear status bits. */
writel(0x0, priv->smbus->io + MLXBF_I2C_SMBUS_MASTER_STATUS);
/* Set the cause data. */
writel(~0x0, priv->smbus->io + MLXBF_I2C_CAUSE_OR_CLEAR);
writel(~0x0, priv->mst_cause->io + MLXBF_I2C_CAUSE_OR_CLEAR);
/* Zero PEC byte. */
writel(0x0, priv->smbus->io + MLXBF_I2C_SMBUS_MASTER_PEC);
/* Zero byte count. */
@ -738,6 +731,9 @@ mlxbf_i2c_smbus_start_transaction(struct mlxbf_i2c_priv *priv,
if (flags & MLXBF_I2C_F_WRITE) {
write_en = 1;
write_len += operation->length;
if (data_idx + operation->length >
MLXBF_I2C_MASTER_DATA_DESC_SIZE)
return -ENOBUFS;
memcpy(data_desc + data_idx,
operation->buffer, operation->length);
data_idx += operation->length;
@ -1407,24 +1403,19 @@ static int mlxbf_i2c_init_master(struct platform_device *pdev,
return 0;
}
static u64 mlxbf_calculate_freq_from_tyu(struct mlxbf_i2c_resource *corepll_res)
static u64 mlxbf_i2c_calculate_freq_from_tyu(struct mlxbf_i2c_resource *corepll_res)
{
u64 core_frequency, pad_frequency;
u64 core_frequency;
u8 core_od, core_r;
u32 corepll_val;
u16 core_f;
pad_frequency = MLXBF_I2C_PLL_IN_FREQ;
corepll_val = readl(corepll_res->io + MLXBF_I2C_CORE_PLL_REG1);
/* Get Core PLL configuration bits. */
core_f = rol32(corepll_val, MLXBF_I2C_COREPLL_CORE_F_TYU_SHIFT) &
MLXBF_I2C_COREPLL_CORE_F_TYU_MASK;
core_od = rol32(corepll_val, MLXBF_I2C_COREPLL_CORE_OD_TYU_SHIFT) &
MLXBF_I2C_COREPLL_CORE_OD_TYU_MASK;
core_r = rol32(corepll_val, MLXBF_I2C_COREPLL_CORE_R_TYU_SHIFT) &
MLXBF_I2C_COREPLL_CORE_R_TYU_MASK;
core_f = FIELD_GET(MLXBF_I2C_COREPLL_CORE_F_TYU_MASK, corepll_val);
core_od = FIELD_GET(MLXBF_I2C_COREPLL_CORE_OD_TYU_MASK, corepll_val);
core_r = FIELD_GET(MLXBF_I2C_COREPLL_CORE_R_TYU_MASK, corepll_val);
/*
* Compute PLL output frequency as follow:
@ -1436,31 +1427,26 @@ static u64 mlxbf_calculate_freq_from_tyu(struct mlxbf_i2c_resource *corepll_res)
* Where PLL_OUT_FREQ and PLL_IN_FREQ refer to CoreFrequency
* and PadFrequency, respectively.
*/
core_frequency = pad_frequency * (++core_f);
core_frequency = MLXBF_I2C_PLL_IN_FREQ * (++core_f);
core_frequency /= (++core_r) * (++core_od);
return core_frequency;
}
static u64 mlxbf_calculate_freq_from_yu(struct mlxbf_i2c_resource *corepll_res)
static u64 mlxbf_i2c_calculate_freq_from_yu(struct mlxbf_i2c_resource *corepll_res)
{
u32 corepll_reg1_val, corepll_reg2_val;
u64 corepll_frequency, pad_frequency;
u64 corepll_frequency;
u8 core_od, core_r;
u32 core_f;
pad_frequency = MLXBF_I2C_PLL_IN_FREQ;
corepll_reg1_val = readl(corepll_res->io + MLXBF_I2C_CORE_PLL_REG1);
corepll_reg2_val = readl(corepll_res->io + MLXBF_I2C_CORE_PLL_REG2);
/* Get Core PLL configuration bits */
core_f = rol32(corepll_reg1_val, MLXBF_I2C_COREPLL_CORE_F_YU_SHIFT) &
MLXBF_I2C_COREPLL_CORE_F_YU_MASK;
core_r = rol32(corepll_reg1_val, MLXBF_I2C_COREPLL_CORE_R_YU_SHIFT) &
MLXBF_I2C_COREPLL_CORE_R_YU_MASK;
core_od = rol32(corepll_reg2_val, MLXBF_I2C_COREPLL_CORE_OD_YU_SHIFT) &
MLXBF_I2C_COREPLL_CORE_OD_YU_MASK;
core_f = FIELD_GET(MLXBF_I2C_COREPLL_CORE_F_YU_MASK, corepll_reg1_val);
core_r = FIELD_GET(MLXBF_I2C_COREPLL_CORE_R_YU_MASK, corepll_reg1_val);
core_od = FIELD_GET(MLXBF_I2C_COREPLL_CORE_OD_YU_MASK, corepll_reg2_val);
/*
* Compute PLL output frequency as follow:
@ -1472,7 +1458,7 @@ static u64 mlxbf_calculate_freq_from_yu(struct mlxbf_i2c_resource *corepll_res)
* Where PLL_OUT_FREQ and PLL_IN_FREQ refer to CoreFrequency
* and PadFrequency, respectively.
*/
corepll_frequency = (pad_frequency * core_f) / MLNXBF_I2C_COREPLL_CONST;
corepll_frequency = (MLXBF_I2C_PLL_IN_FREQ * core_f) / MLNXBF_I2C_COREPLL_CONST;
corepll_frequency /= (++core_r) * (++core_od);
return corepll_frequency;
@ -2180,14 +2166,14 @@ static struct mlxbf_i2c_chip_info mlxbf_i2c_chip[] = {
[1] = &mlxbf_i2c_corepll_res[MLXBF_I2C_CHIP_TYPE_1],
[2] = &mlxbf_i2c_gpio_res[MLXBF_I2C_CHIP_TYPE_1]
},
.calculate_freq = mlxbf_calculate_freq_from_tyu
.calculate_freq = mlxbf_i2c_calculate_freq_from_tyu
},
[MLXBF_I2C_CHIP_TYPE_2] = {
.type = MLXBF_I2C_CHIP_TYPE_2,
.shared_res = {
[0] = &mlxbf_i2c_corepll_res[MLXBF_I2C_CHIP_TYPE_2]
},
.calculate_freq = mlxbf_calculate_freq_from_yu
.calculate_freq = mlxbf_i2c_calculate_freq_from_yu
}
};

View File

@ -243,9 +243,10 @@ struct i2c_mux_core *i2c_mux_alloc(struct i2c_adapter *parent,
int (*deselect)(struct i2c_mux_core *, u32))
{
struct i2c_mux_core *muxc;
size_t mux_size;
muxc = devm_kzalloc(dev, struct_size(muxc, adapter, max_adapters)
+ sizeof_priv, GFP_KERNEL);
mux_size = struct_size(muxc, adapter, max_adapters);
muxc = devm_kzalloc(dev, size_add(mux_size, sizeof_priv), GFP_KERNEL);
if (!muxc)
return NULL;
if (sizeof_priv)