The posted upstream patch (v4, https://lkml.org/lkml/2016/11/9/930) already got an ack by Jarkko Nikula (https://lkml.org/lkml/2016/11/10/193) Signed-off-by: Duc Dang <dhdang at apm.com> --- ...are-Implement-support-for-SMBus-block-rea.patch | 135 +++++++++++++++++++++ SPECS/kernel-aarch64.spec | 3 + 2 files changed, 138 insertions(+) create mode 100644 SOURCES/1019-i2c-designware-Implement-support-for-SMBus-block-rea.patch diff --git a/SOURCES/1019-i2c-designware-Implement-support-for-SMBus-block-rea.patch b/SOURCES/1019-i2c-designware-Implement-support-for-SMBus-block-rea.patch new file mode 100644 index 0000000..eb732e3 --- /dev/null +++ b/SOURCES/1019-i2c-designware-Implement-support-for-SMBus-block-rea.patch @@ -0,0 +1,135 @@ +From 4211222134d5758e53f667c6ebdf1e0c55d9137b Mon Sep 17 00:00:00 2001 +From: Tin Huynh <tnhuynh at apm.com> +Date: Thu, 10 Nov 2016 17:33:00 -0600 +Subject: [PATCH] i2c: designware: Implement support for SMBus block read and + write + +Free and Open IPMI use SMBUS BLOCK Read/Write to support SSIF protocol. +However, I2C Designware Core Driver doesn't handle the case at the moment. +The below patch supports this feature. + +Signed-off-by: Tin Huynh <tnhuynh at apm.com> +Acked-by: Jarkko Nikula <jarkko.nikula at linux.intel.com> + +[Apply from posted v4 patch (already acked-by Jarkko Nikula, +https://lkml.org/lkml/2016/11/10/193) to CentOS 7.3 AltArch] +Signed-off-by: Duc Dang <dhdang at apm.com> +--- + drivers/i2c/busses/i2c-designware-core.c | 46 +++++++++++++++++++++++++++-- + drivers/i2c/busses/i2c-designware-pcidrv.c | 1 + + drivers/i2c/busses/i2c-designware-platdrv.c | 1 + + 3 files changed, 45 insertions(+), 3 deletions(-) + +diff --git a/drivers/i2c/busses/i2c-designware-core.c b/drivers/i2c/busses/i2c-designware-core.c +index 10fbd6d..927849b 100644 +--- a/drivers/i2c/busses/i2c-designware-core.c ++++ b/drivers/i2c/busses/i2c-designware-core.c +@@ -470,6 +470,8 @@ i2c_dw_xfer_msg(struct dw_i2c_dev *dev) + intr_mask = DW_IC_INTR_DEFAULT_MASK; + + for (; dev->msg_write_idx < dev->msgs_num; dev->msg_write_idx++) { ++ u32 flags = msgs[dev->msg_write_idx].flags; ++ + /* + * if target address has changed, we need to + * reprogram the target address in the i2c +@@ -515,8 +517,15 @@ i2c_dw_xfer_msg(struct dw_i2c_dev *dev) + * detected from the registers so we set it always + * when writing/reading the last byte. + */ ++ ++ /* ++ * i2c-core.c always sets the buffer length of ++ * I2C_FUNC_SMBUS_BLOCK_DATA to 1. The length will ++ * be adjusted when receiving the first byte. ++ * Thus we can't stop the transaction here. ++ */ + if (dev->msg_write_idx == dev->msgs_num - 1 && +- buf_len == 1) ++ buf_len == 1 && !(flags & I2C_M_RECV_LEN)) + cmd |= BIT(9); + + if (need_restart) { +@@ -541,7 +550,12 @@ i2c_dw_xfer_msg(struct dw_i2c_dev *dev) + dev->tx_buf = buf; + dev->tx_buf_len = buf_len; + +- if (buf_len > 0) { ++ /* ++ * Because we don't know the buffer length in the ++ * I2C_FUNC_SMBUS_BLOCK_DATA case, we can't stop ++ * the transaction here. ++ */ ++ if (buf_len > 0 || flags & I2C_M_RECV_LEN) { + /* more bytes to be written */ + dev->status |= STATUS_WRITE_IN_PROGRESS; + break; +@@ -562,6 +576,24 @@ i2c_dw_xfer_msg(struct dw_i2c_dev *dev) + dw_writel(dev, intr_mask, DW_IC_INTR_MASK); + } + ++static u8 ++i2c_dw_recv_len(struct dw_i2c_dev *dev, u8 len) ++{ ++ struct i2c_msg *msgs = dev->msgs; ++ u32 flags = msgs[dev->msg_read_idx].flags; ++ ++ /* ++ * Adjust the buffer length and mask the flag ++ * after receiving the first byte. ++ */ ++ len += (flags & I2C_CLIENT_PEC) ? 2 : 1; ++ dev->tx_buf_len = len - min_t(u8, len, dev->rx_outstanding); ++ msgs[dev->msg_read_idx].len = len; ++ msgs[dev->msg_read_idx].flags &= ~I2C_M_RECV_LEN; ++ ++ return len; ++} ++ + static void + i2c_dw_read(struct dw_i2c_dev *dev) + { +@@ -586,7 +618,15 @@ i2c_dw_read(struct dw_i2c_dev *dev) + rx_valid = dw_readl(dev, DW_IC_RXFLR); + + for (; len > 0 && rx_valid > 0; len--, rx_valid--) { +- *buf++ = dw_readl(dev, DW_IC_DATA_CMD); ++ u32 flags = msgs[dev->msg_read_idx].flags; ++ ++ *buf = dw_readl(dev, DW_IC_DATA_CMD); ++ /* Ensure length byte is a valid value */ ++ if (flags & I2C_M_RECV_LEN && ++ *buf <= I2C_SMBUS_BLOCK_MAX && *buf > 0) { ++ len = i2c_dw_recv_len(dev, *buf); ++ } ++ buf++; + dev->rx_outstanding--; + } + +diff --git a/drivers/i2c/busses/i2c-designware-pcidrv.c b/drivers/i2c/busses/i2c-designware-pcidrv.c +index 7368be0..13578d9 100644 +--- a/drivers/i2c/busses/i2c-designware-pcidrv.c ++++ b/drivers/i2c/busses/i2c-designware-pcidrv.c +@@ -78,6 +78,7 @@ struct dw_pci_controller { + I2C_FUNC_SMBUS_BYTE | \ + I2C_FUNC_SMBUS_BYTE_DATA | \ + I2C_FUNC_SMBUS_WORD_DATA | \ ++ I2C_FUNC_SMBUS_BLOCK_DATA | \ + I2C_FUNC_SMBUS_I2C_BLOCK) + + /* BayTrail HCNT/LCNT/SDA hold time */ +diff --git a/drivers/i2c/busses/i2c-designware-platdrv.c b/drivers/i2c/busses/i2c-designware-platdrv.c +index 438f1b4..f67aaed 100644 +--- a/drivers/i2c/busses/i2c-designware-platdrv.c ++++ b/drivers/i2c/busses/i2c-designware-platdrv.c +@@ -210,6 +210,7 @@ static int dw_i2c_plat_probe(struct platform_device *pdev) + I2C_FUNC_SMBUS_BYTE | + I2C_FUNC_SMBUS_BYTE_DATA | + I2C_FUNC_SMBUS_WORD_DATA | ++ I2C_FUNC_SMBUS_BLOCK_DATA | + I2C_FUNC_SMBUS_I2C_BLOCK; + if (clk_freq == 100000) + dev->master_cfg = DW_IC_CON_MASTER | DW_IC_CON_SLAVE_DISABLE | +-- +1.8.3.1 + diff --git a/SPECS/kernel-aarch64.spec b/SPECS/kernel-aarch64.spec index 4c20b21..de899ca 100644 --- a/SPECS/kernel-aarch64.spec +++ b/SPECS/kernel-aarch64.spec @@ -343,6 +343,7 @@ Patch1015: 1015-drivers-net-xgene-fix-Use-GPIO-to-get-link-status.patch Patch1016: 1016-drivers-net-xgene-fix-Disable-coalescing-on-v1-hardw.patch Patch1017: 1017-drivers-net-xgene-fix-Coalescing-values-for-v2-hardw.patch Patch1018: 1018-ACPI-PCI-fix-GIC-irq-model-default-PCI-IRQ-polarity.patch +Patch1019: 1019-i2c-designware-Implement-support-for-SMBus-block-rea.patch # QDF2400 Patches Patch4000: 4000-arm64-Define-Qualcomm-Technologies-ARMv8-CPU.patch @@ -696,6 +697,7 @@ git am %{PATCH1015} git am %{PATCH1016} git am %{PATCH1017} git am %{PATCH1018} +git am %{PATCH1019} # Apply QDF2400 patches git am %{PATCH4000} @@ -1475,6 +1477,7 @@ fi %changelog * Thu Nov 10 2016 Duc Dang <dhdang at apm.com> [4.5.0-17.el7] +- Integrated posted patch to support SMBus block read/write for Designware I2C - Integrate upstream fix for GIC default PCI IRQ polarity - Integrate upstream updates for X-Gene Enet driver - Avoid dma_buffer overrun for SlimPRO I2C driver -- 1.8.3.1