forked from Minki/linux
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:
commit
f0cc7c0008
@ -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);
|
||||
|
@ -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::
|
||||
|
||||
|
@ -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.
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user