static int omap_sr_probe()

in ti/smartreflex.c [818:938]


static int omap_sr_probe(struct platform_device *pdev)
{
	struct omap_sr *sr_info;
	struct omap_sr_data *pdata = pdev->dev.platform_data;
	struct resource *mem, *irq;
	struct dentry *nvalue_dir;
	int i, ret = 0;

	sr_info = devm_kzalloc(&pdev->dev, sizeof(struct omap_sr), GFP_KERNEL);
	if (!sr_info)
		return -ENOMEM;

	sr_info->name = devm_kzalloc(&pdev->dev,
				     SMARTREFLEX_NAME_LEN, GFP_KERNEL);
	if (!sr_info->name)
		return -ENOMEM;

	platform_set_drvdata(pdev, sr_info);

	if (!pdata) {
		dev_err(&pdev->dev, "%s: platform data missing\n", __func__);
		return -EINVAL;
	}

	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	sr_info->base = devm_ioremap_resource(&pdev->dev, mem);
	if (IS_ERR(sr_info->base))
		return PTR_ERR(sr_info->base);

	irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);

	sr_info->fck = devm_clk_get(pdev->dev.parent, "fck");
	if (IS_ERR(sr_info->fck))
		return PTR_ERR(sr_info->fck);
	clk_prepare(sr_info->fck);

	pm_runtime_enable(&pdev->dev);

	snprintf(sr_info->name, SMARTREFLEX_NAME_LEN, "%s", pdata->name);

	sr_info->pdev = pdev;
	sr_info->srid = pdev->id;
	sr_info->voltdm = pdata->voltdm;
	sr_info->nvalue_table = pdata->nvalue_table;
	sr_info->nvalue_count = pdata->nvalue_count;
	sr_info->senn_mod = pdata->senn_mod;
	sr_info->senp_mod = pdata->senp_mod;
	sr_info->err_weight = pdata->err_weight;
	sr_info->err_maxlimit = pdata->err_maxlimit;
	sr_info->accum_data = pdata->accum_data;
	sr_info->senn_avgweight = pdata->senn_avgweight;
	sr_info->senp_avgweight = pdata->senp_avgweight;
	sr_info->autocomp_active = false;
	sr_info->ip_type = pdata->ip_type;

	if (irq)
		sr_info->irq = irq->start;

	sr_set_clk_length(sr_info);

	list_add(&sr_info->node, &sr_list);

	/*
	 * Call into late init to do initializations that require
	 * both sr driver and sr class driver to be initiallized.
	 */
	if (sr_class) {
		ret = sr_late_init(sr_info);
		if (ret) {
			pr_warn("%s: Error in SR late init\n", __func__);
			goto err_list_del;
		}
	}

	dev_info(&pdev->dev, "%s: SmartReflex driver initialized\n", __func__);
	if (!sr_dbg_dir)
		sr_dbg_dir = debugfs_create_dir("smartreflex", NULL);

	sr_info->dbg_dir = debugfs_create_dir(sr_info->name, sr_dbg_dir);

	debugfs_create_file("autocomp", S_IRUGO | S_IWUSR, sr_info->dbg_dir,
			    sr_info, &pm_sr_fops);
	debugfs_create_x32("errweight", S_IRUGO, sr_info->dbg_dir,
			   &sr_info->err_weight);
	debugfs_create_x32("errmaxlimit", S_IRUGO, sr_info->dbg_dir,
			   &sr_info->err_maxlimit);

	nvalue_dir = debugfs_create_dir("nvalue", sr_info->dbg_dir);

	if (sr_info->nvalue_count == 0 || !sr_info->nvalue_table) {
		dev_warn(&pdev->dev, "%s: %s: No Voltage table for the corresponding vdd. Cannot create debugfs entries for n-values\n",
			 __func__, sr_info->name);

		ret = -ENODATA;
		goto err_debugfs;
	}

	for (i = 0; i < sr_info->nvalue_count; i++) {
		char name[NVALUE_NAME_LEN + 1];

		snprintf(name, sizeof(name), "volt_%lu",
				sr_info->nvalue_table[i].volt_nominal);
		debugfs_create_x32(name, S_IRUGO | S_IWUSR, nvalue_dir,
				   &(sr_info->nvalue_table[i].nvalue));
		snprintf(name, sizeof(name), "errminlimit_%lu",
			 sr_info->nvalue_table[i].volt_nominal);
		debugfs_create_x32(name, S_IRUGO | S_IWUSR, nvalue_dir,
				   &(sr_info->nvalue_table[i].errminlimit));

	}

	return ret;

err_debugfs:
	debugfs_remove_recursive(sr_info->dbg_dir);
err_list_del:
	list_del(&sr_info->node);
	clk_unprepare(sr_info->fck);

	return ret;
}