Re: [PATCH v4 4/4] i2c: aspeed: add DMA mode transfer support

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, Feb 24, 2021 at 11:04 AM Jae Hyun Yoo
<jae.hyun.yoo@xxxxxxxxxxxxxxx> 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@xxxxxxxxxxxxxxx>
> ---
> 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.

> @@ -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
>



[Index of Archives]     [Device Tree Compilter]     [Device Tree Spec]     [Linux Driver Backports]     [Video for Linux]     [Linux USB Devel]     [Linux PCI Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [XFree86]     [Yosemite Backpacking]


  Powered by Linux