From 41616ea46a5c0d56bd7201c8860f3944d85aaca1 Mon Sep 17 00:00:00 2001 From: "hyesoo.yu" Date: Fri, 7 Jul 2017 11:35:16 +0900 Subject: [PATCH] [COMMON] g2d: add fimg2d node The user that opens "fimg2d" has permission 0x666, so this user doesn't have authority to request priority or performance, because the user that has high authority should not be disturbed by lower authority user. Change-Id: Ie9af31be60d7d2d80df3fdae561547d8db82440c Signed-off-by: hyesoo.yu --- drivers/gpu/exynos/g2d/g2d.h | 5 +++- drivers/gpu/exynos/g2d/g2d_drv.c | 48 ++++++++++++++++++++++++++------ 2 files changed, 43 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/exynos/g2d/g2d.h b/drivers/gpu/exynos/g2d/g2d.h index 9adae81d3d96..9e1a5a7a7e0a 100644 --- a/drivers/gpu/exynos/g2d/g2d.h +++ b/drivers/gpu/exynos/g2d/g2d.h @@ -63,7 +63,7 @@ struct g2d_dvfs_table { struct g2d_device { unsigned long state; - struct miscdevice misc; + struct miscdevice misc[2]; struct device *dev; struct clk *clock; void __iomem *reg; @@ -98,10 +98,13 @@ struct g2d_device { u32 dvfs_table_cnt; }; +#define G2D_AUTHORITY_HIGHUSER 1 + struct g2d_context { struct g2d_device *g2d_dev; struct shared_buffer_info *hwfc_info; u32 priority; + int authority; struct pm_qos_request req; diff --git a/drivers/gpu/exynos/g2d/g2d_drv.c b/drivers/gpu/exynos/g2d/g2d_drv.c index fb23f73cb490..eb93763c6b6e 100644 --- a/drivers/gpu/exynos/g2d/g2d_drv.c +++ b/drivers/gpu/exynos/g2d/g2d_drv.c @@ -237,14 +237,21 @@ static __u32 get_hw_version(struct g2d_device *g2d_dev, __u32 *version) static int g2d_open(struct inode *inode, struct file *filp) { - struct g2d_device *g2d_dev = container_of(filp->private_data, - struct g2d_device, misc); + struct g2d_device *g2d_dev; struct g2d_context *g2d_ctx; + struct miscdevice *misc = filp->private_data; g2d_ctx = kzalloc(sizeof(*g2d_ctx), GFP_KERNEL); if (!g2d_ctx) return -ENOMEM; + if (!strcmp(misc->name, "g2d")) { + g2d_dev = container_of(misc, struct g2d_device, misc[0]); + g2d_ctx->authority = G2D_AUTHORITY_HIGHUSER; + } else { + g2d_dev = container_of(misc, struct g2d_device, misc[1]); + } + filp->private_data = g2d_ctx; g2d_ctx->g2d_dev = g2d_dev; @@ -371,6 +378,11 @@ static long g2d_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { enum g2d_priority data; + if (!(ctx->authority & G2D_AUTHORITY_HIGHUSER)) { + ret = -EPERM; + break; + } + if (copy_from_user(&data, (void __user *)arg, sizeof(data))) { dev_err(g2d_dev->dev, "%s: Failed to get priority\n", __func__); @@ -393,6 +405,11 @@ static long g2d_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { struct g2d_performance_data data; + if (!(ctx->authority & G2D_AUTHORITY_HIGHUSER)) { + ret = -EPERM; + break; + } + if (copy_from_user(&data, (void __user *)arg, sizeof(data))) { dev_err(g2d_dev->dev, "%s: Failed to read perf data\n", __func__); @@ -761,17 +778,27 @@ static int g2d_probe(struct platform_device *pdev) if (ret < 0) goto err; - g2d_dev->misc.minor = MISC_DYNAMIC_MINOR; - g2d_dev->misc.name = "g2d"; - g2d_dev->misc.fops = &g2d_fops; + g2d_dev->misc[0].minor = MISC_DYNAMIC_MINOR; + g2d_dev->misc[0].name = "g2d"; + g2d_dev->misc[0].fops = &g2d_fops; /* misc register */ - ret = misc_register(&g2d_dev->misc); + ret = misc_register(&g2d_dev->misc[0]); if (ret) { - dev_err(&pdev->dev, "Failed to register misc device"); + dev_err(&pdev->dev, "Failed to register misc device for 0"); goto err; } + g2d_dev->misc[1].minor = MISC_DYNAMIC_MINOR; + g2d_dev->misc[1].name = "fimg2d"; + g2d_dev->misc[1].fops = &g2d_fops; + + ret = misc_register(&g2d_dev->misc[1]); + if (ret) { + dev_err(&pdev->dev, "Failed to register misc device for 1"); + goto err_misc; + } + spin_lock_init(&g2d_dev->lock_task); INIT_LIST_HEAD(&g2d_dev->tasks_free); @@ -806,7 +833,9 @@ static int g2d_probe(struct platform_device *pdev) err_pm: g2d_destroy_tasks(g2d_dev); err_task: - misc_deregister(&g2d_dev->misc); + misc_deregister(&g2d_dev->misc[1]); +err_misc: + misc_deregister(&g2d_dev->misc[0]); err: pm_runtime_disable(&pdev->dev); iovmm_deactivate(g2d_dev->dev); @@ -841,7 +870,8 @@ static int g2d_remove(struct platform_device *pdev) g2d_destroy_tasks(g2d_dev); - misc_deregister(&g2d_dev->misc); + misc_deregister(&g2d_dev->misc[0]); + misc_deregister(&g2d_dev->misc[1]); pm_runtime_disable(&pdev->dev); -- 2.20.1