| @@ -1205,18 +1205,18 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_get_of_node); · 1204 unmodified lines |
| 1205 | | 1205 | |
| 1206 | /* | 1206 | /* |
| 1207 | * Callback function provided to the Energy Model framework upon registration. | 1207 | * Callback function provided to the Energy Model framework upon registration. |
| 1208 | * This computes the power estimated by @CPU at @kHz if it is the frequency | 1208 | * This computes the power estimated by @dev at @kHz if it is the frequency |
| 1209 | * of an existing OPP, or at the frequency of the first OPP above @kHz otherwise | 1209 | * of an existing OPP, or at the frequency of the first OPP above @kHz otherwise |
| 1210 | * (see dev_pm_opp_find_freq_ceil()). This function updates @kHz to the ceiled | 1210 | * (see dev_pm_opp_find_freq_ceil()). This function updates @kHz to the ceiled |
| 1211 | * frequency and @mW to the associated power. The power is estimated as | 1211 | * frequency and @mW to the associated power. The power is estimated as |
| 1212 | * P = C * V^2 * f with C being the CPU's capacitance and V and f respectively | 1212 | * P = C * V^2 * f with C being the device's capacitance and V and f |
| 1213 | * the voltage and frequency of the OPP. | 1213 | * respectively the voltage and frequency of the OPP. |
| 1214 | * | 1214 | * |
| 1215 | * Returns -ENODEV if the CPU device cannot be found, -EINVAL if the power | 1215 | * Returns -EINVAL if the power calculation failed because of missing |
| 1216 | * calculation failed because of missing parameters, 0 otherwise. | 1216 | * parameters, 0 otherwise. |
| 1217 | */ | 1217 | */ |
| 1218 | static int __maybe_unused _get_cpu_power(unsigned long *mW, unsigned long *kHz, | 1218 | static int __maybe_unused _get_power(unsigned long *mW, unsigned long *kHz, |
| 1219 | struct device *cpu_dev) | 1219 | struct device *dev) |
| 1220 | { | 1220 | { |
| 1221 | struct dev_pm_opp *opp; | 1221 | struct dev_pm_opp *opp; |
| 1222 | struct device_node *np; | 1222 | struct device_node *np; |
| @@ -1225,7 +1225,7 @@ static int __maybe_unused _get_cpu_power(unsigned long *mW, unsigned long *kHz, · 2 unmodified lines |
| 1225 | u64 tmp; | 1225 | u64 tmp; |
| 1226 | int ret; | 1226 | int ret; |
| 1227 | | 1227 | |
| 1228 | np = of_node_get(cpu_dev->of_node); | 1228 | np = of_node_get(dev->of_node); |
| 1229 | if (!np) | 1229 | if (!np) |
| 1230 | return -EINVAL; | 1230 | return -EINVAL; |
| 1231 | | 1231 | |
| @@ -1235,7 +1235,7 @@ static int __maybe_unused _get_cpu_power(unsigned long *mW, unsigned long *kHz, · 3 unmodified lines |
| 1235 | return -EINVAL; | 1235 | return -EINVAL; |
| 1236 | | 1236 | |
| 1237 | Hz = *kHz * 1000; | 1237 | Hz = *kHz * 1000; |
| 1238 | opp = dev_pm_opp_find_freq_ceil(cpu_dev, &Hz); | 1238 | opp = dev_pm_opp_find_freq_ceil(dev, &Hz); |
| 1239 | if (IS_ERR(opp)) | 1239 | if (IS_ERR(opp)) |
| 1240 | return -EINVAL; | 1240 | return -EINVAL; |
| 1241 | | 1241 | |
| @@ -1255,30 +1255,38 @@ static int __maybe_unused _get_cpu_power(unsigned long *mW, unsigned long *kHz, · 13 unmodified lines |
| 1255 | | 1255 | |
| 1256 | /** | 1256 | /** |
| 1257 | * dev_pm_opp_of_register_em() - Attempt to register an Energy Model | 1257 | * dev_pm_opp_of_register_em() - Attempt to register an Energy Model |
| 1258 | * @cpus : CPUs for which an Energy Model has to be registered | 1258 | * @dev : Device for which an Energy Model has to be registered |
| | 1259 | * @cpus : CPUs for which an Energy Model has to be registered. For |
| | 1260 | * other type of devices it should be set to NULL. |
| 1259 | * | 1261 | * |
| 1260 | * This checks whether the "dynamic-power-coefficient" devicetree property has | 1262 | * This checks whether the "dynamic-power-coefficient" devicetree property has |
| 1261 | * been specified, and tries to register an Energy Model with it if it has. | 1263 | * been specified, and tries to register an Energy Model with it if it has. |
| | 1264 | * Having this property means the voltages are known for OPPs and the EM |
| | 1265 | * might be calculated. |
| 1262 | */ | 1266 | */ |
| 1263 | void dev_pm_opp_of_register_em(struct cpumask *cpus) | 1267 | int dev_pm_opp_of_register_em(struct device *dev, struct cpumask *cpus) |
| 1264 | { | 1268 | { |
| 1265 | struct em_data_callback em_cb = EM_DATA_CB(_get_cpu_power); | 1269 | struct em_data_callback em_cb = EM_DATA_CB(_get_power); |
| 1266 | int ret, nr_opp, cpu = cpumask_first(cpus); | | |
| 1267 | struct device *cpu_dev; | | |
| 1268 | struct device_node *np; | 1270 | struct device_node *np; |
| | 1271 | int ret, nr_opp; |
| 1269 | u32 cap; | 1272 | u32 cap; |
| 1270 | | 1273 | |
| 1271 | cpu_dev = get_cpu_device(cpu); | 1274 | if (IS_ERR_OR_NULL(dev)) { |
| 1272 | if (!cpu_dev) | 1275 | ret = -EINVAL; |
| 1273 | return; | 1276 | goto failed; |
| | 1277 | } |
| 1274 | | 1278 | |
| 1275 | nr_opp = dev_pm_opp_get_opp_count(cpu_dev); | 1279 | nr_opp = dev_pm_opp_get_opp_count(dev); |
| 1276 | if (nr_opp <= 0) | 1280 | if (nr_opp <= 0) { |
| 1277 | return; | 1281 | ret = -EINVAL; |
| | 1282 | goto failed; |
| | 1283 | } |
| 1278 | | 1284 | |
| 1279 | np = of_node_get(cpu_dev->of_node); | 1285 | np = of_node_get(dev->of_node); |
| 1280 | if (!np) | 1286 | if (!np) { |
| 1281 | return; | 1287 | ret = -EINVAL; |
| | 1288 | goto failed; |
| | 1289 | } |
| 1282 | | 1290 | |
| 1283 | /* | 1291 | /* |
| 1284 | * Register an EM only if the 'dynamic-power-coefficient' property is | 1292 | * Register an EM only if the 'dynamic-power-coefficient' property is |
| @@ -1289,9 +1297,20 @@ void dev_pm_opp_of_register_em(struct cpumask *cpus) · 4 unmodified lines |
| 1289 | */ | 1297 | */ |
| 1290 | ret = of_property_read_u32(np, "dynamic-power-coefficient", &cap); | 1298 | ret = of_property_read_u32(np, "dynamic-power-coefficient", &cap); |
| 1291 | of_node_put(np); | 1299 | of_node_put(np); |
| 1292 | if (ret || !cap) | 1300 | if (ret || !cap) { |
| 1293 | return; | 1301 | dev_dbg(dev, "Couldn't find proper 'dynamic-power-coefficient' in DT\n"); |
| | 1302 | ret = -EINVAL; |
| | 1303 | goto failed; |
| | 1304 | } |
| 1294 | | 1305 | |
| 1295 | em_dev_register_perf_domain(cpu_dev, nr_opp, &em_cb, cpus); | 1306 | ret = em_dev_register_perf_domain(dev, nr_opp, &em_cb, cpus); |
| | 1307 | if (ret) |
| | 1308 | goto failed; |
| | 1309 | |
| | 1310 | return 0; |
| | 1311 | |
| | 1312 | failed: |
| | 1313 | dev_dbg(dev, "Couldn't register Energy Model %d\n", ret); |
| | 1314 | return ret; |
| 1296 | } | 1315 | } |
| 1297 | EXPORT_SYMBOL_GPL(dev_pm_opp_of_register_em); | 1316 | EXPORT_SYMBOL_GPL(dev_pm_opp_of_register_em); |