int tegra_bbc_proxy_bw_register(struct device *dev, u32 bw)
{
	int ret;
	struct tegra_bbc_proxy *bbc = dev_get_drvdata(dev);

	mutex_lock(&bbc->iso_lock);

	if (bbc->isomgr_handle)
		tegra_isomgr_unregister(bbc->isomgr_handle);

	bbc->isomgr_handle = tegra_isomgr_register(TEGRA_ISO_CLIENT_BBC_0,
		bw, NULL, NULL);
	ret = PTR_RET(bbc->isomgr_handle);
	if (ret) {
		dev_err(dev, "error registering bbc with isomgr\n");
		goto done;
	}

	ret = tegra_isomgr_set_margin(TEGRA_ISO_CLIENT_BBC_0,
		bw, true);
	if (ret) {
		dev_err(dev, "can't margin for bbc bw\n");
		tegra_isomgr_unregister(bbc->isomgr_handle);
		goto done;
	}
	else
		bbc->margin = bw;


	dev_dbg(dev, "bbc iso client registered\n");

done:
	mutex_unlock(&bbc->iso_lock);
	return ret;
}
int tegra_camera_isomgr_register(struct tegra_camera *camera)
{
	dev_dbg(camera->dev, "%s++\n", __func__);

	/* Dedicated bw is what VI could ask for at most */
	camera->isomgr_handle = tegra_isomgr_register(TEGRA_ISO_CLIENT_VI_0,
					/* dedicated bw, KBps*/
					tegra_camera_get_max_bw(camera),
					NULL,	/* tegra_isomgr_renegotiate */
					NULL);	/* *priv */
	if (!camera->isomgr_handle) {
		dev_err(camera->dev, "%s: unable to register isomgr\n",
					__func__);
		return -ENOMEM;
	}

	return 0;
}
struct tegra_camera *tegra_camera_register(struct platform_device *ndev)
{
	struct tegra_camera *camera = NULL;
	int ret = 0;
	int i;

	dev_info(&ndev->dev, "%s: ++\n", __func__);

	camera = kzalloc(sizeof(struct tegra_camera), GFP_KERNEL);
	if (!camera) {
		dev_err(&ndev->dev, "can't allocate memory for tegra_camera\n");
		return camera;
	}

	mutex_init(&camera->tegra_camera_lock);

	/* Powergate VE when boot */
	mutex_lock(&camera->tegra_camera_lock);
#ifndef CONFIG_ARCH_TEGRA_2x_SOC
	ret = tegra_camera_powergate_init(camera);
	if (ret)
		goto regulator_fail;
#endif
	mutex_unlock(&camera->tegra_camera_lock);

	camera->dev = &ndev->dev;

	/* Get regulator pointer */
#ifdef CONFIG_ARCH_TEGRA_2x_SOC
	camera->reg = regulator_get(&ndev->dev, "vcsi");
#else
	camera->reg = regulator_get(&ndev->dev, "avdd_dsi_csi");
#endif

	if (IS_ERR_OR_NULL(camera->reg)) {
		ret = -ENODEV;
		if (camera->reg == ERR_PTR(-ENODEV)) {
			camera->reg = NULL;
			dev_info(&ndev->dev,
				"%s: no regulator device, overriding\n",
							__func__);
		} else {
			dev_err(&ndev->dev, "%s: couldn't get regulator\n",
							__func__);
			goto regulator_fail;
		}
	}

	camera->misc_dev.minor = MISC_DYNAMIC_MINOR;
	camera->misc_dev.name = TEGRA_CAMERA_NAME;
	camera->misc_dev.fops = &tegra_camera_fops;
	camera->misc_dev.parent = &ndev->dev;
	ret = misc_register(&camera->misc_dev);
	if (ret) {
		dev_err(&ndev->dev, "%s: unable to register misc device!\n",
			TEGRA_CAMERA_NAME);
		goto misc_register_fail;
	}

	for (i = 0; i < CAMERA_CLK_MAX; i++) {
		ret = tegra_camera_clk_get(ndev, clock_init[i].name,
				&camera->clock[clock_init[i].index].clk);
		if (ret)
			goto clk_get_fail;
	}

#ifdef CONFIG_ARCH_TEGRA_11x_SOC
	/* Dedicated bw is what VI could ask for at most */
	camera->isomgr_handle = tegra_isomgr_register(TEGRA_ISO_CLIENT_VI_0,
					/* dedicated bw, KBps*/
					tegra_camera_get_max_bw(camera),
					NULL,	/* tegra_isomgr_renegotiate */
					NULL);	/* *priv */
	if (!camera->isomgr_handle) {
		dev_err(&ndev->dev, "%s: unable to register isomgr\n",
					__func__);
		goto clk_get_fail;
	}
#endif

	return camera;

clk_get_fail:
	for (; i > 0; i--)
		clk_put(camera->clock[clock_init[i].index].clk);
	misc_deregister(&camera->misc_dev);
misc_register_fail:
	regulator_put(camera->reg);
regulator_fail:
	kfree(camera);
	camera = NULL;
	return camera;
}
static int tegra_bbc_proxy_probe(struct platform_device *pdev)
{
	struct tegra_bbc_proxy_platform_data *pdata = pdev->dev.platform_data;
	struct tegra_bbc_proxy *bbc;
	struct edp_manager *mgr;
	struct device_attribute **attrs;
	struct device_attribute *attr;
	int ret = 0;

	/* check for platform data */
	if (!pdata) {
		dev_err(&pdev->dev, "platform data not available\n");
		return -ENODEV;
	}

	bbc = kzalloc(sizeof(struct tegra_bbc_proxy), GFP_KERNEL);
	if (!bbc) {
		dev_err(&pdev->dev, "failed to allocate memory\n");
		return -ENOMEM;
	}

	if (pdata->modem_boot_edp_client && pdata->edp_manager_name) {
		mutex_init(&bbc->edp_lock);

		/* register bbc boot client */
		bbc->edp_manager_name = pdata->edp_manager_name;
		mgr = edp_get_manager(pdata->edp_manager_name);
		if (!mgr) {
			dev_err(&pdev->dev, "can't get edp manager\n");
			/* goto error; */
			goto bypass_edp;
		}

		bbc->modem_boot_edp_client = pdata->modem_boot_edp_client;
		ret = edp_register_client(mgr, bbc->modem_boot_edp_client);
		if (ret) {
			dev_err(&pdev->dev,
				"unable to register bbc boot edp client\n");
			/* goto error; */
			goto bypass_edp;
		}

		/* request E0 */
		ret = edp_update_client_request(bbc->modem_boot_edp_client,
						0, NULL);
		if (ret) {
			dev_err(&pdev->dev,
				"unable to set e0 state\n");
			/* goto edp_req_error; */
			edp_unregister_client(bbc->modem_boot_edp_client);
			bbc->modem_boot_edp_client = NULL;
			goto bypass_edp;
		}

		bbc->edp_boot_client_registered = 1;

		attrs = edp_attributes;
		while ((attr = *attrs++)) {
			ret = device_create_file(&pdev->dev, attr);
			if (ret) {
				dev_err(&pdev->dev,
					"can't create sysfs file\n");
				//goto edp_req_error;

				edp_unregister_client(bbc->modem_boot_edp_client);
				bbc->modem_boot_edp_client = NULL;
				bbc->edp_boot_client_registered = 0;
				goto bypass_edp;
			}
		}

		bbc->edp_initialized = 1;
		bbc->ap_name = pdata->ap_name;
	}

bypass_edp:
	mutex_init(&bbc->iso_lock);

	bbc->isomgr_handle = tegra_isomgr_register(TEGRA_ISO_CLIENT_BBC_0,
		BBC_ISO_BOOT_BW, NULL, NULL);
	if (!bbc->isomgr_handle)
		goto iso_error;

	/* statically margin for bbc bw */
	ret = tegra_isomgr_set_margin(TEGRA_ISO_CLIENT_BBC_0,
		BBC_ISO_MARGIN_BW, true);
	if (ret)
		dev_err(&pdev->dev, "can't margin for bbc bw\n");
	else
		bbc->margin = BBC_ISO_MARGIN_BW;

	/* thermal zones from bbc */
	tegra_bbc_thermal_init();

	/* power values to bbc */
	tegra_bbc_power_init(pdev);

	attrs = mc_attributes;
	while ((attr = *attrs++)) {
		ret = device_create_file(&pdev->dev, attr);
		if (ret) {
			dev_err(&pdev->dev, "can't create sysfs file\n");
			goto mc_error;
		}
	}

	bbc->sim0 = regulator_get(&pdev->dev, "vddio_sim0");
	if (IS_ERR(bbc->sim0)) {
		dev_err(&pdev->dev, "vddio_sim0 regulator get failed\n");
		bbc->sim0 = NULL;
		goto sim_error;
	}

	bbc->sim1 = regulator_get(&pdev->dev, "vddio_sim1");
	if (IS_ERR(bbc->sim1)) {
		dev_err(&pdev->dev, "vddio_sim1 regulator get failed\n");
		bbc->sim1 = NULL;
		goto sim_error;
	}

	attrs = sim_attributes;
	while ((attr = *attrs++)) {
		ret = device_create_file(&pdev->dev, attr);
		if (ret) {
			dev_err(&pdev->dev, "can't create sysfs file\n");
			goto sim_error;
		}
	}

	bbc->rf1v7 = regulator_get(&pdev->dev, "vdd_1v7_rf");
	if (IS_ERR(bbc->rf1v7)) {
		dev_info(&pdev->dev,
			 "vdd_1v7_rf regulator not available\n");
		bbc->rf1v7 = NULL;
	}

	bbc->rf2v65 = regulator_get(&pdev->dev, "vdd_2v65_rf");
	if (IS_ERR(bbc->rf2v65)) {
		dev_info(&pdev->dev,
			 "vdd_2v65_rf regulator not available\n");
		bbc->rf2v65 = NULL;
	}

	if (bbc->rf1v7 && bbc->rf2v65) {
		attrs = rf_attributes;
		while ((attr = *attrs++)) {
			ret = device_create_file(&pdev->dev, attr);
			if (ret) {
				dev_err(&pdev->dev,
					"can't create sysfs file\n");
				goto rf_error;
			}
		}
	}

	bbc->bb_efuse = regulator_get(&pdev->dev, "vpp_bb_fuse");
	if (IS_ERR(bbc->bb_efuse)) {
		dev_info(&pdev->dev,
			 "vpp_bb_fuse regulator not available\n");
		bbc->bb_efuse = NULL;
	}

	atomic_set(&bbc->mode, 0);
	ret = device_create_file(&pdev->dev, &mode_attr);
	if (ret) {
		dev_err(&pdev->dev, "can't create sysfs file\n");
		goto mode_error;
	}

	/* set to -1 to ensure the mode gets programmed the first time */
	bbc->fpwm = -1;

	dev_set_drvdata(&pdev->dev, bbc);

	return 0;

mode_error:
	regulator_put(bbc->bb_efuse);
	attrs = rf_attributes;
	while ((attr = *attrs++))
		device_remove_file(&pdev->dev, attr);

rf_error:
	regulator_put(bbc->rf1v7);
	regulator_put(bbc->rf2v65);
sim_error:
	regulator_put(bbc->sim0);
	regulator_put(bbc->sim1);

	attrs = mc_attributes;
	while ((attr = *attrs++))
		device_remove_file(&pdev->dev, attr);

mc_error:
	tegra_isomgr_unregister(bbc->isomgr_handle);

iso_error:
	if (bbc->edp_initialized) {
		attrs = edp_attributes;
		while ((attr = *attrs++))
			device_remove_file(&pdev->dev, attr);
	}
#if 0
edp_req_error:
	if (bbc->edp_boot_client_registered)
		edp_unregister_client(bbc->modem_boot_edp_client);

error:
	kfree(bbc);
#endif
	return ret;
}
Example #5
0
static int tegra_bbc_proxy_probe(struct platform_device *pdev)
{
	struct tegra_bbc_proxy_platform_data *pdata = pdev->dev.platform_data;
	struct tegra_bbc_proxy *bbc;
	struct edp_manager *mgr;
	struct device_attribute **attrs;
	struct device_attribute *attr;
	int ret = 0;

	/* check for platform data */
	if (!pdata) {
		dev_err(&pdev->dev, "platform data not available\n");
		return -ENODEV;
	}

	bbc = kzalloc(sizeof(struct tegra_bbc_proxy), GFP_KERNEL);
	if (!bbc) {
		dev_err(&pdev->dev, "failed to allocate memory\n");
		return -ENOMEM;
	}

	if (pdata->modem_boot_edp_client && pdata->edp_manager_name) {
		mutex_init(&bbc->edp_lock);

		/* register bbc boot client */
		bbc->edp_manager_name = pdata->edp_manager_name;
		mgr = edp_get_manager(pdata->edp_manager_name);
		if (!mgr) {
			dev_err(&pdev->dev, "can't get edp manager\n");
			goto error;
		}

		bbc->modem_boot_edp_client = pdata->modem_boot_edp_client;
		ret = edp_register_client(mgr, bbc->modem_boot_edp_client);
		if (ret) {
			dev_err(&pdev->dev,
				"unable to register bbc boot edp client\n");
			goto error;
		}

		/* request E0 */
		ret = edp_update_client_request(bbc->modem_boot_edp_client,
						0, NULL);
		if (ret) {
			dev_err(&pdev->dev,
				"unable to set e0 state\n");
			goto edp_req_error;
		}

		bbc->edp_boot_client_registered = 1;

		bbc->i_breach_ppm = pdata->i_breach_ppm;
		bbc->i_thresh_3g_adjperiod = pdata->i_thresh_3g_adjperiod;
		bbc->i_thresh_lte_adjperiod = pdata->i_thresh_lte_adjperiod;

		attrs = edp_attributes;
		while ((attr = *attrs++)) {
			ret = device_create_file(&pdev->dev, attr);
			if (ret) {
				dev_err(&pdev->dev,
					"can't create sysfs file\n");
				goto edp_req_error;
			}
		}

		bbc->edp_initialized = 1;
		bbc->ap_name = pdata->ap_name;
	}

	mutex_init(&bbc->iso_lock);

	bbc->isomgr_handle = tegra_isomgr_register(TEGRA_ISO_CLIENT_BBC_0,
		MAX_ISO_BW_REQ, NULL, NULL);
	if (!bbc->isomgr_handle)
		goto iso_error;

	tegra_set_latency_allowance(TEGRA_LA_BBCLLR, 640);

	/* statically margin for bbc bw */
	ret = tegra_isomgr_set_margin(TEGRA_ISO_CLIENT_BBC_0,
		MAX_ISO_BW_REQ, true);
	if (ret)
		dev_err(&pdev->dev, "can't margin for bbc bw\n");
	else
		bbc->margin = MAX_ISO_BW_REQ;

	/* thermal zones from bbc */
	tegra_bbc_thermal_init();

	attrs = mc_attributes;
	while ((attr = *attrs++)) {
		ret = device_create_file(&pdev->dev, attr);
		if (ret) {
			dev_err(&pdev->dev, "can't create sysfs file\n");
			goto mc_error;
		}
	}

	bbc->sim0 = regulator_get(&pdev->dev, "vddio_sim0");
	if (IS_ERR(bbc->sim0)) {
		dev_err(&pdev->dev, "vddio_sim0 regulator get failed\n");
		bbc->sim0 = NULL;
		goto sim_error;
	}

	bbc->sim1 = regulator_get(&pdev->dev, "vddio_sim1");
	if (IS_ERR(bbc->sim1)) {
		dev_err(&pdev->dev, "vddio_sim1 regulator get failed\n");
		bbc->sim1 = NULL;
		goto sim_error;
	}

	attrs = sim_attributes;
	while ((attr = *attrs++)) {
		ret = device_create_file(&pdev->dev, attr);
		if (ret) {
			dev_err(&pdev->dev, "can't create sysfs file\n");
			goto sim_error;
		}
	}

	bbc->rf1v7 = regulator_get(&pdev->dev, "vdd_1v7_rf");
	if (IS_ERR(bbc->rf1v7)) {
		dev_info(&pdev->dev,
			 "vdd_1v7_rf regulator not available\n");
		bbc->rf1v7 = NULL;
	}

	bbc->rf2v65 = regulator_get(&pdev->dev, "vdd_2v65_rf");
	if (IS_ERR(bbc->rf2v65)) {
		dev_info(&pdev->dev,
			 "vdd_2v65_rf regulator not available\n");
		bbc->rf2v65 = NULL;
	}

	if (bbc->rf1v7 && bbc->rf2v65) {
		attrs = rf_attributes;
		while ((attr = *attrs++)) {
			ret = device_create_file(&pdev->dev, attr);
			if (ret) {
				dev_err(&pdev->dev,
					"can't create sysfs file\n");
				goto rf_error;
			}
		}
	}

	dev_set_drvdata(&pdev->dev, bbc);

	return 0;

rf_error:
	regulator_put(bbc->rf1v7);
	regulator_put(bbc->rf2v65);
sim_error:
	regulator_put(bbc->sim0);
	regulator_put(bbc->sim1);

	attrs = mc_attributes;
	while ((attr = *attrs++))
		device_remove_file(&pdev->dev, attr);

mc_error:
	tegra_isomgr_unregister(bbc->isomgr_handle);

iso_error:
	if (bbc->edp_initialized) {
		attrs = edp_attributes;
		while ((attr = *attrs++))
			device_remove_file(&pdev->dev, attr);
	}

edp_req_error:
	if (bbc->edp_boot_client_registered)
		edp_unregister_client(bbc->modem_boot_edp_client);

error:
	kfree(bbc);

	return ret;
}