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; }
static int bbc_bw_request_unlocked(struct device *dev, u32 mode, u32 bw, u32 lt, u32 margin) { int ret; u32 dvfs_latency; struct tegra_bbc_proxy *bbc = dev_get_drvdata(dev); dev_dbg(dev, "bbc iso request - bw: %u lt: %u margin: %u mode: %u\n", bw, lt, margin, mode); if (bw > MAX_ISO_BW_REQ) return -EINVAL; if (margin > MAX_ISO_BW_REQ) return -EINVAL; if (mode) atomic_set(&bbc->mode, mode); if ((bw != bbc->bw) || (lt != bbc->lt)) { dvfs_latency = tegra_isomgr_reserve(bbc->isomgr_handle, bw, lt); if (!dvfs_latency) { dev_err(dev, "can't reserve iso bw\n"); return -EINVAL; } bbc->bw = bw; dvfs_latency = tegra_isomgr_realize(bbc->isomgr_handle); if (!dvfs_latency) { dev_err(dev, "can't realize iso bw\n"); return -EINVAL; } bbc->lt = lt; } if (margin != bbc->margin) { ret = tegra_isomgr_set_margin(TEGRA_ISO_CLIENT_BBC_0, margin, true); if (ret) { dev_err(dev, "can't margin for bbc bw\n"); return ret; } bbc->margin = margin; } return 0; }
static int bbc_bw_request_unlocked(struct device *dev, u32 mode, u32 bw, u32 lt, u32 margin) { int ret; struct tegra_bbc_proxy *bbc = dev_get_drvdata(dev); if (bw > MAX_ISO_BW_REQ) return -EINVAL; if (margin > MAX_ISO_BW_REQ) return -EINVAL; if (margin != bbc->margin) { ret = tegra_isomgr_set_margin(TEGRA_ISO_CLIENT_BBC_0, margin, true); if (ret) { dev_err(dev, "can't margin for bbc bw\n"); return ret; } bbc->margin = margin; } if ((bw != bbc->bw) || (lt != bbc->lt)) { ret = tegra_isomgr_reserve(bbc->isomgr_handle, bw, lt); if (!ret) { dev_err(dev, "can't reserve iso bw\n"); return ret; } bbc->bw = bw; ret = tegra_isomgr_realize(bbc->isomgr_handle); if (!ret) { dev_err(dev, "can't realize iso bw\n"); return ret; } bbc->lt = lt; tegra_set_latency_allowance(TEGRA_LA_BBCR, bw / 1000); tegra_set_latency_allowance(TEGRA_LA_BBCW, bw / 1000); } return 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; }
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; }