static int jpeg_probe(struct platform_device *pdev) { struct jpeg_dev *jpeg; struct resource *res; int i, ret; jpeg = devm_kzalloc(&pdev->dev, sizeof(struct jpeg_dev), GFP_KERNEL); if (!jpeg) { dev_err(&pdev->dev, "%s: not enough memory\n", __func__); return -ENOMEM; } ret = of_property_read_u32(pdev->dev.of_node, "ip_ver", &jpeg->ver); if (ret) { dev_err(&pdev->dev, "%s: ip_ver doesn't exist\n", __func__); return -EINVAL; } jpeg->dev = &pdev->dev; spin_lock_init(&jpeg->slock); /* Get memory resource and map SFR region. */ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); jpeg->regs = devm_request_and_ioremap(&pdev->dev, res); if (jpeg->regs == NULL) { dev_err(&pdev->dev, "failed to claim register region\n"); return -ENOENT; } /* Get IRQ resource and register IRQ handler. */ res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (!res) { dev_err(&pdev->dev, "failed to get IRQ resource\n"); return -ENXIO; } /* Get memory resource and map SFR region. */ ret = devm_request_irq(&pdev->dev, res->start, (void *)jpeg_irq_handler, 0, pdev->name, jpeg); if (ret) { dev_err(&pdev->dev, "failed to install irq\n"); return ret; } /* clock */ for (i = 0; i < JPEG_CLK_NUM; i++) jpeg->clocks[i] = ERR_PTR(-ENOENT); ret = jpeg_clk_get(jpeg); if (ret) return ret; jpeg->oneshot_dev = m2m1shot_create_device(&pdev->dev, &jpeg_oneshot_ops, "jpeg", pdev->id, -1); if (IS_ERR(jpeg->oneshot_dev)) { pr_err("%s: Failed to create m2m1shot device\n", __func__); ret = PTR_ERR(jpeg->oneshot_dev); goto err_m2m1shot; } platform_set_drvdata(pdev, jpeg); ret = exynos_create_iovmm(&pdev->dev, 3, 3); if (ret) { dev_err(&pdev->dev, "%s: Failed(%d) to create IOVMM\n", __func__, ret); goto err_iovmm; } ret = iovmm_activate(&pdev->dev); if (ret) { dev_err(&pdev->dev, "%s: Failed(%d) to activate IOVMM\n", __func__, ret); /* nothing to do for exynos_create_iovmm() */ goto err_iovmm; } iovmm_set_fault_handler(&pdev->dev, jpeg_sysmmu_fault_handler, jpeg); pm_runtime_enable(&pdev->dev); if (!IS_ENABLED(CONFIG_PM_RUNTIME)) { jpeg_clock_gating(jpeg, true); set_bit(DEV_RUNTIME_RESUME, &jpeg->state); } dev_info(&pdev->dev, "JPEG driver register successfully"); return 0; err_iovmm: m2m1shot_destroy_device(jpeg->oneshot_dev); err_m2m1shot: jpeg_clk_put(jpeg); return ret; }
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; }
int __devinit mxr_acquire_video(struct mxr_device *mdev, struct mxr_output_conf *output_conf, int output_count) { int i; int ret = 0; struct v4l2_subdev *sd; struct s5p_mxr_platdata *pdata = mdev->pdata; mdev->alloc_ctx = mdev->vb2->init(mdev); if (IS_ERR_OR_NULL(mdev->alloc_ctx)) { mxr_err(mdev, "could not acquire vb2 allocator\n"); ret = PTR_ERR(mdev->alloc_ctx); goto fail; } if (is_ip_ver_5r) { exynos_create_iovmm(mdev->dev, 1, 0); iovmm_reserve(mdev->dev, MXR_VA, MXR_VA); } else { exynos_create_iovmm(mdev->dev, 3, 0); } /* registering outputs */ mdev->output_cnt = 0; for (i = 0; i < output_count; ++i) { struct mxr_output_conf *conf = &output_conf[i]; struct mxr_output *out; /* find subdev of output devices */ sd = (struct v4l2_subdev *) module_name_to_driver_data(conf->module_name); /* trying to register next output */ if (sd == NULL) continue; out = kzalloc(sizeof *out, GFP_KERNEL); if (out == NULL) { mxr_err(mdev, "no memory for '%s'\n", conf->output_name); ret = -ENOMEM; /* registered subdevs are removed in fail_v4l2_dev */ goto fail_output; } strlcpy(out->name, conf->output_name, sizeof(out->name)); out->sd = sd; out->cookie = conf->cookie; mdev->output[mdev->output_cnt++] = out; mxr_info(mdev, "added output '%s' from module '%s'\n", conf->output_name, conf->module_name); /* checking if maximal number of outputs is reached */ if (mdev->output_cnt >= MXR_MAX_OUTPUTS) break; } if (mdev->output_cnt == 0) { mxr_err(mdev, "failed to register any output\n"); ret = -ENODEV; /* skipping fail_output because there is nothing to free */ goto fail_vb2_allocator; } return 0; fail_output: /* kfree is NULL-safe */ for (i = 0; i < mdev->output_cnt; ++i) kfree(mdev->output[i]); memset(mdev->output, 0, sizeof mdev->output); fail_vb2_allocator: /* freeing allocator context */ mdev->vb2->cleanup(mdev->alloc_ctx); fail: return ret; }