[RFC v3 dev-5.2 4/5] i2c: aspeed: add buffer mode transfer support
Jae Hyun Yoo
jae.hyun.yoo at linux.intel.com
Fri Aug 9 05:08:42 AEST 2019
Hi Eddie,
On 8/8/2019 11:14 AM, Eddie James wrote:
>
> On 7/18/19 2:35 PM, Jae Hyun Yoo wrote:
>> Byte mode currently this driver uses makes lots of interrupt call
>> which isn't good for performance and it makes the driver very
>> timing sensitive. To improve performance of the driver, this commit
>> adds buffer mode transfer support which uses I2C SRAM buffer
>> instead of using a single byte buffer.
>>
>> Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
>> Tested-by: Tao Ren <taoren at fb.com>
>> ---
>> v2 -> v3:
>> - Fixed resource getting logic using indices instead of reg-names to
>> make
>> this driver compatible with old device trees.
>> - Refined slave RX flow to get rid of duplicate read on the first
>> byte of
>> received data.
>>
>> v1 -> v2:
>> - Moved I2C SRAM enabling code from irq-aspeed-i2c-ic module to this
>> module.
>>
>> drivers/i2c/busses/i2c-aspeed.c | 294 ++++++++++++++++++++++++++++----
>> 1 file changed, 260 insertions(+), 34 deletions(-)
>>
>> diff --git a/drivers/i2c/busses/i2c-aspeed.c
>> b/drivers/i2c/busses/i2c-aspeed.c
>> index 40f6cf98d32e..b314101aaa9e 100644
>> --- a/drivers/i2c/busses/i2c-aspeed.c
>> +++ b/drivers/i2c/busses/i2c-aspeed.c
>> @@ -7,6 +7,7 @@
>> * Copyright 2017 Google, Inc.
>> */
>> +#include <linux/bitfield.h>
>> #include <linux/clk.h>
>> #include <linux/completion.h>
>> #include <linux/err.h>
>> @@ -19,15 +20,24 @@
>> #include <linux/irqchip/chained_irq.h>
>> #include <linux/irqdomain.h>
>> #include <linux/kernel.h>
>> +#include <linux/mfd/syscon.h>
>> #include <linux/module.h>
>> #include <linux/of_address.h>
>> #include <linux/of_irq.h>
>> #include <linux/of_platform.h>
>> #include <linux/platform_device.h>
>> +#include <linux/regmap.h>
>> #include <linux/reset.h>
>> #include <linux/slab.h>
>> -/* I2C Register */
>> +/* I2C Global Registers */
>> +/* 0x00 : I2CG Interrupt Status Register */
>> +/* 0x08 : I2CG Interrupt Target Assignment */
>> +/* 0x0c : I2CG Global Control Register (AST2500) */
>> +#define ASPEED_I2CG_GLOBAL_CTRL_REG 0x0c
>> +#define ASPEED_I2CG_SRAM_BUFFER_EN BIT(0)
>> +
>> +/* I2C Bus Registers */
>> #define ASPEED_I2C_FUN_CTRL_REG 0x00
>> #define ASPEED_I2C_AC_TIMING_REG1 0x04
>> #define ASPEED_I2C_AC_TIMING_REG2 0x08
>> @@ -35,14 +45,12 @@
>> #define ASPEED_I2C_INTR_STS_REG 0x10
>> #define ASPEED_I2C_CMD_REG 0x14
>> #define ASPEED_I2C_DEV_ADDR_REG 0x18
>> +#define ASPEED_I2C_BUF_CTRL_REG 0x1c
>> #define ASPEED_I2C_BYTE_BUF_REG 0x20
>> -/* Global Register Definition */
>> -/* 0x00 : I2C Interrupt Status Register */
>> -/* 0x08 : I2C Interrupt Target Assignment */
>> -
>> /* Device Register Definition */
>> /* 0x00 : I2CD Function Control Register */
>> +#define ASPEED_I2CD_BUFFER_PAGE_SEL_MASK GENMASK(22, 20)
>> #define ASPEED_I2CD_MULTI_MASTER_DIS BIT(15)
>> #define ASPEED_I2CD_SDA_DRIVE_1T_EN BIT(8)
>> #define ASPEED_I2CD_M_SDA_DRIVE_1T_EN BIT(7)
>> @@ -102,6 +110,8 @@
>> #define ASPEED_I2CD_BUS_RECOVER_CMD BIT(11)
>> /* Command Bit */
>> +#define ASPEED_I2CD_RX_BUFF_ENABLE BIT(7)
>> +#define ASPEED_I2CD_TX_BUFF_ENABLE BIT(6)
>> #define ASPEED_I2CD_M_STOP_CMD BIT(5)
>> #define ASPEED_I2CD_M_S_RX_CMD_LAST BIT(4)
>> #define ASPEED_I2CD_M_RX_CMD BIT(3)
>> @@ -112,6 +122,13 @@
>> /* 0x18 : I2CD Slave Device Address Register */
>> #define ASPEED_I2CD_DEV_ADDR_MASK GENMASK(6, 0)
>> +/* 0x1c : I2CD Buffer Control Register */
>> +/* Use 8-bits or 6-bits wide bit fileds to support both AST2400 and
>> AST2500 */
>> +#define ASPEED_I2CD_BUF_RX_COUNT_MASK GENMASK(31, 24)
>> +#define ASPEED_I2CD_BUF_RX_SIZE_MASK GENMASK(23, 16)
>> +#define ASPEED_I2CD_BUF_TX_COUNT_MASK GENMASK(15, 8)
>> +#define ASPEED_I2CD_BUF_OFFSET_MASK GENMASK(5, 0)
>> +
>> enum aspeed_i2c_master_state {
>> ASPEED_I2C_MASTER_INACTIVE,
>> ASPEED_I2C_MASTER_PENDING,
>> @@ -157,6 +174,11 @@ struct aspeed_i2c_bus {
>> int master_xfer_result;
>> /* Multi-master */
>> bool multi_master;
>> + /* Buffer mode */
>> + void __iomem *buf_base;
>> + size_t buf_size;
>> + u8 buf_offset;
>> + u8 buf_page;
>> #if IS_ENABLED(CONFIG_I2C_SLAVE)
>> struct i2c_client *slave;
>> enum aspeed_i2c_slave_state slave_state;
>> @@ -238,6 +260,7 @@ static u32 aspeed_i2c_slave_irq(struct
>> aspeed_i2c_bus *bus, u32 irq_status)
>> {
>> u32 command, irq_handled = 0;
>> struct i2c_client *slave = bus->slave;
>> + int i, len;
>> u8 value;
>> if (!slave)
>> @@ -260,7 +283,12 @@ static u32 aspeed_i2c_slave_irq(struct
>> aspeed_i2c_bus *bus, u32 irq_status)
>> /* Slave was sent something. */
>> if (irq_status & ASPEED_I2CD_INTR_RX_DONE) {
>> - value = readl(bus->base + ASPEED_I2C_BYTE_BUF_REG) >> 8;
>> + if (bus->buf_base &&
>> + bus->slave_state == ASPEED_I2C_SLAVE_WRITE_RECEIVED &&
>> + !(irq_status & ASPEED_I2CD_INTR_NORMAL_STOP))
>> + value = readb(bus->buf_base);
>> + else
>> + value = readl(bus->base + ASPEED_I2C_BYTE_BUF_REG) >> 8;
>> /* Handle address frame. */
>> if (bus->slave_state == ASPEED_I2C_SLAVE_START) {
>> if (value & 0x1)
>> @@ -275,6 +303,20 @@ static u32 aspeed_i2c_slave_irq(struct
>> aspeed_i2c_bus *bus, u32 irq_status)
>> /* Slave was asked to stop. */
>> if (irq_status & ASPEED_I2CD_INTR_NORMAL_STOP) {
>> + if (bus->slave_state == ASPEED_I2C_SLAVE_WRITE_RECEIVED &&
>> + irq_status & ASPEED_I2CD_INTR_RX_DONE) {
>> + if (bus->buf_base) {
>> + len = FIELD_GET(ASPEED_I2CD_BUF_RX_COUNT_MASK,
>> + readl(bus->base +
>> + ASPEED_I2C_BUF_CTRL_REG));
>> + for (i = 0; i < len; i++) {
>> + value = readb(bus->buf_base + i);
>> + i2c_slave_event(slave,
>> + I2C_SLAVE_WRITE_RECEIVED,
>> + &value);
>> + }
>> + }
>> + }
>> irq_handled |= ASPEED_I2CD_INTR_NORMAL_STOP;
>> bus->slave_state = ASPEED_I2C_SLAVE_STOP;
>> }
>> @@ -307,9 +349,36 @@ static u32 aspeed_i2c_slave_irq(struct
>> aspeed_i2c_bus *bus, u32 irq_status)
>> case ASPEED_I2C_SLAVE_WRITE_REQUESTED:
>> bus->slave_state = ASPEED_I2C_SLAVE_WRITE_RECEIVED;
>> i2c_slave_event(slave, I2C_SLAVE_WRITE_REQUESTED, &value);
>> + if (bus->buf_base) {
>> + writel(FIELD_PREP(ASPEED_I2CD_BUF_RX_SIZE_MASK,
>> + bus->buf_size - 1) |
>> + FIELD_PREP(ASPEED_I2CD_BUF_OFFSET_MASK,
>> + bus->buf_offset),
>> + bus->base + ASPEED_I2C_BUF_CTRL_REG);
>> + writel(ASPEED_I2CD_RX_BUFF_ENABLE,
>> + bus->base + ASPEED_I2C_CMD_REG);
>> + }
>> break;
>> case ASPEED_I2C_SLAVE_WRITE_RECEIVED:
>> i2c_slave_event(slave, I2C_SLAVE_WRITE_RECEIVED, &value);
>> + if (bus->buf_base) {
>> + len = FIELD_GET(ASPEED_I2CD_BUF_RX_COUNT_MASK,
>> + readl(bus->base +
>> + ASPEED_I2C_BUF_CTRL_REG));
>> + for (i = 1; i < len; i++) {
>> + value = readb(bus->buf_base + i);
>> + i2c_slave_event(slave,
>> + I2C_SLAVE_WRITE_RECEIVED,
>> + &value);
>> + }
>> + writel(FIELD_PREP(ASPEED_I2CD_BUF_RX_SIZE_MASK,
>> + bus->buf_size - 1) |
>> + FIELD_PREP(ASPEED_I2CD_BUF_OFFSET_MASK,
>> + bus->buf_offset),
>> + bus->base + ASPEED_I2C_BUF_CTRL_REG);
>> + writel(ASPEED_I2CD_RX_BUFF_ENABLE,
>> + bus->base + ASPEED_I2C_CMD_REG);
>> + }
>> break;
>> case ASPEED_I2C_SLAVE_STOP:
>> i2c_slave_event(slave, I2C_SLAVE_STOP, &value);
>> @@ -335,6 +404,8 @@ static void aspeed_i2c_do_start(struct
>> aspeed_i2c_bus *bus)
>> u32 command = ASPEED_I2CD_M_START_CMD | ASPEED_I2CD_M_TX_CMD;
>> struct i2c_msg *msg = &bus->msgs[bus->msgs_index];
>> u8 slave_addr = i2c_8bit_addr_from_msg(msg);
>> + u8 wbuf[4];
>> + int len;
>> #if IS_ENABLED(CONFIG_I2C_SLAVE)
>> /*
>> @@ -353,12 +424,66 @@ static void aspeed_i2c_do_start(struct
>> aspeed_i2c_bus *bus)
>> if (msg->flags & I2C_M_RD) {
>> command |= ASPEED_I2CD_M_RX_CMD;
>> - /* Need to let the hardware know to NACK after RX. */
>> - if (msg->len == 1 && !(msg->flags & I2C_M_RECV_LEN))
>> - command |= ASPEED_I2CD_M_S_RX_CMD_LAST;
>> +
>> + if (bus->buf_base && !(msg->flags & I2C_M_RECV_LEN)) {
>> + command |= ASPEED_I2CD_RX_BUFF_ENABLE;
>> +
>> + if (msg->len > bus->buf_size) {
>> + len = bus->buf_size;
>> + } else {
>> + len = msg->len;
>> + command |= ASPEED_I2CD_M_S_RX_CMD_LAST;
>> + }
>> +
>> + writel(FIELD_PREP(ASPEED_I2CD_BUF_RX_SIZE_MASK,
>> + len - 1) |
>> + FIELD_PREP(ASPEED_I2CD_BUF_OFFSET_MASK,
>> + bus->buf_offset),
>> + bus->base + ASPEED_I2C_BUF_CTRL_REG);
>> + } else {
>> + /* Need to let the hardware know to NACK after RX. */
>> + if (msg->len == 1 && !(msg->flags & I2C_M_RECV_LEN))
>> + command |= ASPEED_I2CD_M_S_RX_CMD_LAST;
>> + }
>> + } else {
>> + if (bus->buf_base) {
>> + int i;
>> +
>> + command |= ASPEED_I2CD_TX_BUFF_ENABLE;
>> +
>> + if (msg->len + 1 > bus->buf_size)
>> + len = bus->buf_size;
>> + else
>> + len = msg->len + 1;
In case of one byte TX, len will be set 2 at here because the first byte
of the buffer is slave address.
>> +
>> + /*
>> + * Yeah, it looks clumsy but byte writings on a remapped
>> + * I2C SRAM cause corruptions so use this way to make
>> + * dword writings.
>> + */
>> + wbuf[0] = slave_addr;
>> + for (i = 1; i < len; i++) {
>> + wbuf[i % 4] = msg->buf[i - 1];
>> + if (i % 4 == 3)
>> + writel(*(u32 *)wbuf,
>> + bus->buf_base + i - 3);
>> + }
>> + if (--i % 4 != 3)
>> + writel(*(u32 *)wbuf,
>> + bus->buf_base + i - (i % 4));
>> +
>> + bus->buf_index = len - 1;
>
>
> Is updating the buf_index here correct? You haven't actually sent any
> data yet, only set the slave address and sent start. For a 1 byte tx,
> buf_index == 1 now. Then, when the master irq is received and status is
> ASPEED_I2C_MASTER_TX_FIRST, it fails the check for buf_index < msg->len
> and therefore doesn't send tx command...
>
> I could be misunderstanding what the hardware expects, but this behavior
> is different than the non-buffered case. This is causing a problem in QEMU.
It's correct. In case of 1 byte TX, bus->buf_index is now 1 at here
(2 - 1). See below comment in the master irq.
>
> Thanks,
>
> Eddie
>
>> +
>> + writel(FIELD_PREP(ASPEED_I2CD_BUF_TX_COUNT_MASK,
>> + len - 1) |
>> + FIELD_PREP(ASPEED_I2CD_BUF_OFFSET_MASK,
>> + bus->buf_offset),
>> + bus->base + ASPEED_I2C_BUF_CTRL_REG);
>> + }
>> }
>> - writel(slave_addr, bus->base + ASPEED_I2C_BYTE_BUF_REG);
>> + if (!(command & ASPEED_I2CD_TX_BUFF_ENABLE))
>> + writel(slave_addr, bus->base + ASPEED_I2C_BYTE_BUF_REG);
>> writel(command, bus->base + ASPEED_I2C_CMD_REG);
>> }
>> @@ -398,7 +523,7 @@ static u32 aspeed_i2c_master_irq(struct
>> aspeed_i2c_bus *bus, u32 irq_status)
>> u32 irq_handled = 0, command = 0;
>> struct i2c_msg *msg;
>> u8 recv_byte;
>> - int ret;
>> + int ret, len;
>> if (irq_status & ASPEED_I2CD_INTR_BUS_RECOVER_DONE) {
>> bus->master_state = ASPEED_I2C_MASTER_INACTIVE;
>> @@ -511,11 +636,43 @@ static u32 aspeed_i2c_master_irq(struct
>> aspeed_i2c_bus *bus, u32 irq_status)
>> /* fall through */
>> case ASPEED_I2C_MASTER_TX_FIRST:
>> if (bus->buf_index < msg->len) {
Below code is for sending for remaining data when msg->len is bigger
than the buffer size. In case of 1 byte TX, below code will be bypassed
because are bus->buf_index and msg->len are 1, and it will send a 'stop'
command below...
>> + command = ASPEED_I2CD_M_TX_CMD;
>> +
>> + if (bus->buf_base) {
>> + u8 wbuf[4];
>> + int i;
>> +
>> + command |= ASPEED_I2CD_TX_BUFF_ENABLE;
>> +
>> + if (msg->len - bus->buf_index > bus->buf_size)
>> + len = bus->buf_size;
>> + else
>> + len = msg->len - bus->buf_index;
>> +
>> + for (i = 0; i < len; i++) {
>> + wbuf[i % 4] = msg->buf[bus->buf_index
>> + + i];
>> + if (i % 4 == 3)
>> + writel(*(u32 *)wbuf,
>> + bus->buf_base + i - 3);
>> + }
>> + if (--i % 4 != 3)
>> + writel(*(u32 *)wbuf,
>> + bus->buf_base + i - (i % 4));
>> +
>> + bus->buf_index += len;
>> +
>> + writel(FIELD_PREP(ASPEED_I2CD_BUF_TX_COUNT_MASK,
>> + len - 1) |
>> + FIELD_PREP(ASPEED_I2CD_BUF_OFFSET_MASK,
>> + bus->buf_offset),
>> + bus->base + ASPEED_I2C_BUF_CTRL_REG);
>> + } else {
>> + writel(msg->buf[bus->buf_index++],
>> + bus->base + ASPEED_I2C_BYTE_BUF_REG);
>> + }
>> + writel(command, bus->base + ASPEED_I2C_CMD_REG);
>> bus->master_state = ASPEED_I2C_MASTER_TX;
>> - writel(msg->buf[bus->buf_index++],
>> - bus->base + ASPEED_I2C_BYTE_BUF_REG);
>> - writel(ASPEED_I2CD_M_TX_CMD,
>> - bus->base + ASPEED_I2C_CMD_REG);
>> } else {
>> aspeed_i2c_next_msg_or_stop(bus);
at here.
It works well in real hardware and I don't think it causes QEMU crash.
QEMU needs to emulate this buffer mode correctly to prevent the crash.
Thanks,
Jae
>> }
>> @@ -532,25 +689,56 @@ static u32 aspeed_i2c_master_irq(struct
>> aspeed_i2c_bus *bus, u32 irq_status)
>> }
>> irq_handled |= ASPEED_I2CD_INTR_RX_DONE;
>> - recv_byte = readl(bus->base + ASPEED_I2C_BYTE_BUF_REG) >> 8;
>> - msg->buf[bus->buf_index++] = recv_byte;
>> -
>> - if (msg->flags & I2C_M_RECV_LEN) {
>> - if (unlikely(recv_byte > I2C_SMBUS_BLOCK_MAX)) {
>> - bus->cmd_err = -EPROTO;
>> - aspeed_i2c_do_stop(bus);
>> - goto out_no_complete;
>> + if (bus->buf_base && !(msg->flags & I2C_M_RECV_LEN)) {
>> + len = FIELD_GET(ASPEED_I2CD_BUF_RX_COUNT_MASK,
>> + readl(bus->base +
>> + ASPEED_I2C_BUF_CTRL_REG));
>> + memcpy_fromio(msg->buf + bus->buf_index,
>> + bus->buf_base, len);
>> + bus->buf_index += len;
>> + } else {
>> + recv_byte = readl(bus->base + ASPEED_I2C_BYTE_BUF_REG)
>> + >> 8;
>> + msg->buf[bus->buf_index++] = recv_byte;
>> +
>> + if (msg->flags & I2C_M_RECV_LEN) {
>> + if (unlikely(recv_byte > I2C_SMBUS_BLOCK_MAX)) {
>> + bus->cmd_err = -EPROTO;
>> + aspeed_i2c_do_stop(bus);
>> + goto out_no_complete;
>> + }
>> + msg->len = recv_byte +
>> + ((msg->flags & I2C_CLIENT_PEC) ?
>> + 2 : 1);
>> + msg->flags &= ~I2C_M_RECV_LEN;
>> }
>> - msg->len = recv_byte +
>> - ((msg->flags & I2C_CLIENT_PEC) ? 2 : 1);
>> - msg->flags &= ~I2C_M_RECV_LEN;
>> }
>> if (bus->buf_index < msg->len) {
>> - bus->master_state = ASPEED_I2C_MASTER_RX;
>> command = ASPEED_I2CD_M_RX_CMD;
>> - if (bus->buf_index + 1 == msg->len)
>> - command |= ASPEED_I2CD_M_S_RX_CMD_LAST;
>> + bus->master_state = ASPEED_I2C_MASTER_RX;
>> + if (bus->buf_base) {
>> + command |= ASPEED_I2CD_RX_BUFF_ENABLE;
>> +
>> + if (msg->len - bus->buf_index >
>> + bus->buf_size) {
>> + len = bus->buf_size;
>> + } else {
>> + len = msg->len - bus->buf_index;
>> + command |= ASPEED_I2CD_M_S_RX_CMD_LAST;
>> + }
>> +
>> + writel(FIELD_PREP(ASPEED_I2CD_BUF_RX_SIZE_MASK,
>> + len - 1) |
>> + FIELD_PREP(ASPEED_I2CD_BUF_TX_COUNT_MASK,
>> + 0) |
>> + FIELD_PREP(ASPEED_I2CD_BUF_OFFSET_MASK,
>> + bus->buf_offset),
>> + bus->base + ASPEED_I2C_BUF_CTRL_REG);
>> + } else {
>> + if (bus->buf_index + 1 == msg->len)
>> + command |= ASPEED_I2CD_M_S_RX_CMD_LAST;
>> + }
>> writel(command, bus->base + ASPEED_I2C_CMD_REG);
>> } else {
>> aspeed_i2c_next_msg_or_stop(bus);
>> @@ -890,6 +1078,9 @@ static int aspeed_i2c_init(struct aspeed_i2c_bus
>> *bus,
>> if (ret < 0)
>> return ret;
>> + fun_ctrl_reg |= FIELD_PREP(ASPEED_I2CD_BUFFER_PAGE_SEL_MASK,
>> + bus->buf_page);
>> +
>> if (of_property_read_bool(pdev->dev.of_node, "multi-master"))
>> bus->multi_master = true;
>> else
>> @@ -947,16 +1138,15 @@ static int aspeed_i2c_probe_bus(struct
>> platform_device *pdev)
>> {
>> const struct of_device_id *match;
>> struct aspeed_i2c_bus *bus;
>> + bool sram_enabled = true;
>> struct clk *parent_clk;
>> - struct resource *res;
>> int irq, ret;
>> bus = devm_kzalloc(&pdev->dev, sizeof(*bus), GFP_KERNEL);
>> if (!bus)
>> return -ENOMEM;
>> - res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>> - bus->base = devm_ioremap_resource(&pdev->dev, res);
>> + bus->base = devm_platform_ioremap_resource(pdev, 0);
>> if (IS_ERR(bus->base))
>> return PTR_ERR(bus->base);
>> @@ -990,6 +1180,42 @@ static int aspeed_i2c_probe_bus(struct
>> platform_device *pdev)
>> bus->get_clk_reg_val = (u32 (*)(struct device *, u32))
>> match->data;
>> + /* Enable I2C SRAM in case of AST2500 */
>> + if (of_device_is_compatible(pdev->dev.of_node,
>> + "aspeed,ast2500-i2c-bus")) {
>> + struct regmap *gr_regmap = syscon_regmap_lookup_by_compatible(
>> + "aspeed,ast2500-i2c-gr");
>> + if (IS_ERR(gr_regmap))
>> + ret = PTR_ERR(gr_regmap);
>> + else
>> + ret = regmap_update_bits(gr_regmap,
>> + ASPEED_I2CG_GLOBAL_CTRL_REG,
>> + ASPEED_I2CG_SRAM_BUFFER_EN,
>> + ASPEED_I2CG_SRAM_BUFFER_EN);
>> +
>> + if (ret)
>> + sram_enabled = false;
>> + }
>> +
>> + if (sram_enabled) {
>> + struct resource *res = platform_get_resource(pdev,
>> + IORESOURCE_MEM, 1);
>> +
>> + bus->buf_base = devm_ioremap_resource(&pdev->dev, res);
>> + if (IS_ERR(bus->buf_base) || resource_size(res) < 2) {
>> + bus->buf_base = NULL;
>> + } else {
>> + bus->buf_size = resource_size(res);
>> + if (of_device_is_compatible(pdev->dev.of_node,
>> + "aspeed,ast2400-i2c-bus")) {
>> + bus->buf_page = ((res->start >> 8) &
>> + GENMASK(3, 0)) - 8;
>> + bus->buf_offset = (res->start >> 2) &
>> + ASPEED_I2CD_BUF_OFFSET_MASK;
>> + }
>> + }
>> + }
>> +
>> /* Initialize the I2C adapter */
>> spin_lock_init(&bus->lock);
>> init_completion(&bus->cmd_complete);
>> @@ -1026,8 +1252,8 @@ static int aspeed_i2c_probe_bus(struct
>> platform_device *pdev)
>> platform_set_drvdata(pdev, bus);
>> - dev_info(bus->dev, "i2c bus %d registered, irq %d\n",
>> - bus->adap.nr, irq);
>> + dev_info(bus->dev, "i2c bus %d registered (%s mode), irq %d\n",
>> + bus->adap.nr, bus->buf_base ? "buffer" : "byte", irq);
>> return 0;
>> }
More information about the openbmc
mailing list