コード例 #1
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; */
			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;
}
コード例 #2
0
ファイル: tegra_bbc_proxy.c プロジェクト: Beta1440/Sublime-N9
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;
}