Esempio n. 1
0
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;
}
Esempio n. 2
0
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;
}