static int fimg2d_probe(struct platform_device *pdev) { int ret = 0; struct resource *res; struct fimg2d_platdata *pdata; #ifdef CONFIG_OF struct device *dev = &pdev->dev; int id = 0; #else pdata = to_fimg2d_plat(&pdev->dev); #endif dev_info(&pdev->dev, "++%s\n", __func__); #ifdef CONFIG_OF if (dev->of_node) { id = of_alias_get_id(pdev->dev.of_node, "fimg2d"); } else { id = pdev->id; pdata = dev->platform_data; if (!pdata) { dev_err(&pdev->dev, "no platform data\n"); return -EINVAL; } } #else if (!to_fimg2d_plat(&pdev->dev)) { fimg2d_err("failed to get platform data\n"); return -ENOMEM; } #endif /* global structure */ ctrl = kzalloc(sizeof(*ctrl), GFP_KERNEL); if (!ctrl) { fimg2d_err("failed to allocate memory for controller\n"); return -ENOMEM; } #ifdef CONFIG_OF pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); if (!pdata) { fimg2d_err("failed to allocate memory for controller\n"); kfree(ctrl); return -ENOMEM; } ctrl->pdata = pdata; g2d_parse_dt(dev->of_node, ctrl->pdata); #endif /* setup global ctrl */ ret = fimg2d_setup_controller(ctrl); if (ret) { fimg2d_err("failed to setup controller\n"); goto drv_free; } ctrl->dev = &pdev->dev; /* memory region */ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { fimg2d_err("failed to get resource\n"); ret = -ENOENT; goto drv_free; } ctrl->mem = request_mem_region(res->start, resource_size(res), pdev->name); if (!ctrl->mem) { fimg2d_err("failed to request memory region\n"); ret = -ENOMEM; goto drv_free; } /* ioremap */ ctrl->regs = ioremap(res->start, resource_size(res)); if (!ctrl->regs) { fimg2d_err("failed to ioremap for SFR\n"); ret = -ENOENT; goto mem_free; } fimg2d_debug("base address: 0x%lx\n", (unsigned long)res->start); /* irq */ ctrl->irq = platform_get_irq(pdev, 0); if (!ctrl->irq) { fimg2d_err("failed to get irq resource\n"); ret = -ENOENT; goto reg_unmap; } fimg2d_debug("irq: %d\n", ctrl->irq); ret = request_irq(ctrl->irq, fimg2d_irq, IRQF_DISABLED, pdev->name, ctrl); if (ret) { fimg2d_err("failed to request irq\n"); ret = -ENOENT; goto reg_unmap; } ret = fimg2d_clk_setup(ctrl); if (ret) { fimg2d_err("failed to setup clk\n"); ret = -ENOENT; goto irq_free; } spin_lock_init(&ctrl->qoslock); #ifdef CONFIG_PM_RUNTIME pm_runtime_enable(ctrl->dev); fimg2d_info("enable runtime pm\n"); #else fimg2d_clk_on(ctrl); #endif #ifdef FIMG2D_IOVMM_PAGETABLE exynos_create_iovmm(dev, 3, 3); #endif iovmm_set_fault_handler(dev, fimg2d_sysmmu_fault_handler, ctrl); fimg2d_debug("register sysmmu page fault handler\n"); /* misc register */ ret = misc_register(&fimg2d_dev); if (ret) { fimg2d_err("failed to register misc driver\n"); goto clk_release; } fimg2d_pm_qos_add(ctrl); dev_info(&pdev->dev, "fimg2d registered successfully\n"); return 0; clk_release: #ifdef CONFIG_PM_RUNTIME pm_runtime_disable(ctrl->dev); #else fimg2d_clk_off(ctrl); #endif fimg2d_clk_release(ctrl); irq_free: free_irq(ctrl->irq, NULL); reg_unmap: iounmap(ctrl->regs); mem_free: release_mem_region(res->start, resource_size(res)); drv_free: #ifdef BLIT_WORKQUE if (ctrl->work_q) destroy_workqueue(ctrl->work_q); #endif mutex_destroy(&ctrl->drvlock); #ifdef CONFIG_OF kfree(pdata); #endif kfree(ctrl); return ret; }
static int fimg2d_probe(struct platform_device *pdev) { int ret = 0; struct resource *res; struct fimg2d_platdata *pdata = to_fimg2d_plat(&pdev->dev); dev_info(&pdev->dev, "++%s\n", __func__); if (!to_fimg2d_plat(&pdev->dev)) { fimg2d_err("failed to get platform data\n"); return -ENOMEM; } /* global structure */ ctrl = kzalloc(sizeof(*ctrl), GFP_KERNEL); if (!ctrl) { fimg2d_err("failed to allocate memory for controller\n"); return -ENOMEM; } /* setup global ctrl */ ret = fimg2d_setup_controller(ctrl); if (ret) { fimg2d_err("failed to setup controller\n"); goto drv_free; } ctrl->dev = &pdev->dev; /* memory region */ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { fimg2d_err("failed to get resource\n"); ret = -ENOENT; goto drv_free; } ctrl->mem = request_mem_region(res->start, resource_size(res), pdev->name); if (!ctrl->mem) { fimg2d_err("failed to request memory region\n"); ret = -ENOMEM; goto drv_free; } /* ioremap */ ctrl->regs = ioremap(res->start, resource_size(res)); if (!ctrl->regs) { fimg2d_err("failed to ioremap for SFR\n"); ret = -ENOENT; goto mem_free; } fimg2d_debug("base address: 0x%lx\n", (unsigned long)res->start); /* irq */ ctrl->irq = platform_get_irq(pdev, 0); if (!ctrl->irq) { fimg2d_err("failed to get irq resource\n"); ret = -ENOENT; goto reg_unmap; } fimg2d_debug("irq: %d\n", ctrl->irq); ret = request_irq(ctrl->irq, fimg2d_irq, IRQF_DISABLED, pdev->name, ctrl); if (ret) { fimg2d_err("failed to request irq\n"); ret = -ENOENT; goto reg_unmap; } ret = fimg2d_clk_setup(ctrl); if (ret) { fimg2d_err("failed to setup clk\n"); ret = -ENOENT; goto irq_free; } #ifdef CONFIG_PM_RUNTIME pm_runtime_enable(ctrl->dev); fimg2d_info("enable runtime pm\n"); #endif g2d_cci_snoop_init(pdata->ip_ver); exynos_sysmmu_set_fault_handler(ctrl->dev, fimg2d_sysmmu_fault_handler); fimg2d_debug("register sysmmu page fault handler\n"); /* misc register */ ret = misc_register(&fimg2d_dev); if (ret) { fimg2d_err("failed to register misc driver\n"); goto clk_release; } fimg2d_pm_qos_add(ctrl); dev_info(&pdev->dev, "fimg2d registered successfully\n"); return 0; clk_release: g2d_cci_snoop_remove(pdata->ip_ver); #ifdef CONFIG_PM_RUNTIME pm_runtime_disable(ctrl->dev); #else fimg2d_clk_off(ctrl); #endif fimg2d_clk_release(ctrl); irq_free: free_irq(ctrl->irq, NULL); reg_unmap: iounmap(ctrl->regs); mem_free: release_mem_region(res->start, resource_size(res)); drv_free: #ifdef BLIT_WORKQUE if (ctrl->work_q) destroy_workqueue(ctrl->work_q); #endif mutex_destroy(&ctrl->drvlock); kfree(ctrl); return ret; }