From: Jae Hyun Yoo <jae.hyun.yoo@linux.intel.com>
To: Brendan Higgins <brendanhiggins@google.com>
Cc: Wolfram Sang <wsa@the-dreams.de>,
Benjamin Herrenschmidt <benh@kernel.crashing.org>,
Joel Stanley <joel@jms.id.au>, Rob Herring <robh+dt@kernel.org>,
Mark Rutland <mark.rutland@arm.com>,
Andrew Jeffery <andrew@aj.id.au>, Tao Ren <taoren@fb.com>,
Cedric Le Goater <clg@kaod.org>,
Linux I2C <linux-i2c@vger.kernel.org>,
devicetree <devicetree@vger.kernel.org>,
linux-aspeed <linux-aspeed@lists.ozlabs.org>,
OpenBMC Maillist <openbmc@lists.ozlabs.org>
Subject: Re: [PATCH v4 4/4] i2c: aspeed: add DMA mode transfer support
Date: Wed, 14 Apr 2021 08:08:35 -0700 [thread overview]
Message-ID: <685d21f9-2f9d-c0ae-ee77-10eb4441870c@linux.intel.com> (raw)
In-Reply-To: <CAFd5g46eAcnSVFuUrXTuJmP-s_hsXDJ9x4QSQUM5JqfxFNwJVw@mail.gmail.com>
Hi Brendan,
On 4/13/2021 2:32 PM, Brendan Higgins wrote:
> On Wed, Feb 24, 2021 at 11:04 AM Jae Hyun Yoo
> <jae.hyun.yoo@linux.intel.com> wrote:
>>
>> This commit adds DMA mode transfer support.
>>
>> Only AST2500 and later versions support DMA mode.
>>
>> AST2500 has these restrictions:
>> - If one of these controllers is enabled
>> * UHCI host controller
>> * MCTP controller
>> I2C has to use buffer mode or byte mode instead
>> since these controllers run only in DMA mode and
>> I2C is sharing the same DMA H/W with them.
>> - If one of these controllers uses DMA mode, I2C
>> can't use DMA mode
>> * SD/eMMC
>> * Port80 snoop
>>
>> Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo@linux.intel.com>
>> ---
>> Changes since v3:
>> - None
>>
>> Changes since v2:
>> - Refined SoC family dependent xfer mode configuration functions.
>>
>> Changes since v1:
>> - Updated commit message and comments.
>> - Refined using abstract functions.
>>
>> drivers/i2c/busses/i2c-aspeed.c | 265 ++++++++++++++++++++++++++------
>> 1 file changed, 216 insertions(+), 49 deletions(-)
>>
>> diff --git a/drivers/i2c/busses/i2c-aspeed.c b/drivers/i2c/busses/i2c-aspeed.c
>> index ffc52937df26..3e3bb014b027 100644
>> --- a/drivers/i2c/busses/i2c-aspeed.c
>> +++ b/drivers/i2c/busses/i2c-aspeed.c
>> @@ -10,6 +10,8 @@
>> #include <linux/bitfield.h>
>> #include <linux/clk.h>
>> #include <linux/completion.h>
>> +#include <linux/dma-mapping.h>
>> +#include <linux/dmapool.h>
>> #include <linux/err.h>
>> #include <linux/errno.h>
>> #include <linux/i2c.h>
>> @@ -47,6 +49,8 @@
>> #define ASPEED_I2C_DEV_ADDR_REG 0x18
>> #define ASPEED_I2C_BUF_CTRL_REG 0x1c
>> #define ASPEED_I2C_BYTE_BUF_REG 0x20
>> +#define ASPEED_I2C_DMA_ADDR_REG 0x24
>> +#define ASPEED_I2C_DMA_LEN_REG 0x28
>>
>> /* Device Register Definition */
>> /* 0x00 : I2CD Function Control Register */
>> @@ -111,6 +115,8 @@
>> #define ASPEED_I2CD_BUS_RECOVER_CMD BIT(11)
>>
>> /* Command Bit */
>> +#define ASPEED_I2CD_RX_DMA_ENABLE BIT(9)
>> +#define ASPEED_I2CD_TX_DMA_ENABLE BIT(8)
>> #define ASPEED_I2CD_RX_BUFF_ENABLE BIT(7)
>> #define ASPEED_I2CD_TX_BUFF_ENABLE BIT(6)
>> #define ASPEED_I2CD_M_STOP_CMD BIT(5)
>> @@ -136,6 +142,14 @@
>> #define ASPEED_I2CD_BUF_TX_COUNT_MASK GENMASK(15, 8)
>> #define ASPEED_I2CD_BUF_OFFSET_MASK GENMASK(5, 0)
>>
>> +/* 0x24 : I2CD DMA Mode Buffer Address Register */
>> +#define ASPEED_I2CD_DMA_ADDR_MASK GENMASK(31, 2)
>> +#define ASPEED_I2CD_DMA_ALIGN 4
>> +
>> +/* 0x28 : I2CD DMA Transfer Length Register */
>> +#define ASPEED_I2CD_DMA_LEN_SHIFT 0
>> +#define ASPEED_I2CD_DMA_LEN_MASK GENMASK(11, 0)
>> +
>> enum aspeed_i2c_master_state {
>> ASPEED_I2C_MASTER_INACTIVE,
>> ASPEED_I2C_MASTER_PENDING,
>> @@ -161,6 +175,7 @@ struct aspeed_i2c_config {
>> u32 (*get_clk_reg_val)(struct device *dev, u32 divisor);
>> int (*enable_sram)(void);
>> int (*set_buf_xfer_mode)(struct device *dev);
>> + int (*set_dma_xfer_mode)(struct device *dev);
>> };
>>
>> struct aspeed_i2c_bus {
>> @@ -190,6 +205,12 @@ struct aspeed_i2c_bus {
>> void __iomem *buf_base;
>> u8 buf_offset;
>> u8 buf_page;
>> + /* DMA mode */
>> + struct dma_pool *dma_pool;
>> + dma_addr_t dma_handle;
>> + u8 *dma_buf;
>> + size_t dma_len;
>> + /* Buffer/DMA mode */
>> size_t buf_size;
>> #if IS_ENABLED(CONFIG_I2C_SLAVE)
>> struct i2c_client *slave;
>> @@ -272,9 +293,13 @@ static inline void
>> aspeed_i2c_slave_handle_rx_done(struct aspeed_i2c_bus *bus, u32 irq_status,
>> u8 *value)
>> {
>> - if (bus->buf_base &&
>> + if (bus->dma_buf &&
>> bus->slave_state == ASPEED_I2C_SLAVE_WRITE_RECEIVED &&
>> !(irq_status & ASPEED_I2CD_INTR_NORMAL_STOP))
>> + *value = bus->dma_buf[0];
>> + else 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;
>> @@ -288,7 +313,18 @@ aspeed_i2c_slave_handle_normal_stop(struct aspeed_i2c_bus *bus, u32 irq_status,
>>
>> if (bus->slave_state == ASPEED_I2C_SLAVE_WRITE_RECEIVED &&
>> irq_status & ASPEED_I2CD_INTR_RX_DONE) {
>> - if (bus->buf_base) {
>> + if (bus->dma_buf) {
>> + len = bus->buf_size -
>> + FIELD_GET(ASPEED_I2CD_DMA_LEN_MASK,
>> + readl(bus->base +
>> + ASPEED_I2C_DMA_LEN_REG));
>> + for (i = 0; i < len; i++) {
>> + *value = bus->dma_buf[i];
>> + i2c_slave_event(bus->slave,
>> + I2C_SLAVE_WRITE_RECEIVED,
>> + value);
>> + }
>> + } else if (bus->buf_base) {
>> len = FIELD_GET(ASPEED_I2CD_BUF_RX_COUNT_MASK,
>> readl(bus->base +
>> ASPEED_I2C_BUF_CTRL_REG));
>> @@ -305,7 +341,14 @@ aspeed_i2c_slave_handle_normal_stop(struct aspeed_i2c_bus *bus, u32 irq_status,
>> static inline void
>> aspeed_i2c_slave_handle_write_requested(struct aspeed_i2c_bus *bus, u8 *value)
>> {
>> - if (bus->buf_base) {
>> + if (bus->dma_buf) {
>> + writel(bus->dma_handle & ASPEED_I2CD_DMA_ADDR_MASK,
>> + bus->base + ASPEED_I2C_DMA_ADDR_REG);
>> + writel(FIELD_PREP(ASPEED_I2CD_DMA_LEN_MASK, bus->buf_size),
>> + bus->base + ASPEED_I2C_DMA_LEN_REG);
>> + writel(ASPEED_I2CD_RX_DMA_ENABLE,
>> + bus->base + ASPEED_I2C_CMD_REG);
>> + } else if (bus->buf_base) {
>> writel(FIELD_PREP(ASPEED_I2CD_BUF_RX_SIZE_MASK,
>> bus->buf_size - 1) |
>> FIELD_PREP(ASPEED_I2CD_BUF_OFFSET_MASK,
>> @@ -321,7 +364,23 @@ aspeed_i2c_slave_handle_write_received(struct aspeed_i2c_bus *bus, u8 *value)
>> {
>> int i, len;
>>
>> - if (bus->buf_base) {
>> + if (bus->dma_buf) {
>> + len = bus->buf_size -
>> + FIELD_GET(ASPEED_I2CD_DMA_LEN_MASK,
>> + readl(bus->base +
>> + ASPEED_I2C_DMA_LEN_REG));
>> + for (i = 1; i < len; i++) {
>> + *value = bus->dma_buf[i];
>> + i2c_slave_event(bus->slave, I2C_SLAVE_WRITE_RECEIVED,
>> + value);
>> + }
>> + writel(bus->dma_handle & ASPEED_I2CD_DMA_ADDR_MASK,
>> + bus->base + ASPEED_I2C_DMA_ADDR_REG);
>> + writel(FIELD_PREP(ASPEED_I2CD_DMA_LEN_MASK, bus->buf_size),
>> + bus->base + ASPEED_I2C_DMA_LEN_REG);
>> + writel(ASPEED_I2CD_RX_DMA_ENABLE,
>> + bus->base + ASPEED_I2C_CMD_REG);
>> + } else if (bus->buf_base) {
>> len = FIELD_GET(ASPEED_I2CD_BUF_RX_COUNT_MASK,
>> readl(bus->base +
>> ASPEED_I2C_BUF_CTRL_REG));
>> @@ -451,7 +510,15 @@ aspeed_i2c_prepare_rx_buf(struct aspeed_i2c_bus *bus, struct i2c_msg *msg)
>> command |= ASPEED_I2CD_M_S_RX_CMD_LAST;
>> }
>>
>> - if (bus->buf_base) {
>> + if (bus->dma_buf) {
>> + command |= ASPEED_I2CD_RX_DMA_ENABLE;
>> +
>> + writel(bus->dma_handle & ASPEED_I2CD_DMA_ADDR_MASK,
>> + bus->base + ASPEED_I2C_DMA_ADDR_REG);
>> + writel(FIELD_PREP(ASPEED_I2CD_DMA_LEN_MASK, len),
>> + bus->base + ASPEED_I2C_DMA_LEN_REG);
>> + bus->dma_len = len;
>> + } else {
>> command |= ASPEED_I2CD_RX_BUFF_ENABLE;
>>
>> writel(FIELD_PREP(ASPEED_I2CD_BUF_RX_SIZE_MASK, len - 1) |
>> @@ -474,7 +541,18 @@ aspeed_i2c_prepare_tx_buf(struct aspeed_i2c_bus *bus, struct i2c_msg *msg)
>> else
>> len = msg->len + 1;
>>
>> - if (bus->buf_base) {
>> + if (bus->dma_buf) {
>> + command |= ASPEED_I2CD_TX_DMA_ENABLE;
>> +
>> + bus->dma_buf[0] = slave_addr;
>> + memcpy(bus->dma_buf + 1, msg->buf, len);
>> +
>> + writel(bus->dma_handle & ASPEED_I2CD_DMA_ADDR_MASK,
>> + bus->base + ASPEED_I2C_DMA_ADDR_REG);
>> + writel(FIELD_PREP(ASPEED_I2CD_DMA_LEN_MASK, len),
>> + bus->base + ASPEED_I2C_DMA_LEN_REG);
>> + bus->dma_len = len;
>> + } else {
>> u8 wbuf[4];
>> int i;
>>
>> @@ -527,18 +605,19 @@ static void aspeed_i2c_do_start(struct aspeed_i2c_bus *bus)
>> if (msg->flags & I2C_M_RD) {
>> command |= ASPEED_I2CD_M_RX_CMD;
>> if (!(msg->flags & I2C_M_RECV_LEN)) {
>> - if (msg->len && bus->buf_base)
>> + if (msg->len && (bus->dma_buf || bus->buf_base))
>> command |= aspeed_i2c_prepare_rx_buf(bus, msg);
>>
>> /* Need to let the hardware know to NACK after RX. */
>> if (msg->len <= 1)
>> command |= ASPEED_I2CD_M_S_RX_CMD_LAST;
>> }
>> - } else if (msg->len && bus->buf_base) {
>> + } else if (msg->len && (bus->dma_buf || bus->buf_base)) {
>> command |= aspeed_i2c_prepare_tx_buf(bus, msg);
>> }
>>
>> - if (!(command & ASPEED_I2CD_TX_BUFF_ENABLE))
>> + if (!(command & (ASPEED_I2CD_TX_BUFF_ENABLE |
>> + ASPEED_I2CD_TX_DMA_ENABLE)))
>> writel(i2c_8bit_addr_from_msg(msg),
>> bus->base + ASPEED_I2C_BYTE_BUF_REG);
>> writel(command, bus->base + ASPEED_I2C_CMD_REG);
>> @@ -581,42 +660,55 @@ aspeed_i2c_master_handle_tx_first(struct aspeed_i2c_bus *bus,
>> {
>> u32 command = 0;
>>
>> - if (bus->buf_base) {
>> - u8 wbuf[4];
>> + if (bus->dma_buf || bus->buf_base) {
>> int len;
>> - int i;
>>
>> if (msg->len - bus->buf_index > bus->buf_size)
>> len = bus->buf_size;
>> else
>> len = msg->len - bus->buf_index;
>>
>> - command |= ASPEED_I2CD_TX_BUFF_ENABLE;
>> + if (bus->dma_buf) {
>> + command |= ASPEED_I2CD_TX_DMA_ENABLE;
>>
>> - if (msg->len - bus->buf_index > bus->buf_size)
>> - len = bus->buf_size;
>> - else
>> - len = msg->len - bus->buf_index;
>> + memcpy(bus->dma_buf, msg->buf + bus->buf_index, len);
>>
>> - /*
>> - * Looks bad here again but use dword writings to avoid data
>> - * corruption of byte writing on remapped I2C SRAM.
>> - */
>> - for (i = 0; i < len; i++) {
>> - wbuf[i % 4] = msg->buf[bus->buf_index + i];
>> - if (i % 4 == 3)
>> + writel(bus->dma_handle & ASPEED_I2CD_DMA_ADDR_MASK,
>> + bus->base + ASPEED_I2C_DMA_ADDR_REG);
>> + writel(FIELD_PREP(ASPEED_I2CD_DMA_LEN_MASK, len),
>> + bus->base + ASPEED_I2C_DMA_LEN_REG);
>> + bus->dma_len = len;
>> + } else {
>> + 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;
>> +
>> + /*
>> + * Looks bad here again but use dword writings to avoid
>> + * data corruption of byte writing on remapped I2C SRAM.
>> + */
>> + 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 - 3);
>> - }
>> - if (--i % 4 != 3)
>> - writel(*(u32 *)wbuf,
>> - bus->buf_base + i - (i % 4));
>> + bus->buf_base + i - (i % 4));
>>
>> - 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(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);
>> + }
>>
>> bus->buf_index += len;
>> } else {
>
> Some of these functions are getting really complex and most of the
> logic for the different modes is in different if-else blocks. Could
> you look into splitting this into separate functions based on which
> mode is being used?
>
> Otherwise, this patch looks good.
I already splitted some big chunk of mode dependant logics to address
your comment on v1. Could you please check again the patched result of
this function? It's not much complex and it'd be better keep as is for
consistency in other changes in this patch. I think, splitting it again
would be not good for readability of the code flow.
Thanks,
Jae
>> @@ -633,7 +725,14 @@ aspeed_i2c_master_handle_rx(struct aspeed_i2c_bus *bus, struct i2c_msg *msg)
>> u8 recv_byte;
>> int len;
>>
>> - if (bus->buf_base) {
>> + if (bus->dma_buf) {
>> + len = bus->dma_len -
>> + FIELD_GET(ASPEED_I2CD_DMA_LEN_MASK,
>> + readl(bus->base + ASPEED_I2C_DMA_LEN_REG));
>> +
>> + memcpy(msg->buf + bus->buf_index, bus->dma_buf, len);
>> + bus->buf_index += len;
>> + } else if (bus->buf_base) {
>> 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);
>> @@ -650,7 +749,7 @@ aspeed_i2c_master_handle_rx_next(struct aspeed_i2c_bus *bus,
>> {
>> u32 command = 0;
>>
>> - if (bus->buf_base) {
>> + if (bus->dma_buf || bus->buf_base) {
>> int len;
>>
>> if (msg->len - bus->buf_index > bus->buf_size) {
>> @@ -660,14 +759,24 @@ aspeed_i2c_master_handle_rx_next(struct aspeed_i2c_bus *bus,
>> command |= ASPEED_I2CD_M_S_RX_CMD_LAST;
>> }
>>
>> - command |= ASPEED_I2CD_RX_BUFF_ENABLE;
>> + if (bus->dma_buf) {
>> + command |= ASPEED_I2CD_RX_DMA_ENABLE;
>>
>> - 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);
>> + writel(bus->dma_handle & ASPEED_I2CD_DMA_ADDR_MASK,
>> + bus->base + ASPEED_I2C_DMA_ADDR_REG);
>> + writel(FIELD_PREP(ASPEED_I2CD_DMA_LEN_MASK, len),
>> + bus->base + ASPEED_I2C_DMA_LEN_REG);
>> + bus->dma_len = len;
>> + } else {
>> + command |= ASPEED_I2CD_RX_BUFF_ENABLE;
>> +
>> + 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;
>> @@ -1287,22 +1396,63 @@ static int aspeed_i2c_25xx_set_buf_xfer_mode(struct device *dev)
>> return bus->buf_size ? 0 : -EINVAL;
>> }
>>
>> +static int aspeed_i2c_24xx_set_dma_xfer_mode(struct device *dev)
>> +{
>> + /* AST24xx doesn't support DMA mode */
>> +
>> + return -EBADR;
>> +}
>> +
>> +static int aspeed_i2c_25xx_set_dma_xfer_mode(struct device *dev)
>> +{
>> + struct platform_device *pdev = to_platform_device(dev);
>> + struct aspeed_i2c_bus *bus = platform_get_drvdata(pdev);
>> + int ret;
>> +
>> + ret = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
>> + if (!ret) {
>> + bus->buf_size = ASPEED_I2CD_DMA_LEN_MASK >>
>> + ASPEED_I2CD_DMA_LEN_SHIFT;
>> + bus->dma_pool = dma_pool_create("i2c-aspeed",
>> + &pdev->dev,
>> + bus->buf_size,
>> + ASPEED_I2CD_DMA_ALIGN,
>> + 0);
>> + if (bus->dma_pool)
>> + bus->dma_buf = dma_pool_alloc(bus->dma_pool,
>> + GFP_KERNEL,
>> + &bus->dma_handle);
>> +
>> + if (!bus->dma_buf) {
>> + ret = -ENOMEM;
>> + bus->buf_size = 0;
>> + dev_dbg(&pdev->dev, "Cannot allocate DMA buffer\n");
>> + dma_pool_destroy(bus->dma_pool);
>> + }
>> + }
>> +
>> + return ret;
>> +}
>> +
>> static const struct aspeed_i2c_config ast24xx_config = {
>> .get_clk_reg_val = aspeed_i2c_24xx_get_clk_reg_val,
>> .enable_sram = aspeed_i2c_24xx_enable_sram,
>> .set_buf_xfer_mode = aspeed_i2c_24xx_set_buf_xfer_mode,
>> + .set_dma_xfer_mode = aspeed_i2c_24xx_set_dma_xfer_mode,
>> };
>>
>> static const struct aspeed_i2c_config ast25xx_config = {
>> .get_clk_reg_val = aspeed_i2c_25xx_get_clk_reg_val,
>> .enable_sram = aspeed_i2c_25xx_enable_sram,
>> .set_buf_xfer_mode = aspeed_i2c_25xx_set_buf_xfer_mode,
>> + .set_dma_xfer_mode = aspeed_i2c_25xx_set_dma_xfer_mode,
>> };
>>
>> static const struct aspeed_i2c_config ast26xx_config = {
>> .get_clk_reg_val = aspeed_i2c_25xx_get_clk_reg_val,
>> .enable_sram = aspeed_i2c_24xx_enable_sram,
>> .set_buf_xfer_mode = aspeed_i2c_25xx_set_buf_xfer_mode,
>> + .set_dma_xfer_mode = aspeed_i2c_25xx_set_dma_xfer_mode,
>> };
>>
>> static const struct of_device_id aspeed_i2c_bus_of_table[] = {
>> @@ -1324,8 +1474,12 @@ static void aspeed_i2c_set_xfer_mode(struct aspeed_i2c_bus *bus)
>> return;
>>
>> ret = bus->config->enable_sram();
>> - if (!ret && !strncasecmp(mode, "buf", 3))
>> - ret = bus->config->set_buf_xfer_mode(bus->dev);
>> + if (!ret) {
>> + if (!strncasecmp(mode, "buf", 3))
>> + ret = bus->config->set_buf_xfer_mode(bus->dev);
>> + else if (!strncasecmp(mode, "dma", 3))
>> + ret = bus->config->set_dma_xfer_mode(bus->dev);
>> + }
>>
>> if (ret)
>> dev_dbg(&pdev->dev, "Use default (byte) xfer mode\n");
>> @@ -1400,22 +1554,31 @@ static int aspeed_i2c_probe_bus(struct platform_device *pdev)
>> */
>> ret = aspeed_i2c_init(bus, pdev);
>> if (ret < 0)
>> - return ret;
>> + goto out_free_dma_buf;
>>
>> irq = irq_of_parse_and_map(pdev->dev.of_node, 0);
>> ret = devm_request_irq(&pdev->dev, irq, aspeed_i2c_bus_irq,
>> 0, dev_name(&pdev->dev), bus);
>> if (ret < 0)
>> - return ret;
>> + goto out_free_dma_buf;
>>
>> ret = i2c_add_adapter(&bus->adap);
>> if (ret < 0)
>> - return ret;
>> + goto out_free_dma_buf;
>>
>> dev_info(bus->dev, "i2c bus %d registered (%s mode), irq %d\n",
>> - bus->adap.nr, bus->buf_base ? "buf" : "byte", irq);
>> + bus->adap.nr, bus->dma_buf ? "dma" :
>> + bus->buf_base ? "buf" : "byte",
>> + irq);
>>
>> return 0;
>> +
>> +out_free_dma_buf:
>> + if (bus->dma_buf)
>> + dma_pool_free(bus->dma_pool, bus->dma_buf, bus->dma_handle);
>> + dma_pool_destroy(bus->dma_pool);
>> +
>> + return ret;
>> }
>>
>> static int aspeed_i2c_remove_bus(struct platform_device *pdev)
>> @@ -1433,6 +1596,10 @@ static int aspeed_i2c_remove_bus(struct platform_device *pdev)
>>
>> reset_control_assert(bus->rst);
>>
>> + if (bus->dma_buf)
>> + dma_pool_free(bus->dma_pool, bus->dma_buf, bus->dma_handle);
>> + dma_pool_destroy(bus->dma_pool);
>> +
>> i2c_del_adapter(&bus->adap);
>>
>> return 0;
>> --
>> 2.17.1
>>
next prev parent reply other threads:[~2021-04-14 15:09 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-02-24 19:17 [PATCH v4 0/4] i2c: aspeed: Add buffer and DMA modes support Jae Hyun Yoo
2021-02-24 19:17 ` [PATCH v4 1/4] dt-bindings: i2c: aspeed: add transfer mode support Jae Hyun Yoo
2021-03-06 20:30 ` Rob Herring
2021-03-09 17:02 ` Jae Hyun Yoo
2021-03-10 2:15 ` Rob Herring
2021-03-10 15:55 ` Jae Hyun Yoo
2021-04-08 17:50 ` Jae Hyun Yoo
2021-04-13 19:50 ` Brendan Higgins
2021-10-01 17:05 ` Jae Hyun Yoo
2021-02-24 19:17 ` [PATCH v4 2/4] ARM: dts: aspeed: modify I2C node to support buffer mode Jae Hyun Yoo
2021-02-24 19:17 ` [PATCH v4 3/4] i2c: aspeed: add buffer mode transfer support Jae Hyun Yoo
2021-04-13 21:24 ` Brendan Higgins
2021-02-24 19:17 ` [PATCH v4 4/4] i2c: aspeed: add DMA " Jae Hyun Yoo
2021-04-13 21:32 ` Brendan Higgins
2021-04-14 15:08 ` Jae Hyun Yoo [this message]
2021-05-19 18:38 ` Jae Hyun Yoo
2021-09-30 2:44 ` [PATCH v4 0/4] i2c: aspeed: Add buffer and DMA modes support Zev Weiss
2021-10-01 17:06 ` Jae Hyun Yoo
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=685d21f9-2f9d-c0ae-ee77-10eb4441870c@linux.intel.com \
--to=jae.hyun.yoo@linux.intel.com \
--cc=andrew@aj.id.au \
--cc=benh@kernel.crashing.org \
--cc=brendanhiggins@google.com \
--cc=clg@kaod.org \
--cc=devicetree@vger.kernel.org \
--cc=joel@jms.id.au \
--cc=linux-aspeed@lists.ozlabs.org \
--cc=linux-i2c@vger.kernel.org \
--cc=mark.rutland@arm.com \
--cc=openbmc@lists.ozlabs.org \
--cc=robh+dt@kernel.org \
--cc=taoren@fb.com \
--cc=wsa@the-dreams.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).