static int cti_probe()

in coresight/coresight-cti-core.c [853:952]


static int cti_probe(struct amba_device *adev, const struct amba_id *id)
{
	int ret = 0;
	void __iomem *base;
	struct device *dev = &adev->dev;
	struct cti_drvdata *drvdata = NULL;
	struct coresight_desc cti_desc;
	struct coresight_platform_data *pdata = NULL;
	struct resource *res = &adev->res;

	/* driver data*/
	drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
	if (!drvdata)
		return -ENOMEM;

	/* Validity for the resource is already checked by the AMBA core */
	base = devm_ioremap_resource(dev, res);
	if (IS_ERR(base))
		return PTR_ERR(base);

	drvdata->base = base;
	cti_desc.access = CSDEV_ACCESS_IOMEM(base);

	dev_set_drvdata(dev, drvdata);

	/* default CTI device info  */
	drvdata->ctidev.cpu = -1;
	drvdata->ctidev.nr_trig_con = 0;
	drvdata->ctidev.ctm_id = 0;
	INIT_LIST_HEAD(&drvdata->ctidev.trig_cons);

	spin_lock_init(&drvdata->spinlock);

	/* initialise CTI driver config values */
	cti_set_default_config(dev, drvdata);

	pdata = coresight_cti_get_platform_data(dev);
	if (IS_ERR(pdata)) {
		dev_err(dev, "coresight_cti_get_platform_data err\n");
		return  PTR_ERR(pdata);
	}

	/* default to powered - could change on PM notifications */
	drvdata->config.hw_powered = true;

	/* set up device name - will depend if cpu bound or otherwise */
	if (drvdata->ctidev.cpu >= 0)
		cti_desc.name = devm_kasprintf(dev, GFP_KERNEL, "cti_cpu%d",
					       drvdata->ctidev.cpu);
	else
		cti_desc.name = coresight_alloc_device_name(&cti_sys_devs, dev);
	if (!cti_desc.name)
		return -ENOMEM;

	/* setup CPU power management handling for CPU bound CTI devices. */
	ret = cti_pm_setup(drvdata);
	if (ret)
		return ret;

	/* create dynamic attributes for connections */
	ret = cti_create_cons_sysfs(dev, drvdata);
	if (ret) {
		dev_err(dev, "%s: create dynamic sysfs entries failed\n",
			cti_desc.name);
		goto pm_release;
	}

	/* set up coresight component description */
	cti_desc.pdata = pdata;
	cti_desc.type = CORESIGHT_DEV_TYPE_ECT;
	cti_desc.subtype.ect_subtype = CORESIGHT_DEV_SUBTYPE_ECT_CTI;
	cti_desc.ops = &cti_ops;
	cti_desc.groups = drvdata->ctidev.con_groups;
	cti_desc.dev = dev;
	drvdata->csdev = coresight_register(&cti_desc);
	if (IS_ERR(drvdata->csdev)) {
		ret = PTR_ERR(drvdata->csdev);
		goto pm_release;
	}

	/* add to list of CTI devices */
	mutex_lock(&ect_mutex);
	list_add(&drvdata->node, &ect_net);
	/* set any cross references */
	cti_update_conn_xrefs(drvdata);
	mutex_unlock(&ect_mutex);

	/* set up release chain */
	drvdata->csdev_release = drvdata->csdev->dev.release;
	drvdata->csdev->dev.release = cti_device_release;

	/* all done - dec pm refcount */
	pm_runtime_put(&adev->dev);
	dev_info(&drvdata->csdev->dev, "CTI initialized\n");
	return 0;

pm_release:
	cti_pm_release(drvdata);
	return ret;
}