diff options
author | Gao Pan <pandy.gao@nxp.com> | 2017-07-14 17:36:59 +0800 |
---|---|---|
committer | Leonard Crestez <leonard.crestez@nxp.com> | 2018-08-24 12:41:33 +0300 |
commit | 9743c5a2a240dc9a55d9834b928bab0f8c555477 (patch) | |
tree | e343a37f23252194445b39394be3bdd8003f7da2 /drivers/mxc/mlb | |
parent | b5d728a1da27b003af71f3b0302d206ce3f86491 (diff) |
MLK-15987 imx: mlb: use dma pool when iram doesn't exist
alloc mlb data buffer from dma pool when iram doesn't exist
Signed-off-by: Gao Pan <pandy.gao@nxp.com>
Diffstat (limited to 'drivers/mxc/mlb')
-rwxr-xr-x | drivers/mxc/mlb/mxc_mlb.c | 38 |
1 files changed, 23 insertions, 15 deletions
diff --git a/drivers/mxc/mlb/mxc_mlb.c b/drivers/mxc/mlb/mxc_mlb.c index f935ab8cb848..fc65aa4baa1f 100755 --- a/drivers/mxc/mlb/mxc_mlb.c +++ b/drivers/mxc/mlb/mxc_mlb.c @@ -21,6 +21,7 @@ #include <linux/clk.h> #include <linux/delay.h> #include <linux/device.h> +#include <linux/dma-mapping.h> #include <linux/errno.h> #include <linux/fs.h> #include <linux/genalloc.h> @@ -365,6 +366,7 @@ struct mlb_dev_info { }; struct mlb_data { + struct device *dev; struct mlb_dev_info *devinfo; struct clk *clk_mlb3p; struct clk *clk_mlb6p; @@ -381,6 +383,7 @@ struct mlb_data { int irq_ahb1; int irq_mlb; u32 quirk_flag; + bool use_iram; }; /* @@ -1920,14 +1923,15 @@ static irqreturn_t mlb_isr(int irq, void *dev_id) static int mxc_mlb150_open(struct inode *inode, struct file *filp) { int minor, ring_buf_size, buf_size, j, ret; - void __iomem *buf_addr; - ulong phy_addr; + void *buf_addr; + dma_addr_t phy_addr; struct mlb_dev_info *pdevinfo = NULL; struct mlb_channel_info *pchinfo = NULL; struct mlb_data *drvdata; minor = MINOR(inode->i_rdev); drvdata = container_of(inode->i_cdev, struct mlb_data, cdev); + drvdata->use_iram = true; if (minor < 0 || minor >= MLB_MINOR_DEVICES) { pr_err("no device\n"); @@ -1950,19 +1954,24 @@ static int mxc_mlb150_open(struct inode *inode, struct file *filp) ring_buf_size = pdevinfo->buf_size; buf_size = ring_buf_size * (TRANS_RING_NODES * 2); - buf_addr = (void __iomem *)gen_pool_alloc(drvdata->iram_pool, buf_size); - if (buf_addr == NULL) { - ret = -ENOMEM; - pr_err("can not alloc rx/tx buffers: %d\n", buf_size); - return ret; + + buf_addr = gen_pool_dma_alloc(drvdata->iram_pool, buf_size, &phy_addr); + if (!buf_addr) { + drvdata->use_iram = false; + buf_addr = dma_alloc_coherent(drvdata->dev, buf_size, &phy_addr, GFP_KERNEL); + if (!buf_addr) { + ret = -ENOMEM; + pr_err("can not alloc rx/tx buffers: %d\n", buf_size); + return ret; + } } - phy_addr = gen_pool_virt_to_phys(drvdata->iram_pool, (ulong)buf_addr); + pr_debug("IRAM Range: Virt 0x%p - 0x%p, Phys 0x%x - 0x%x, size: 0x%x\n", buf_addr, (buf_addr + buf_size - 1), (u32)phy_addr, (u32)(phy_addr + buf_size - 1), buf_size); pdevinfo->rbuf_base_virt = buf_addr; pdevinfo->rbuf_base_phy = phy_addr; - drvdata->iram_size = buf_size; + drvdata->iram_size = drvdata->use_iram ? buf_size : 0; memset(buf_addr, 0, buf_size); @@ -2017,7 +2026,8 @@ static int mxc_mlb150_release(struct inode *inode, struct file *filp) mlb150_dev_dump_ctr_tbl(0, pdevinfo->channels[TX_CHANNEL].cl + 1); #endif - gen_pool_free(drvdata->iram_pool, + if (drvdata->use_iram) + gen_pool_free(drvdata->iram_pool, (ulong)pdevinfo->rbuf_base_virt, drvdata->iram_size); mlb150_dev_exit(); @@ -2542,6 +2552,7 @@ static int mxc_mlb150_probe(struct platform_device *pdev) return -ENOMEM; } + drvdata->dev = &pdev->dev; of_id = of_match_device(mlb150_imx_dt_ids, &pdev->dev); if (of_id) pdev->id_entry = of_id->data; @@ -2679,11 +2690,8 @@ static int mxc_mlb150_probe(struct platform_device *pdev) } drvdata->iram_pool = of_gen_pool_get(np, "iram", 0); - if (!drvdata->iram_pool) { - dev_err(&pdev->dev, "iram pool not available\n"); - ret = -ENOMEM; - goto err_dev; - } + if (!drvdata->iram_pool) + dev_warn(&pdev->dev, "no iram assigned, using external mem\n"); drvdata->devinfo = NULL; mxc_mlb150_irq_enable(drvdata, 0); |