Merge branches 'pm-devfreq' and 'pm-opp'

Merge devfreq and OPP (Operating Performance Points) updates for 6.14:

- Clean up the Exynos devfreq driver and devfreq core (Markus Elfring,
Jeongjun Park).

- Minor cleanups and fixes for OPP (Dan Carpenter, Neil Armstrong, Joe
Hattori).

- Implement dev_pm_opp_get_bw() (Neil Armstrong).

- Expose OPP reference counting helpers for Rust (Viresh Kumar).

* pm-devfreq:
PM / devfreq: exynos: remove unused function parameter
PM / devfreq: event: Call of_node_put() only once in devfreq_event_get_edev_by_phandle()

* pm-opp:
PM / OPP: Add reference counting helpers for Rust implementation
OPP: OF: Fix an OF node leak in _opp_add_static_v2()
OPP: fix dev_pm_opp_find_bw_*() when bandwidth table not initialized
OPP: add index check to assert to avoid buffer overflow in _read_freq()
opp: core: Fix off by one in dev_pm_opp_get_bw()
opp: core: implement dev_pm_opp_get_bw

+97 -33
+2 -6
drivers/devfreq/devfreq-event.c
··· 244 244 edev = NULL; 245 245 out: 246 246 mutex_unlock(&devfreq_event_list_lock); 247 - 248 - if (!edev) { 249 - of_node_put(node); 250 - return ERR_PTR(-ENODEV); 251 - } 252 - 253 247 of_node_put(node); 248 + if (!edev) 249 + return ERR_PTR(-ENODEV); 254 250 255 251 return edev; 256 252 }
+2 -3
drivers/devfreq/exynos-bus.c
··· 236 236 return ret; 237 237 } 238 238 239 - static int exynos_bus_parse_of(struct device_node *np, 240 - struct exynos_bus *bus) 239 + static int exynos_bus_parse_of(struct exynos_bus *bus) 241 240 { 242 241 struct device *dev = bus->dev; 243 242 struct dev_pm_opp *opp; ··· 407 408 } 408 409 409 410 /* Parse the device-tree to get the resource information */ 410 - ret = exynos_bus_parse_of(np, bus); 411 + ret = exynos_bus_parse_of(bus); 411 412 if (ret < 0) 412 413 goto err_reg; 413 414
+77 -22
drivers/opp/core.c
··· 101 101 * representation in the OPP table and manage the clock configuration themselves 102 102 * in an platform specific way. 103 103 */ 104 - static bool assert_single_clk(struct opp_table *opp_table) 104 + static bool assert_single_clk(struct opp_table *opp_table, 105 + unsigned int __always_unused index) 105 106 { 106 107 return !WARN_ON(opp_table->clk_count > 1); 107 108 } 109 + 110 + /* 111 + * Returns true if clock table is large enough to contain the clock index. 112 + */ 113 + static bool assert_clk_index(struct opp_table *opp_table, 114 + unsigned int index) 115 + { 116 + return opp_table->clk_count > index; 117 + } 118 + 119 + /* 120 + * Returns true if bandwidth table is large enough to contain the bandwidth index. 121 + */ 122 + static bool assert_bandwidth_index(struct opp_table *opp_table, 123 + unsigned int index) 124 + { 125 + return opp_table->path_count > index; 126 + } 127 + 128 + /** 129 + * dev_pm_opp_get_bw() - Gets the bandwidth corresponding to an opp 130 + * @opp: opp for which bandwidth has to be returned for 131 + * @peak: select peak or average bandwidth 132 + * @index: bandwidth index 133 + * 134 + * Return: bandwidth in kBps, else return 0 135 + */ 136 + unsigned long dev_pm_opp_get_bw(struct dev_pm_opp *opp, bool peak, int index) 137 + { 138 + if (IS_ERR_OR_NULL(opp)) { 139 + pr_err("%s: Invalid parameters\n", __func__); 140 + return 0; 141 + } 142 + 143 + if (index >= opp->opp_table->path_count) 144 + return 0; 145 + 146 + if (!opp->bandwidth) 147 + return 0; 148 + 149 + return peak ? opp->bandwidth[index].peak : opp->bandwidth[index].avg; 150 + } 151 + EXPORT_SYMBOL_GPL(dev_pm_opp_get_bw); 108 152 109 153 /** 110 154 * dev_pm_opp_get_voltage() - Gets the voltage corresponding to an opp ··· 543 499 unsigned long (*read)(struct dev_pm_opp *opp, int index), 544 500 bool (*compare)(struct dev_pm_opp **opp, struct dev_pm_opp *temp_opp, 545 501 unsigned long opp_key, unsigned long key), 546 - bool (*assert)(struct opp_table *opp_table)) 502 + bool (*assert)(struct opp_table *opp_table, unsigned int index)) 547 503 { 548 504 struct dev_pm_opp *temp_opp, *opp = ERR_PTR(-ERANGE); 549 505 550 506 /* Assert that the requirement is met */ 551 - if (assert && !assert(opp_table)) 507 + if (assert && !assert(opp_table, index)) 552 508 return ERR_PTR(-EINVAL); 553 509 554 510 mutex_lock(&opp_table->lock); ··· 576 532 unsigned long (*read)(struct dev_pm_opp *opp, int index), 577 533 bool (*compare)(struct dev_pm_opp **opp, struct dev_pm_opp *temp_opp, 578 534 unsigned long opp_key, unsigned long key), 579 - bool (*assert)(struct opp_table *opp_table)) 535 + bool (*assert)(struct opp_table *opp_table, unsigned int index)) 580 536 { 581 537 struct opp_table *opp_table; 582 538 struct dev_pm_opp *opp; ··· 599 555 static struct dev_pm_opp *_find_key_exact(struct device *dev, 600 556 unsigned long key, int index, bool available, 601 557 unsigned long (*read)(struct dev_pm_opp *opp, int index), 602 - bool (*assert)(struct opp_table *opp_table)) 558 + bool (*assert)(struct opp_table *opp_table, unsigned int index)) 603 559 { 604 560 /* 605 561 * The value of key will be updated here, but will be ignored as the ··· 612 568 static struct dev_pm_opp *_opp_table_find_key_ceil(struct opp_table *opp_table, 613 569 unsigned long *key, int index, bool available, 614 570 unsigned long (*read)(struct dev_pm_opp *opp, int index), 615 - bool (*assert)(struct opp_table *opp_table)) 571 + bool (*assert)(struct opp_table *opp_table, unsigned int index)) 616 572 { 617 573 return _opp_table_find_key(opp_table, key, index, available, read, 618 574 _compare_ceil, assert); ··· 621 577 static struct dev_pm_opp *_find_key_ceil(struct device *dev, unsigned long *key, 622 578 int index, bool available, 623 579 unsigned long (*read)(struct dev_pm_opp *opp, int index), 624 - bool (*assert)(struct opp_table *opp_table)) 580 + bool (*assert)(struct opp_table *opp_table, unsigned int index)) 625 581 { 626 582 return _find_key(dev, key, index, available, read, _compare_ceil, 627 583 assert); ··· 630 586 static struct dev_pm_opp *_find_key_floor(struct device *dev, 631 587 unsigned long *key, int index, bool available, 632 588 unsigned long (*read)(struct dev_pm_opp *opp, int index), 633 - bool (*assert)(struct opp_table *opp_table)) 589 + bool (*assert)(struct opp_table *opp_table, unsigned int index)) 634 590 { 635 591 return _find_key(dev, key, index, available, read, _compare_floor, 636 592 assert); ··· 691 647 dev_pm_opp_find_freq_exact_indexed(struct device *dev, unsigned long freq, 692 648 u32 index, bool available) 693 649 { 694 - return _find_key_exact(dev, freq, index, available, _read_freq, NULL); 650 + return _find_key_exact(dev, freq, index, available, _read_freq, 651 + assert_clk_index); 695 652 } 696 653 EXPORT_SYMBOL_GPL(dev_pm_opp_find_freq_exact_indexed); 697 654 ··· 752 707 dev_pm_opp_find_freq_ceil_indexed(struct device *dev, unsigned long *freq, 753 708 u32 index) 754 709 { 755 - return _find_key_ceil(dev, freq, index, true, _read_freq, NULL); 710 + return _find_key_ceil(dev, freq, index, true, _read_freq, 711 + assert_clk_index); 756 712 } 757 713 EXPORT_SYMBOL_GPL(dev_pm_opp_find_freq_ceil_indexed); 758 714 ··· 806 760 dev_pm_opp_find_freq_floor_indexed(struct device *dev, unsigned long *freq, 807 761 u32 index) 808 762 { 809 - return _find_key_floor(dev, freq, index, true, _read_freq, NULL); 763 + return _find_key_floor(dev, freq, index, true, _read_freq, assert_clk_index); 810 764 } 811 765 EXPORT_SYMBOL_GPL(dev_pm_opp_find_freq_floor_indexed); 812 766 ··· 924 878 unsigned long temp = *bw; 925 879 struct dev_pm_opp *opp; 926 880 927 - opp = _find_key_ceil(dev, &temp, index, true, _read_bw, NULL); 881 + opp = _find_key_ceil(dev, &temp, index, true, _read_bw, 882 + assert_bandwidth_index); 928 883 *bw = temp; 929 884 return opp; 930 885 } ··· 956 909 unsigned long temp = *bw; 957 910 struct dev_pm_opp *opp; 958 911 959 - opp = _find_key_floor(dev, &temp, index, true, _read_bw, NULL); 912 + opp = _find_key_floor(dev, &temp, index, true, _read_bw, 913 + assert_bandwidth_index); 960 914 *bw = temp; 961 915 return opp; 962 916 } ··· 1528 1480 return ERR_PTR(ret); 1529 1481 } 1530 1482 1531 - void _get_opp_table_kref(struct opp_table *opp_table) 1532 - { 1533 - kref_get(&opp_table->kref); 1534 - } 1535 - 1536 1483 static struct opp_table *_update_opp_table_clk(struct device *dev, 1537 1484 struct opp_table *opp_table, 1538 1485 bool getclk) ··· 1688 1645 kfree(opp_table); 1689 1646 } 1690 1647 1648 + void _get_opp_table_kref(struct opp_table *opp_table) 1649 + { 1650 + kref_get(&opp_table->kref); 1651 + } 1652 + 1653 + void dev_pm_opp_get_opp_table_ref(struct opp_table *opp_table) 1654 + { 1655 + _get_opp_table_kref(opp_table); 1656 + } 1657 + EXPORT_SYMBOL_GPL(dev_pm_opp_get_opp_table_ref); 1658 + 1691 1659 void dev_pm_opp_put_opp_table(struct opp_table *opp_table) 1692 1660 { 1693 1661 kref_put_mutex(&opp_table->kref, _opp_table_kref_release, ··· 1733 1679 { 1734 1680 kref_get(&opp->kref); 1735 1681 } 1682 + EXPORT_SYMBOL_GPL(dev_pm_opp_get); 1736 1683 1737 1684 void dev_pm_opp_put(struct dev_pm_opp *opp) 1738 1685 { ··· 1757 1702 if (IS_ERR(opp_table)) 1758 1703 return; 1759 1704 1760 - if (!assert_single_clk(opp_table)) 1705 + if (!assert_single_clk(opp_table, 0)) 1761 1706 goto put_table; 1762 1707 1763 1708 mutex_lock(&opp_table->lock); ··· 2109 2054 unsigned long tol, u_volt = data->u_volt; 2110 2055 int ret; 2111 2056 2112 - if (!assert_single_clk(opp_table)) 2057 + if (!assert_single_clk(opp_table, 0)) 2113 2058 return -EINVAL; 2114 2059 2115 2060 new_opp = _opp_allocate(opp_table); ··· 2865 2810 return r; 2866 2811 } 2867 2812 2868 - if (!assert_single_clk(opp_table)) { 2813 + if (!assert_single_clk(opp_table, 0)) { 2869 2814 r = -EINVAL; 2870 2815 goto put_table; 2871 2816 } ··· 2941 2886 return r; 2942 2887 } 2943 2888 2944 - if (!assert_single_clk(opp_table)) { 2889 + if (!assert_single_clk(opp_table, 0)) { 2945 2890 r = -EINVAL; 2946 2891 goto put_table; 2947 2892 }
+3 -1
drivers/opp/of.c
··· 926 926 927 927 ret = _of_opp_alloc_required_opps(opp_table, new_opp); 928 928 if (ret) 929 - goto free_opp; 929 + goto put_node; 930 930 931 931 if (!of_property_read_u32(np, "clock-latency-ns", &val)) 932 932 new_opp->clock_latency_ns = val; ··· 976 976 977 977 free_required_opps: 978 978 _of_opp_free_required_opps(opp_table, new_opp); 979 + put_node: 980 + of_node_put(np); 979 981 free_opp: 980 982 _opp_free(new_opp); 981 983
-1
drivers/opp/opp.h
··· 250 250 }; 251 251 252 252 /* Routines internal to opp core */ 253 - void dev_pm_opp_get(struct dev_pm_opp *opp); 254 253 bool _opp_remove_all_static(struct opp_table *opp_table); 255 254 void _get_opp_table_kref(struct opp_table *opp_table); 256 255 int _get_opp_count(struct opp_table *opp_table);
+13
include/linux/pm_opp.h
··· 100 100 #if defined(CONFIG_PM_OPP) 101 101 102 102 struct opp_table *dev_pm_opp_get_opp_table(struct device *dev); 103 + void dev_pm_opp_get_opp_table_ref(struct opp_table *opp_table); 103 104 void dev_pm_opp_put_opp_table(struct opp_table *opp_table); 105 + 106 + unsigned long dev_pm_opp_get_bw(struct dev_pm_opp *opp, bool peak, int index); 104 107 105 108 unsigned long dev_pm_opp_get_voltage(struct dev_pm_opp *opp); 106 109 ··· 161 158 struct dev_pm_opp *dev_pm_opp_find_bw_floor(struct device *dev, 162 159 unsigned int *bw, int index); 163 160 161 + void dev_pm_opp_get(struct dev_pm_opp *opp); 164 162 void dev_pm_opp_put(struct dev_pm_opp *opp); 165 163 166 164 int dev_pm_opp_add_dynamic(struct device *dev, struct dev_pm_opp_data *opp); ··· 207 203 return ERR_PTR(-EOPNOTSUPP); 208 204 } 209 205 206 + static inline void dev_pm_opp_get_opp_table_ref(struct opp_table *opp_table) {} 207 + 210 208 static inline void dev_pm_opp_put_opp_table(struct opp_table *opp_table) {} 209 + 210 + static inline unsigned long dev_pm_opp_get_bw(struct dev_pm_opp *opp, bool peak, int index) 211 + { 212 + return 0; 213 + } 211 214 212 215 static inline unsigned long dev_pm_opp_get_voltage(struct dev_pm_opp *opp) 213 216 { ··· 344 333 { 345 334 return ERR_PTR(-EOPNOTSUPP); 346 335 } 336 + 337 + static inline void dev_pm_opp_get(struct dev_pm_opp *opp) {} 347 338 348 339 static inline void dev_pm_opp_put(struct dev_pm_opp *opp) {} 349 340