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

Merge branch 'pm-opp' into pm-cpufreq

+75 -42
+75 -42
drivers/base/power/opp.c
··· 84 84 * 85 85 * This is an internal data structure maintaining the link to opps attached to 86 86 * a device. This structure is not meant to be shared to users as it is 87 - * meant for book keeping and private to OPP library 87 + * meant for book keeping and private to OPP library. 88 + * 89 + * Because the opp structures can be used from both rcu and srcu readers, we 90 + * need to wait for the grace period of both of them before freeing any 91 + * resources. And so we have used kfree_rcu() from within call_srcu() handlers. 88 92 */ 89 93 struct device_opp { 90 94 struct list_head node; ··· 107 103 static LIST_HEAD(dev_opp_list); 108 104 /* Lock to allow exclusive modification to the device and opp lists */ 109 105 static DEFINE_MUTEX(dev_opp_list_lock); 106 + 107 + #define opp_rcu_lockdep_assert() \ 108 + do { \ 109 + rcu_lockdep_assert(rcu_read_lock_held() || \ 110 + lockdep_is_held(&dev_opp_list_lock), \ 111 + "Missing rcu_read_lock() or " \ 112 + "dev_opp_list_lock protection"); \ 113 + } while (0) 110 114 111 115 /** 112 116 * find_device_opp() - find device_opp struct using device pointer ··· 216 204 * This function returns the number of available opps if there are any, 217 205 * else returns 0 if none or the corresponding error value. 218 206 * 219 - * Locking: This function must be called under rcu_read_lock(). This function 220 - * internally references two RCU protected structures: device_opp and opp which 221 - * are safe as long as we are under a common RCU locked section. 207 + * Locking: This function takes rcu_read_lock(). 222 208 */ 223 209 int dev_pm_opp_get_opp_count(struct device *dev) 224 210 { ··· 224 214 struct dev_pm_opp *temp_opp; 225 215 int count = 0; 226 216 217 + rcu_read_lock(); 218 + 227 219 dev_opp = find_device_opp(dev); 228 220 if (IS_ERR(dev_opp)) { 229 - int r = PTR_ERR(dev_opp); 230 - dev_err(dev, "%s: device OPP not found (%d)\n", __func__, r); 231 - return r; 221 + count = PTR_ERR(dev_opp); 222 + dev_err(dev, "%s: device OPP not found (%d)\n", 223 + __func__, count); 224 + goto out_unlock; 232 225 } 233 226 234 227 list_for_each_entry_rcu(temp_opp, &dev_opp->opp_list, node) { ··· 239 226 count++; 240 227 } 241 228 229 + out_unlock: 230 + rcu_read_unlock(); 242 231 return count; 243 232 } 244 233 EXPORT_SYMBOL_GPL(dev_pm_opp_get_opp_count); ··· 277 262 { 278 263 struct device_opp *dev_opp; 279 264 struct dev_pm_opp *temp_opp, *opp = ERR_PTR(-ERANGE); 265 + 266 + opp_rcu_lockdep_assert(); 280 267 281 268 dev_opp = find_device_opp(dev); 282 269 if (IS_ERR(dev_opp)) { ··· 325 308 { 326 309 struct device_opp *dev_opp; 327 310 struct dev_pm_opp *temp_opp, *opp = ERR_PTR(-ERANGE); 311 + 312 + opp_rcu_lockdep_assert(); 328 313 329 314 if (!dev || !freq) { 330 315 dev_err(dev, "%s: Invalid argument freq=%p\n", __func__, freq); ··· 376 357 struct device_opp *dev_opp; 377 358 struct dev_pm_opp *temp_opp, *opp = ERR_PTR(-ERANGE); 378 359 360 + opp_rcu_lockdep_assert(); 361 + 379 362 if (!dev || !freq) { 380 363 dev_err(dev, "%s: Invalid argument freq=%p\n", __func__, freq); 381 364 return ERR_PTR(-EINVAL); ··· 403 382 } 404 383 EXPORT_SYMBOL_GPL(dev_pm_opp_find_freq_floor); 405 384 385 + static struct device_opp *add_device_opp(struct device *dev) 386 + { 387 + struct device_opp *dev_opp; 388 + 389 + /* 390 + * Allocate a new device OPP table. In the infrequent case where a new 391 + * device is needed to be added, we pay this penalty. 392 + */ 393 + dev_opp = kzalloc(sizeof(*dev_opp), GFP_KERNEL); 394 + if (!dev_opp) 395 + return NULL; 396 + 397 + dev_opp->dev = dev; 398 + srcu_init_notifier_head(&dev_opp->srcu_head); 399 + INIT_LIST_HEAD(&dev_opp->opp_list); 400 + 401 + /* Secure the device list modification */ 402 + list_add_rcu(&dev_opp->node, &dev_opp_list); 403 + return dev_opp; 404 + } 405 + 406 406 static int dev_pm_opp_add_dynamic(struct device *dev, unsigned long freq, 407 407 unsigned long u_volt, bool dynamic) 408 408 { 409 409 struct device_opp *dev_opp = NULL; 410 410 struct dev_pm_opp *opp, *new_opp; 411 411 struct list_head *head; 412 + int ret; 412 413 413 414 /* allocate new OPP node */ 414 415 new_opp = kzalloc(sizeof(*new_opp), GFP_KERNEL); ··· 443 400 mutex_lock(&dev_opp_list_lock); 444 401 445 402 /* populate the opp table */ 446 - new_opp->dev_opp = dev_opp; 447 403 new_opp->rate = freq; 448 404 new_opp->u_volt = u_volt; 449 405 new_opp->available = true; ··· 451 409 /* Check for existing list for 'dev' */ 452 410 dev_opp = find_device_opp(dev); 453 411 if (IS_ERR(dev_opp)) { 454 - /* 455 - * Allocate a new device OPP table. In the infrequent case 456 - * where a new device is needed to be added, we pay this 457 - * penalty. 458 - */ 459 - dev_opp = kzalloc(sizeof(struct device_opp), GFP_KERNEL); 412 + dev_opp = add_device_opp(dev); 460 413 if (!dev_opp) { 461 - mutex_unlock(&dev_opp_list_lock); 462 - kfree(new_opp); 463 - dev_warn(dev, 464 - "%s: Unable to create device OPP structure\n", 465 - __func__); 466 - return -ENOMEM; 414 + ret = -ENOMEM; 415 + goto free_opp; 467 416 } 468 417 469 - dev_opp->dev = dev; 470 - srcu_init_notifier_head(&dev_opp->srcu_head); 471 - INIT_LIST_HEAD(&dev_opp->opp_list); 472 - 473 - /* Secure the device list modification */ 474 - list_add_rcu(&dev_opp->node, &dev_opp_list); 475 418 head = &dev_opp->opp_list; 476 419 goto list_add; 477 420 } ··· 475 448 476 449 /* Duplicate OPPs ? */ 477 450 if (new_opp->rate == opp->rate) { 478 - int ret = opp->available && new_opp->u_volt == opp->u_volt ? 451 + ret = opp->available && new_opp->u_volt == opp->u_volt ? 479 452 0 : -EEXIST; 480 453 481 454 dev_warn(dev, "%s: duplicate OPPs detected. Existing: freq: %lu, volt: %lu, enabled: %d. New: freq: %lu, volt: %lu, enabled: %d\n", 482 455 __func__, opp->rate, opp->u_volt, opp->available, 483 456 new_opp->rate, new_opp->u_volt, new_opp->available); 484 - mutex_unlock(&dev_opp_list_lock); 485 - kfree(new_opp); 486 - return ret; 457 + goto free_opp; 487 458 } 488 459 489 460 list_add: 461 + new_opp->dev_opp = dev_opp; 490 462 list_add_rcu(&new_opp->node, head); 491 463 mutex_unlock(&dev_opp_list_lock); 492 464 ··· 495 469 */ 496 470 srcu_notifier_call_chain(&dev_opp->srcu_head, OPP_EVENT_ADD, new_opp); 497 471 return 0; 472 + 473 + free_opp: 474 + mutex_unlock(&dev_opp_list_lock); 475 + kfree(new_opp); 476 + return ret; 498 477 } 499 478 500 479 /** ··· 542 511 { 543 512 struct device_opp *device_opp = container_of(head, struct device_opp, rcu_head); 544 513 545 - kfree(device_opp); 514 + kfree_rcu(device_opp, rcu_head); 546 515 } 547 516 548 - void __dev_pm_opp_remove(struct device_opp *dev_opp, struct dev_pm_opp *opp) 517 + static void __dev_pm_opp_remove(struct device_opp *dev_opp, 518 + struct dev_pm_opp *opp) 549 519 { 550 520 /* 551 521 * Notify the changes in the availability of the operable ··· 624 592 static int opp_set_availability(struct device *dev, unsigned long freq, 625 593 bool availability_req) 626 594 { 627 - struct device_opp *tmp_dev_opp, *dev_opp = ERR_PTR(-ENODEV); 595 + struct device_opp *dev_opp; 628 596 struct dev_pm_opp *new_opp, *tmp_opp, *opp = ERR_PTR(-ENODEV); 629 597 int r = 0; 630 598 ··· 638 606 mutex_lock(&dev_opp_list_lock); 639 607 640 608 /* Find the device_opp */ 641 - list_for_each_entry(tmp_dev_opp, &dev_opp_list, node) { 642 - if (dev == tmp_dev_opp->dev) { 643 - dev_opp = tmp_dev_opp; 644 - break; 645 - } 646 - } 609 + dev_opp = find_device_opp(dev); 647 610 if (IS_ERR(dev_opp)) { 648 611 r = PTR_ERR(dev_opp); 649 612 dev_warn(dev, "%s: Device OPP not found (%d)\n", __func__, r); ··· 795 768 */ 796 769 void of_free_opp_table(struct device *dev) 797 770 { 798 - struct device_opp *dev_opp = find_device_opp(dev); 771 + struct device_opp *dev_opp; 799 772 struct dev_pm_opp *opp, *tmp; 800 773 801 774 /* Check for existing list for 'dev' */ 802 775 dev_opp = find_device_opp(dev); 803 - if (WARN(IS_ERR(dev_opp), "%s: dev_opp: %ld\n", dev_name(dev), 804 - PTR_ERR(dev_opp))) 776 + if (IS_ERR(dev_opp)) { 777 + int error = PTR_ERR(dev_opp); 778 + if (error != -ENODEV) 779 + WARN(1, "%s: dev_opp: %d\n", 780 + IS_ERR_OR_NULL(dev) ? 781 + "Invalid device" : dev_name(dev), 782 + error); 805 783 return; 784 + } 806 785 807 786 /* Hold our list modification lock here */ 808 787 mutex_lock(&dev_opp_list_lock);