Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

OPP: Remove genpd_virt_dev_lock

All the config operations for OPP tables share common code paths now and
none of the other ones have such protection in place. Either all should
have it or none.

The understanding here is that user won't clear the OPP configs while
still using them and so such a case won't happen. We can always come
back and use a wider lock for all resource types if required.

Also fix the error on failing to allocate memory.

Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>

+6 -35
+6 -33
drivers/opp/core.c
··· 1076 1076 { 1077 1077 struct device **genpd_virt_devs = 1078 1078 opp_table->genpd_virt_devs ? opp_table->genpd_virt_devs : &dev; 1079 - int index, target, delta, ret = 0; 1079 + int index, target, delta, ret; 1080 1080 1081 1081 /* Scaling up? Set required OPPs in normal order, else reverse */ 1082 1082 if (!scaling_down) { ··· 1089 1089 delta = -1; 1090 1090 } 1091 1091 1092 - /* 1093 - * Acquire genpd_virt_dev_lock to make sure we don't use a genpd_dev 1094 - * after it is freed from another thread. 1095 - */ 1096 - mutex_lock(&opp_table->genpd_virt_dev_lock); 1097 - 1098 1092 while (index != target) { 1099 1093 ret = _set_performance_state(dev, genpd_virt_devs[index], opp, index); 1100 1094 if (ret) 1101 - break; 1095 + return ret; 1102 1096 1103 1097 index += delta; 1104 1098 } 1105 1099 1106 - mutex_unlock(&opp_table->genpd_virt_dev_lock); 1107 - 1108 - return ret; 1100 + return 0; 1109 1101 } 1110 1102 1111 1103 /* This is only called for PM domain for now */ ··· 1466 1474 return ERR_PTR(-ENOMEM); 1467 1475 1468 1476 mutex_init(&opp_table->lock); 1469 - mutex_init(&opp_table->genpd_virt_dev_lock); 1470 1477 INIT_LIST_HEAD(&opp_table->dev_list); 1471 1478 INIT_LIST_HEAD(&opp_table->lazy); 1472 1479 ··· 1501 1510 remove_opp_dev: 1502 1511 _of_clear_opp_table(opp_table); 1503 1512 _remove_opp_dev(opp_dev, opp_table); 1504 - mutex_destroy(&opp_table->genpd_virt_dev_lock); 1505 1513 mutex_destroy(&opp_table->lock); 1506 1514 err: 1507 1515 kfree(opp_table); ··· 1668 1678 list_for_each_entry_safe(opp_dev, temp, &opp_table->dev_list, node) 1669 1679 _remove_opp_dev(opp_dev, opp_table); 1670 1680 1671 - mutex_destroy(&opp_table->genpd_virt_dev_lock); 1672 1681 mutex_destroy(&opp_table->lock); 1673 1682 kfree(opp_table); 1674 1683 } ··· 2384 2395 opp_table->config_regulators = NULL; 2385 2396 } 2386 2397 2387 - static void _detach_genpd(struct opp_table *opp_table) 2398 + static void _opp_detach_genpd(struct opp_table *opp_table) 2388 2399 { 2389 2400 int index; 2390 2401 ··· 2438 2449 if (!opp_table->required_opp_count) 2439 2450 return -EPROBE_DEFER; 2440 2451 2441 - mutex_lock(&opp_table->genpd_virt_dev_lock); 2442 - 2443 2452 opp_table->genpd_virt_devs = kcalloc(opp_table->required_opp_count, 2444 2453 sizeof(*opp_table->genpd_virt_devs), 2445 2454 GFP_KERNEL); 2446 2455 if (!opp_table->genpd_virt_devs) 2447 - goto unlock; 2456 + return -ENOMEM; 2448 2457 2449 2458 while (*name) { 2450 2459 if (index >= opp_table->required_opp_count) { ··· 2465 2478 2466 2479 if (virt_devs) 2467 2480 *virt_devs = opp_table->genpd_virt_devs; 2468 - mutex_unlock(&opp_table->genpd_virt_dev_lock); 2469 2481 2470 2482 return 0; 2471 2483 2472 2484 err: 2473 - _detach_genpd(opp_table); 2474 - unlock: 2475 - mutex_unlock(&opp_table->genpd_virt_dev_lock); 2485 + _opp_detach_genpd(opp_table); 2476 2486 return ret; 2477 2487 2478 - } 2479 - 2480 - static void _opp_detach_genpd(struct opp_table *opp_table) 2481 - { 2482 - /* 2483 - * Acquire genpd_virt_dev_lock to make sure virt_dev isn't getting 2484 - * used in parallel. 2485 - */ 2486 - mutex_lock(&opp_table->genpd_virt_dev_lock); 2487 - _detach_genpd(opp_table); 2488 - mutex_unlock(&opp_table->genpd_virt_dev_lock); 2489 2488 } 2490 2489 2491 2490 static void _opp_clear_config(struct opp_config_data *data)
-2
drivers/opp/opp.h
··· 160 160 * @rate_clk_single: Currently configured frequency for single clk. 161 161 * @current_opp: Currently configured OPP for the table. 162 162 * @suspend_opp: Pointer to OPP to be used during device suspend. 163 - * @genpd_virt_dev_lock: Mutex protecting the genpd virtual device pointers. 164 163 * @genpd_virt_devs: List of virtual devices for multiple genpd support. 165 164 * @required_opp_tables: List of device OPP tables that are required by OPPs in 166 165 * this table. ··· 211 212 struct dev_pm_opp *current_opp; 212 213 struct dev_pm_opp *suspend_opp; 213 214 214 - struct mutex genpd_virt_dev_lock; 215 215 struct device **genpd_virt_devs; 216 216 struct opp_table **required_opp_tables; 217 217 unsigned int required_opp_count;