diff options
author | Fancy Fang <chen.fang@nxp.com> | 2017-09-20 17:51:50 +0800 |
---|---|---|
committer | Leonard Crestez <leonard.crestez@nxp.com> | 2018-08-24 12:41:33 +0300 |
commit | f68b5233c82ab1d59e35383ad5b1f2f76ddf3005 (patch) | |
tree | 5fcb0964c05a23b1e7348295b820d837dfc23a76 /drivers/video | |
parent | 307d34e00e1a8061af4e2fd4316e931e6ccad747 (diff) |
MLK-16536-6 video: fbdev: dcss: split 'commit_to_fifo' into three parts
This commit split the function 'commit_to_fifo' into three
parts: 'alloc_cc()', 'commit_cfifo()' and 'flush_cfifo()'.
So that each of the three parts can be used as required,
but not used all together.
Signed-off-by: Fancy Fang <chen.fang@nxp.com>
Reviewed-by: Robby Cai <robby.cai@nxp.com>
Diffstat (limited to 'drivers/video')
-rw-r--r-- | drivers/video/fbdev/mxc/imx_dcss.c | 109 |
1 files changed, 78 insertions, 31 deletions
diff --git a/drivers/video/fbdev/mxc/imx_dcss.c b/drivers/video/fbdev/mxc/imx_dcss.c index cf948d8b5554..756076d80cfa 100644 --- a/drivers/video/fbdev/mxc/imx_dcss.c +++ b/drivers/video/fbdev/mxc/imx_dcss.c @@ -2317,8 +2317,34 @@ static void copy_data_to_cfifo(struct ctxld_fifo *cfifo, } } -static int commit_to_fifo(uint32_t channel, - struct dcss_info *info) +static struct ctxld_commit *alloc_cc(struct dcss_info *info) +{ + struct ctxld_commit *cc; + + cc = kzalloc(sizeof(*cc), GFP_KERNEL); + if (!cc) + return ERR_PTR(-ENOMEM); + + INIT_LIST_HEAD(&cc->list); + INIT_WORK(&cc->work, dcss_ctxld_config); + cc->data = info; + + return cc; +} + +static void flush_cfifo(struct ctxld_fifo *cfifo, + struct work_struct *work) +{ + int ret; + + ret = queue_work(cfifo->ctxld_wq, work); + + WARN(!ret, "work has already been queued\n"); +} + +static int commit_cfifo(uint32_t channel, + struct dcss_info *info, + struct ctxld_commit *cc) { int ret = 0; uint32_t commit_size; @@ -2326,17 +2352,8 @@ static int commit_to_fifo(uint32_t channel, struct dcss_channels *chans; struct dcss_channel_info *chan_info; struct ctxld_fifo *cfifo; - struct ctxld_commit *cc; struct cbuffer *cb; - if (channel > 2 || !info) - return -EINVAL; - - cc = (struct ctxld_commit *)kzalloc(sizeof(*cc), GFP_KERNEL); - if (!cc) - return -ENOMEM; - INIT_LIST_HEAD(&cc->list); - cfifo = &info->cfifo; chans = &info->chans; chan_info = &chans->chan_info[channel]; @@ -2381,11 +2398,6 @@ restart: spin_unlock(&cfifo->cqueue.lock); - /* queue the work to workqueue */ - cc->data = info; - INIT_WORK(&cc->work, dcss_ctxld_config); - queue_work(cfifo->ctxld_wq, &cc->work); - return 0; } @@ -2593,10 +2605,10 @@ static int dcss_set_par(struct fb_info *fbi) int fb_node = fbi->node; struct dcss_channel_info *cinfo = fbi->par; struct dcss_info *info = cinfo->dev_data; - struct platform_device *pdev = info->pdev; struct dcss_channels *chans = &info->chans; struct dcss_channel_info *chan_info; struct cbuffer *cb; + struct ctxld_commit *cc; if (fb_node < 0 || fb_node > 2) BUG_ON(1); @@ -2616,11 +2628,15 @@ static int dcss_set_par(struct fb_info *fbi) goto fail; #if USE_CTXLD - ret = commit_to_fifo(fb_node, info); - if (ret) { - dev_err(&pdev->dev, "commit config failed\n"); - goto out; + cc = alloc_cc(info); + if (IS_ERR(cc)) { + ret = PTR_ERR(cc); + goto fail; } + + commit_cfifo(fb_node, info, cc); + + flush_cfifo(&info->cfifo, &cc->work); #endif goto out; @@ -2684,21 +2700,37 @@ static int dcss_blank(int blank, struct fb_info *fbi) int fb_node = fbi->node; struct dcss_channel_info *cinfo = fbi->par; struct dcss_info *info = cinfo->dev_data; - struct platform_device *pdev = info->pdev; + struct cbuffer *cb; + struct ctxld_commit *cc; + + cb = &cinfo->cb; dtg_channel_timing_config(blank, cinfo); dcss_channel_blank(blank, cinfo); #if USE_CTXLD - ret = commit_to_fifo(fb_node, info); - if (ret) { - dev_err(&pdev->dev, "commit config failed\n"); - goto out; + cc = alloc_cc(info); + if (IS_ERR(cc)) { + ret = PTR_ERR(cc); + goto fail; } + + commit_cfifo(fb_node, info, cc); + + flush_cfifo(&info->cfifo, &cc->work); #endif cinfo->blank = blank; + goto out; + +fail: + /* drop any ctxld_uint already + * been written to sb or db + */ + cb->sb_data_len = 0; + cb->db_data_len = 0; + out: return ret; } @@ -2713,6 +2745,7 @@ static int dcss_pan_display(struct fb_var_screeninfo *var, struct platform_device *pdev = info->pdev; struct cbuffer *cb = &cinfo->cb; struct dcss_pixmap *input = &cinfo->input; + struct ctxld_commit *cc; /* TODO: change framebuffer memory start address */ luma_addr = var->reserved[0] ? var->reserved[0] : @@ -2742,18 +2775,32 @@ static int dcss_pan_display(struct fb_var_screeninfo *var, chroma_addr + (offset >> 1)); } - ret = commit_to_fifo(fbi->node, info); - if (ret) { - dev_err(&pdev->dev, "commit config failed\n"); - return ret; + cc = alloc_cc(info); + if (IS_ERR(cc)) { + ret = PTR_ERR(cc); + goto fail; } + commit_cfifo(fbi->node, info, cc); + + flush_cfifo(&info->cfifo, &cc->work); + /* TODO: blocking mode */ if (likely(!var->reserved[2])) /* make pan display synchronously */ flush_workqueue(info->cfifo.ctxld_wq); - return 0; + goto out; + +fail: + /* drop any ctxld_uint already + * been written to sb or db + */ + cb->sb_data_len = 0; + cb->db_data_len = 0; + +out: + return ret; } static int vcount_compare(unsigned long vcount, |