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

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'pm-5.16-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm

Pull more power management updates from Rafael Wysocki:
"These fix three intel_pstate driver regressions, fix locking in the
core code suspending and resuming devices during system PM
transitions, fix the handling of cpuidle drivers based on runtime PM
during system-wide suspend, fix two issues in the operating
performance points (OPP) framework and resource-managed helpers to it.

Specifics:

- Fix two intel_pstate driver regressions related to the HWP
interrupt handling added recently (Srinivas Pandruvada).

- Fix intel_pstate driver regression introduced during the 5.11 cycle
and causing HWP desired performance to be mishandled in some cases
when switching driver modes and during system suspend and shutdown
(Rafael Wysocki).

- Fix system-wide device suspend and resume locking to avoid
deadlocks when device objects are deleted during a system-wide PM
transition (Rafael Wysocki).

- Modify system-wide suspend of devices to prevent cpuidle drivers
based on runtime PM from misbehaving during the "no IRQ" phase of
it (Ulf Hansson).

- Fix return value of _opp_add_static_v2() helper (YueHaibing).

- Fix required-opp handle count (Pavankumar Kondeti).

- Add resource managed OPP helpers, update dev_pm_opp_attach_genpd(),
update their devfreq users, and make minor DT binding change
(Dmitry Osipenko)"

* tag 'pm-5.16-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
PM: sleep: Avoid calling put_device() under dpm_list_mtx
cpufreq: intel_pstate: Clear HWP Status during HWP Interrupt enable
cpufreq: intel_pstate: Fix unchecked MSR 0x773 access
cpufreq: intel_pstate: Clear HWP desired on suspend/shutdown and offline
PM: sleep: Fix runtime PM based cpuidle support
dt-bindings: opp: Allow multi-worded OPP entry name
opp: Fix return in _opp_add_static_v2()
PM / devfreq: tegra30: Check whether clk_round_rate() returns zero rate
PM / devfreq: tegra30: Use resource-managed helpers
PM / devfreq: Add devm_devfreq_add_governor()
opp: Add more resource-managed variants of dev_pm_opp_of_add_table()
opp: Change type of dev_pm_opp_attach_genpd(names) argument
opp: Fix required-opps phandle array count check

+229 -108
+1 -1
Documentation/devicetree/bindings/opp/opp-v2-base.yaml
··· 33 33 type: boolean 34 34 35 35 patternProperties: 36 - '^opp-?[0-9]+$': 36 + '^opp(-?[0-9]+)*$': 37 37 type: object 38 38 description: 39 39 One or more OPP nodes describing voltage-current-frequency combinations.
+58 -27
drivers/base/power/main.c
··· 710 710 dev = to_device(dpm_noirq_list.next); 711 711 get_device(dev); 712 712 list_move_tail(&dev->power.entry, &dpm_late_early_list); 713 + 713 714 mutex_unlock(&dpm_list_mtx); 714 715 715 716 if (!is_async(dev)) { ··· 725 724 } 726 725 } 727 726 728 - mutex_lock(&dpm_list_mtx); 729 727 put_device(dev); 728 + 729 + mutex_lock(&dpm_list_mtx); 730 730 } 731 731 mutex_unlock(&dpm_list_mtx); 732 732 async_synchronize_full(); ··· 851 849 dev = to_device(dpm_late_early_list.next); 852 850 get_device(dev); 853 851 list_move_tail(&dev->power.entry, &dpm_suspended_list); 852 + 854 853 mutex_unlock(&dpm_list_mtx); 855 854 856 855 if (!is_async(dev)) { ··· 865 862 pm_dev_err(dev, state, " early", error); 866 863 } 867 864 } 868 - mutex_lock(&dpm_list_mtx); 865 + 869 866 put_device(dev); 867 + 868 + mutex_lock(&dpm_list_mtx); 870 869 } 871 870 mutex_unlock(&dpm_list_mtx); 872 871 async_synchronize_full(); ··· 1031 1026 } 1032 1027 if (!list_empty(&dev->power.entry)) 1033 1028 list_move_tail(&dev->power.entry, &dpm_prepared_list); 1029 + 1030 + mutex_unlock(&dpm_list_mtx); 1031 + 1034 1032 put_device(dev); 1033 + 1034 + mutex_lock(&dpm_list_mtx); 1035 1035 } 1036 1036 mutex_unlock(&dpm_list_mtx); 1037 1037 async_synchronize_full(); ··· 1114 1104 get_device(dev); 1115 1105 dev->power.is_prepared = false; 1116 1106 list_move(&dev->power.entry, &list); 1107 + 1117 1108 mutex_unlock(&dpm_list_mtx); 1118 1109 1119 1110 trace_device_pm_callback_start(dev, "", state.event); 1120 1111 device_complete(dev, state); 1121 1112 trace_device_pm_callback_end(dev, 0); 1122 1113 1123 - mutex_lock(&dpm_list_mtx); 1124 1114 put_device(dev); 1115 + 1116 + mutex_lock(&dpm_list_mtx); 1125 1117 } 1126 1118 list_splice(&list, &dpm_list); 1127 1119 mutex_unlock(&dpm_list_mtx); ··· 1308 1296 error = device_suspend_noirq(dev); 1309 1297 1310 1298 mutex_lock(&dpm_list_mtx); 1299 + 1311 1300 if (error) { 1312 1301 pm_dev_err(dev, state, " noirq", error); 1313 1302 dpm_save_failed_dev(dev_name(dev)); 1314 - put_device(dev); 1315 - break; 1316 - } 1317 - if (!list_empty(&dev->power.entry)) 1303 + } else if (!list_empty(&dev->power.entry)) { 1318 1304 list_move(&dev->power.entry, &dpm_noirq_list); 1305 + } 1306 + 1307 + mutex_unlock(&dpm_list_mtx); 1308 + 1319 1309 put_device(dev); 1320 1310 1321 - if (async_error) 1311 + mutex_lock(&dpm_list_mtx); 1312 + 1313 + if (error || async_error) 1322 1314 break; 1323 1315 } 1324 1316 mutex_unlock(&dpm_list_mtx); ··· 1479 1463 int error = 0; 1480 1464 1481 1465 trace_suspend_resume(TPS("dpm_suspend_late"), state.event, true); 1466 + wake_up_all_idle_cpus(); 1482 1467 mutex_lock(&dpm_list_mtx); 1483 1468 pm_transition = state; 1484 1469 async_error = 0; ··· 1488 1471 struct device *dev = to_device(dpm_suspended_list.prev); 1489 1472 1490 1473 get_device(dev); 1474 + 1491 1475 mutex_unlock(&dpm_list_mtx); 1492 1476 1493 1477 error = device_suspend_late(dev); 1494 1478 1495 1479 mutex_lock(&dpm_list_mtx); 1480 + 1496 1481 if (!list_empty(&dev->power.entry)) 1497 1482 list_move(&dev->power.entry, &dpm_late_early_list); 1498 1483 1499 1484 if (error) { 1500 1485 pm_dev_err(dev, state, " late", error); 1501 1486 dpm_save_failed_dev(dev_name(dev)); 1502 - put_device(dev); 1503 - break; 1504 1487 } 1488 + 1489 + mutex_unlock(&dpm_list_mtx); 1490 + 1505 1491 put_device(dev); 1506 1492 1507 - if (async_error) 1493 + mutex_lock(&dpm_list_mtx); 1494 + 1495 + if (error || async_error) 1508 1496 break; 1509 1497 } 1510 1498 mutex_unlock(&dpm_list_mtx); ··· 1769 1747 struct device *dev = to_device(dpm_prepared_list.prev); 1770 1748 1771 1749 get_device(dev); 1750 + 1772 1751 mutex_unlock(&dpm_list_mtx); 1773 1752 1774 1753 error = device_suspend(dev); 1775 1754 1776 1755 mutex_lock(&dpm_list_mtx); 1756 + 1777 1757 if (error) { 1778 1758 pm_dev_err(dev, state, "", error); 1779 1759 dpm_save_failed_dev(dev_name(dev)); 1780 - put_device(dev); 1781 - break; 1782 - } 1783 - if (!list_empty(&dev->power.entry)) 1760 + } else if (!list_empty(&dev->power.entry)) { 1784 1761 list_move(&dev->power.entry, &dpm_suspended_list); 1762 + } 1763 + 1764 + mutex_unlock(&dpm_list_mtx); 1765 + 1785 1766 put_device(dev); 1786 - if (async_error) 1767 + 1768 + mutex_lock(&dpm_list_mtx); 1769 + 1770 + if (error || async_error) 1787 1771 break; 1788 1772 } 1789 1773 mutex_unlock(&dpm_list_mtx); ··· 1906 1878 struct device *dev = to_device(dpm_list.next); 1907 1879 1908 1880 get_device(dev); 1881 + 1909 1882 mutex_unlock(&dpm_list_mtx); 1910 1883 1911 1884 trace_device_pm_callback_start(dev, "", state.event); ··· 1914 1885 trace_device_pm_callback_end(dev, error); 1915 1886 1916 1887 mutex_lock(&dpm_list_mtx); 1917 - if (error) { 1918 - if (error == -EAGAIN) { 1919 - put_device(dev); 1920 - error = 0; 1921 - continue; 1922 - } 1888 + 1889 + if (!error) { 1890 + dev->power.is_prepared = true; 1891 + if (!list_empty(&dev->power.entry)) 1892 + list_move_tail(&dev->power.entry, &dpm_prepared_list); 1893 + } else if (error == -EAGAIN) { 1894 + error = 0; 1895 + } else { 1923 1896 dev_info(dev, "not prepared for power transition: code %d\n", 1924 1897 error); 1925 - put_device(dev); 1926 - break; 1927 1898 } 1928 - dev->power.is_prepared = true; 1929 - if (!list_empty(&dev->power.entry)) 1930 - list_move_tail(&dev->power.entry, &dpm_prepared_list); 1899 + 1900 + mutex_unlock(&dpm_list_mtx); 1901 + 1931 1902 put_device(dev); 1903 + 1904 + mutex_lock(&dpm_list_mtx); 1932 1905 } 1933 1906 mutex_unlock(&dpm_list_mtx); 1934 1907 trace_suspend_resume(TPS("dpm_prepare"), state.event, false);
+34 -2
drivers/cpufreq/intel_pstate.c
··· 1006 1006 */ 1007 1007 value &= ~GENMASK_ULL(31, 24); 1008 1008 value |= HWP_ENERGY_PERF_PREFERENCE(cpu->epp_cached); 1009 - WRITE_ONCE(cpu->hwp_req_cached, value); 1010 1009 } 1010 + 1011 + /* 1012 + * Clear the desired perf field in the cached HWP request value to 1013 + * prevent nonzero desired values from being leaked into the active 1014 + * mode. 1015 + */ 1016 + value &= ~HWP_DESIRED_PERF(~0L); 1017 + WRITE_ONCE(cpu->hwp_req_cached, value); 1011 1018 1012 1019 value &= ~GENMASK_ULL(31, 0); 1013 1020 min_perf = HWP_LOWEST_PERF(READ_ONCE(cpu->hwp_cap_cached)); ··· 1627 1620 { 1628 1621 unsigned long flags; 1629 1622 1623 + if (!boot_cpu_has(X86_FEATURE_HWP_NOTIFY)) 1624 + return; 1625 + 1630 1626 /* wrmsrl_on_cpu has to be outside spinlock as this can result in IPC */ 1631 1627 wrmsrl_on_cpu(cpudata->cpu, MSR_HWP_INTERRUPT, 0x00); 1632 1628 ··· 1652 1642 1653 1643 /* wrmsrl_on_cpu has to be outside spinlock as this can result in IPC */ 1654 1644 wrmsrl_on_cpu(cpudata->cpu, MSR_HWP_INTERRUPT, 0x01); 1645 + wrmsrl_on_cpu(cpudata->cpu, MSR_HWP_STATUS, 0); 1655 1646 } 1656 1647 } 1657 1648 ··· 3014 3003 return intel_pstate_cpu_exit(policy); 3015 3004 } 3016 3005 3006 + static int intel_cpufreq_suspend(struct cpufreq_policy *policy) 3007 + { 3008 + intel_pstate_suspend(policy); 3009 + 3010 + if (hwp_active) { 3011 + struct cpudata *cpu = all_cpu_data[policy->cpu]; 3012 + u64 value = READ_ONCE(cpu->hwp_req_cached); 3013 + 3014 + /* 3015 + * Clear the desired perf field in MSR_HWP_REQUEST in case 3016 + * intel_cpufreq_adjust_perf() is in use and the last value 3017 + * written by it may not be suitable. 3018 + */ 3019 + value &= ~HWP_DESIRED_PERF(~0L); 3020 + wrmsrl_on_cpu(cpu->cpu, MSR_HWP_REQUEST, value); 3021 + WRITE_ONCE(cpu->hwp_req_cached, value); 3022 + } 3023 + 3024 + return 0; 3025 + } 3026 + 3017 3027 static struct cpufreq_driver intel_cpufreq = { 3018 3028 .flags = CPUFREQ_CONST_LOOPS, 3019 3029 .verify = intel_cpufreq_verify_policy, ··· 3044 3012 .exit = intel_cpufreq_cpu_exit, 3045 3013 .offline = intel_cpufreq_cpu_offline, 3046 3014 .online = intel_pstate_cpu_online, 3047 - .suspend = intel_pstate_suspend, 3015 + .suspend = intel_cpufreq_suspend, 3048 3016 .resume = intel_pstate_resume, 3049 3017 .update_limits = intel_pstate_update_limits, 3050 3018 .name = "intel_cpufreq",
+26
drivers/devfreq/devfreq.c
··· 1301 1301 } 1302 1302 EXPORT_SYMBOL(devfreq_add_governor); 1303 1303 1304 + static void devm_devfreq_remove_governor(void *governor) 1305 + { 1306 + WARN_ON(devfreq_remove_governor(governor)); 1307 + } 1308 + 1309 + /** 1310 + * devm_devfreq_add_governor() - Add devfreq governor 1311 + * @dev: device which adds devfreq governor 1312 + * @governor: the devfreq governor to be added 1313 + * 1314 + * This is a resource-managed variant of devfreq_add_governor(). 1315 + */ 1316 + int devm_devfreq_add_governor(struct device *dev, 1317 + struct devfreq_governor *governor) 1318 + { 1319 + int err; 1320 + 1321 + err = devfreq_add_governor(governor); 1322 + if (err) 1323 + return err; 1324 + 1325 + return devm_add_action_or_reset(dev, devm_devfreq_remove_governor, 1326 + governor); 1327 + } 1328 + EXPORT_SYMBOL(devm_devfreq_add_governor); 1329 + 1304 1330 /** 1305 1331 * devfreq_remove_governor() - Remove devfreq feature from a device. 1306 1332 * @governor: the devfreq governor to be removed
+3
drivers/devfreq/governor.h
··· 84 84 int devfreq_add_governor(struct devfreq_governor *governor); 85 85 int devfreq_remove_governor(struct devfreq_governor *governor); 86 86 87 + int devm_devfreq_add_governor(struct device *dev, 88 + struct devfreq_governor *governor); 89 + 87 90 int devfreq_update_status(struct devfreq *devfreq, unsigned long freq); 88 91 int devfreq_update_target(struct devfreq *devfreq, unsigned long freq); 89 92
+47 -62
drivers/devfreq/tegra30-devfreq.c
··· 178 178 179 179 struct tegra_devfreq { 180 180 struct devfreq *devfreq; 181 - struct opp_table *opp_table; 182 181 183 182 struct reset_control *reset; 184 183 struct clk *clock; ··· 788 789 .event_handler = tegra_governor_event_handler, 789 790 }; 790 791 792 + static void devm_tegra_devfreq_deinit_hw(void *data) 793 + { 794 + struct tegra_devfreq *tegra = data; 795 + 796 + reset_control_reset(tegra->reset); 797 + clk_disable_unprepare(tegra->clock); 798 + } 799 + 800 + static int devm_tegra_devfreq_init_hw(struct device *dev, 801 + struct tegra_devfreq *tegra) 802 + { 803 + int err; 804 + 805 + err = clk_prepare_enable(tegra->clock); 806 + if (err) { 807 + dev_err(dev, "Failed to prepare and enable ACTMON clock\n"); 808 + return err; 809 + } 810 + 811 + err = devm_add_action_or_reset(dev, devm_tegra_devfreq_deinit_hw, 812 + tegra); 813 + if (err) 814 + return err; 815 + 816 + err = reset_control_reset(tegra->reset); 817 + if (err) { 818 + dev_err(dev, "Failed to reset hardware: %d\n", err); 819 + return err; 820 + } 821 + 822 + return err; 823 + } 824 + 791 825 static int tegra_devfreq_probe(struct platform_device *pdev) 792 826 { 793 827 u32 hw_version = BIT(tegra_sku_info.soc_speedo_id); ··· 874 842 return err; 875 843 } 876 844 877 - tegra->opp_table = dev_pm_opp_set_supported_hw(&pdev->dev, 878 - &hw_version, 1); 879 - err = PTR_ERR_OR_ZERO(tegra->opp_table); 845 + err = devm_pm_opp_set_supported_hw(&pdev->dev, &hw_version, 1); 880 846 if (err) { 881 847 dev_err(&pdev->dev, "Failed to set supported HW: %d\n", err); 882 848 return err; 883 849 } 884 850 885 - err = dev_pm_opp_of_add_table_noclk(&pdev->dev, 0); 851 + err = devm_pm_opp_of_add_table_noclk(&pdev->dev, 0); 886 852 if (err) { 887 853 dev_err(&pdev->dev, "Failed to add OPP table: %d\n", err); 888 - goto put_hw; 854 + return err; 889 855 } 890 856 891 - err = clk_prepare_enable(tegra->clock); 892 - if (err) { 893 - dev_err(&pdev->dev, 894 - "Failed to prepare and enable ACTMON clock\n"); 895 - goto remove_table; 896 - } 897 - 898 - err = reset_control_reset(tegra->reset); 899 - if (err) { 900 - dev_err(&pdev->dev, "Failed to reset hardware: %d\n", err); 901 - goto disable_clk; 902 - } 857 + err = devm_tegra_devfreq_init_hw(&pdev->dev, tegra); 858 + if (err) 859 + return err; 903 860 904 861 rate = clk_round_rate(tegra->emc_clock, ULONG_MAX); 905 - if (rate < 0) { 862 + if (rate <= 0) { 906 863 dev_err(&pdev->dev, "Failed to round clock rate: %ld\n", rate); 907 - err = rate; 908 - goto disable_clk; 864 + return rate ?: -EINVAL; 909 865 } 910 866 911 867 tegra->max_freq = rate / KHZ; ··· 912 892 INIT_DELAYED_WORK(&tegra->cpufreq_update_work, 913 893 tegra_actmon_delayed_update); 914 894 915 - err = devfreq_add_governor(&tegra_devfreq_governor); 895 + err = devm_devfreq_add_governor(&pdev->dev, &tegra_devfreq_governor); 916 896 if (err) { 917 897 dev_err(&pdev->dev, "Failed to add governor: %d\n", err); 918 - goto remove_opps; 898 + return err; 919 899 } 920 900 921 901 tegra_devfreq_profile.initial_freq = clk_get_rate(tegra->emc_clock); 922 902 923 - devfreq = devfreq_add_device(&pdev->dev, &tegra_devfreq_profile, 924 - "tegra_actmon", NULL); 925 - if (IS_ERR(devfreq)) { 926 - err = PTR_ERR(devfreq); 927 - goto remove_governor; 928 - } 929 - 930 - return 0; 931 - 932 - remove_governor: 933 - devfreq_remove_governor(&tegra_devfreq_governor); 934 - 935 - remove_opps: 936 - dev_pm_opp_remove_all_dynamic(&pdev->dev); 937 - 938 - reset_control_reset(tegra->reset); 939 - disable_clk: 940 - clk_disable_unprepare(tegra->clock); 941 - remove_table: 942 - dev_pm_opp_of_remove_table(&pdev->dev); 943 - put_hw: 944 - dev_pm_opp_put_supported_hw(tegra->opp_table); 945 - 946 - return err; 947 - } 948 - 949 - static int tegra_devfreq_remove(struct platform_device *pdev) 950 - { 951 - struct tegra_devfreq *tegra = platform_get_drvdata(pdev); 952 - 953 - devfreq_remove_device(tegra->devfreq); 954 - devfreq_remove_governor(&tegra_devfreq_governor); 955 - 956 - reset_control_reset(tegra->reset); 957 - clk_disable_unprepare(tegra->clock); 958 - 959 - dev_pm_opp_of_remove_table(&pdev->dev); 960 - dev_pm_opp_put_supported_hw(tegra->opp_table); 903 + devfreq = devm_devfreq_add_device(&pdev->dev, &tegra_devfreq_profile, 904 + "tegra_actmon", NULL); 905 + if (IS_ERR(devfreq)) 906 + return PTR_ERR(devfreq); 961 907 962 908 return 0; 963 909 } ··· 953 967 954 968 static struct platform_driver tegra_devfreq_driver = { 955 969 .probe = tegra_devfreq_probe, 956 - .remove = tegra_devfreq_remove, 957 970 .driver = { 958 971 .name = "tegra-devfreq", 959 972 .of_match_table = tegra_devfreq_of_match,
+3 -3
drivers/opp/core.c
··· 2348 2348 * "required-opps" are added in DT. 2349 2349 */ 2350 2350 struct opp_table *dev_pm_opp_attach_genpd(struct device *dev, 2351 - const char **names, struct device ***virt_devs) 2351 + const char * const *names, struct device ***virt_devs) 2352 2352 { 2353 2353 struct opp_table *opp_table; 2354 2354 struct device *virt_dev; 2355 2355 int index = 0, ret = -EINVAL; 2356 - const char **name = names; 2356 + const char * const *name = names; 2357 2357 2358 2358 opp_table = _add_opp_table(dev, false); 2359 2359 if (IS_ERR(opp_table)) ··· 2457 2457 * 2458 2458 * Return: 0 on success and errorno otherwise. 2459 2459 */ 2460 - int devm_pm_opp_attach_genpd(struct device *dev, const char **names, 2460 + int devm_pm_opp_attach_genpd(struct device *dev, const char * const *names, 2461 2461 struct device ***virt_devs) 2462 2462 { 2463 2463 struct opp_table *opp_table;
+41 -9
drivers/opp/of.c
··· 170 170 } 171 171 172 172 count = of_count_phandle_with_args(np, "required-opps", NULL); 173 - if (!count) 173 + if (count <= 0) 174 174 goto put_np; 175 175 176 176 required_opp_tables = kcalloc(count, sizeof(*required_opp_tables), ··· 921 921 free_opp: 922 922 _opp_free(new_opp); 923 923 924 - return ERR_PTR(ret); 924 + return ret ? ERR_PTR(ret) : NULL; 925 925 } 926 926 927 927 /* Initializes OPP tables based on new bindings */ ··· 1081 1081 dev_pm_opp_of_remove_table(data); 1082 1082 } 1083 1083 1084 + static int _devm_of_add_table_indexed(struct device *dev, int index, bool getclk) 1085 + { 1086 + int ret; 1087 + 1088 + ret = _of_add_table_indexed(dev, index, getclk); 1089 + if (ret) 1090 + return ret; 1091 + 1092 + return devm_add_action_or_reset(dev, devm_pm_opp_of_table_release, dev); 1093 + } 1094 + 1084 1095 /** 1085 1096 * devm_pm_opp_of_add_table() - Initialize opp table from device tree 1086 1097 * @dev: device pointer used to lookup OPP table. ··· 1113 1102 */ 1114 1103 int devm_pm_opp_of_add_table(struct device *dev) 1115 1104 { 1116 - int ret; 1117 - 1118 - ret = dev_pm_opp_of_add_table(dev); 1119 - if (ret) 1120 - return ret; 1121 - 1122 - return devm_add_action_or_reset(dev, devm_pm_opp_of_table_release, dev); 1105 + return _devm_of_add_table_indexed(dev, 0, true); 1123 1106 } 1124 1107 EXPORT_SYMBOL_GPL(devm_pm_opp_of_add_table); 1125 1108 ··· 1157 1152 EXPORT_SYMBOL_GPL(dev_pm_opp_of_add_table_indexed); 1158 1153 1159 1154 /** 1155 + * devm_pm_opp_of_add_table_indexed() - Initialize indexed opp table from device tree 1156 + * @dev: device pointer used to lookup OPP table. 1157 + * @index: Index number. 1158 + * 1159 + * This is a resource-managed variant of dev_pm_opp_of_add_table_indexed(). 1160 + */ 1161 + int devm_pm_opp_of_add_table_indexed(struct device *dev, int index) 1162 + { 1163 + return _devm_of_add_table_indexed(dev, index, true); 1164 + } 1165 + EXPORT_SYMBOL_GPL(devm_pm_opp_of_add_table_indexed); 1166 + 1167 + /** 1160 1168 * dev_pm_opp_of_add_table_noclk() - Initialize indexed opp table from device 1161 1169 * tree without getting clk for device. 1162 1170 * @dev: device pointer used to lookup OPP table. ··· 1186 1168 return _of_add_table_indexed(dev, index, false); 1187 1169 } 1188 1170 EXPORT_SYMBOL_GPL(dev_pm_opp_of_add_table_noclk); 1171 + 1172 + /** 1173 + * devm_pm_opp_of_add_table_noclk() - Initialize indexed opp table from device 1174 + * tree without getting clk for device. 1175 + * @dev: device pointer used to lookup OPP table. 1176 + * @index: Index number. 1177 + * 1178 + * This is a resource-managed variant of dev_pm_opp_of_add_table_noclk(). 1179 + */ 1180 + int devm_pm_opp_of_add_table_noclk(struct device *dev, int index) 1181 + { 1182 + return _devm_of_add_table_indexed(dev, index, false); 1183 + } 1184 + EXPORT_SYMBOL_GPL(devm_pm_opp_of_add_table_noclk); 1189 1185 1190 1186 /* CPU device specific helpers */ 1191 1187
+16 -4
include/linux/pm_opp.h
··· 156 156 struct opp_table *dev_pm_opp_register_set_opp_helper(struct device *dev, int (*set_opp)(struct dev_pm_set_opp_data *data)); 157 157 void dev_pm_opp_unregister_set_opp_helper(struct opp_table *opp_table); 158 158 int devm_pm_opp_register_set_opp_helper(struct device *dev, int (*set_opp)(struct dev_pm_set_opp_data *data)); 159 - struct opp_table *dev_pm_opp_attach_genpd(struct device *dev, const char **names, struct device ***virt_devs); 159 + struct opp_table *dev_pm_opp_attach_genpd(struct device *dev, const char * const *names, struct device ***virt_devs); 160 160 void dev_pm_opp_detach_genpd(struct opp_table *opp_table); 161 - int devm_pm_opp_attach_genpd(struct device *dev, const char **names, struct device ***virt_devs); 161 + int devm_pm_opp_attach_genpd(struct device *dev, const char * const *names, struct device ***virt_devs); 162 162 struct dev_pm_opp *dev_pm_opp_xlate_required_opp(struct opp_table *src_table, struct opp_table *dst_table, struct dev_pm_opp *src_opp); 163 163 int dev_pm_opp_xlate_performance_state(struct opp_table *src_table, struct opp_table *dst_table, unsigned int pstate); 164 164 int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq); ··· 376 376 return -EOPNOTSUPP; 377 377 } 378 378 379 - static inline struct opp_table *dev_pm_opp_attach_genpd(struct device *dev, const char **names, struct device ***virt_devs) 379 + static inline struct opp_table *dev_pm_opp_attach_genpd(struct device *dev, const char * const *names, struct device ***virt_devs) 380 380 { 381 381 return ERR_PTR(-EOPNOTSUPP); 382 382 } ··· 384 384 static inline void dev_pm_opp_detach_genpd(struct opp_table *opp_table) {} 385 385 386 386 static inline int devm_pm_opp_attach_genpd(struct device *dev, 387 - const char **names, 387 + const char * const *names, 388 388 struct device ***virt_devs) 389 389 { 390 390 return -EOPNOTSUPP; ··· 439 439 #if defined(CONFIG_PM_OPP) && defined(CONFIG_OF) 440 440 int dev_pm_opp_of_add_table(struct device *dev); 441 441 int dev_pm_opp_of_add_table_indexed(struct device *dev, int index); 442 + int devm_pm_opp_of_add_table_indexed(struct device *dev, int index); 442 443 int dev_pm_opp_of_add_table_noclk(struct device *dev, int index); 444 + int devm_pm_opp_of_add_table_noclk(struct device *dev, int index); 443 445 void dev_pm_opp_of_remove_table(struct device *dev); 444 446 int devm_pm_opp_of_add_table(struct device *dev); 445 447 int dev_pm_opp_of_cpumask_add_table(const struct cpumask *cpumask); ··· 467 465 return -EOPNOTSUPP; 468 466 } 469 467 468 + static inline int devm_pm_opp_of_add_table_indexed(struct device *dev, int index) 469 + { 470 + return -EOPNOTSUPP; 471 + } 472 + 470 473 static inline int dev_pm_opp_of_add_table_noclk(struct device *dev, int index) 474 + { 475 + return -EOPNOTSUPP; 476 + } 477 + 478 + static inline int devm_pm_opp_of_add_table_noclk(struct device *dev, int index) 471 479 { 472 480 return -EOPNOTSUPP; 473 481 }