aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2018-06-04 04:40:41 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2018-06-04 04:40:41 -0400
commitd9fecca2efea004c617e01b9eb7a36ef407e7b28 (patch)
tree6581aa6dce2733276278297ebf11fabcbf329e6d
parent5b550c92d704ad4b5f1081c62d515a137d1c4bd2 (diff)
parent96c1bf68852a1709bb411eafd3edcc59186eb293 (diff)
Merge branch 'pm-opp'
* pm-opp: (24 commits) PM / Domains: Drop unused parameter in genpd_allocate_dev_data() PM / Domains: Drop genpd as in-param for pm_genpd_remove_device() PM / Domains: Drop __pm_genpd_add_device() PM / Domains: Drop extern declarations of functions in pm_domain.h PM / domains: Add perf_state attribute to genpd debugfs OPP: Allow same OPP table to be used for multiple genpd PM / Domain: Return 0 on error from of_genpd_opp_to_performance_state() PM / OPP: Fix shared OPP table support in dev_pm_opp_register_set_opp_helper() PM / OPP: Fix shared OPP table support in dev_pm_opp_set_regulators() PM / OPP: Fix shared OPP table support in dev_pm_opp_set_prop_name() PM / OPP: Fix shared OPP table support in dev_pm_opp_set_supported_hw() PM / OPP: silence an uninitialized variable warning PM / OPP: Remove dev_pm_opp_{un}register_get_pstate_helper() PM / OPP: Get performance state using genpd helper PM / Domain: Implement of_genpd_opp_to_performance_state() PM / Domain: Add support to parse domain's OPP table PM / Domain: Add struct device to genpd PM / OPP: Implement dev_pm_opp_get_of_node() PM / OPP: Implement of_dev_pm_opp_find_required_opp() PM / OPP: Implement dev_pm_opp_of_add_table_indexed() ...
-rw-r--r--Documentation/devicetree/bindings/opp/opp.txt7
-rw-r--r--Documentation/devicetree/bindings/power/power_domain.txt6
-rw-r--r--drivers/base/power/domain.c167
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c2
-rw-r--r--drivers/opp/core.c267
-rw-r--r--drivers/opp/debugfs.c15
-rw-r--r--drivers/opp/of.c184
-rw-r--r--drivers/opp/opp.h6
-rw-r--r--drivers/soc/tegra/pmc.c20
-rw-r--r--include/linux/pm_domain.h75
-rw-r--r--include/linux/pm_opp.h27
11 files changed, 476 insertions, 300 deletions
diff --git a/Documentation/devicetree/bindings/opp/opp.txt b/Documentation/devicetree/bindings/opp/opp.txt
index 4e4f30288c8b..c396c4c0af92 100644
--- a/Documentation/devicetree/bindings/opp/opp.txt
+++ b/Documentation/devicetree/bindings/opp/opp.txt
@@ -82,7 +82,10 @@ This defines voltage-current-frequency combinations along with other related
82properties. 82properties.
83 83
84Required properties: 84Required properties:
85- opp-hz: Frequency in Hz, expressed as a 64-bit big-endian integer. 85- opp-hz: Frequency in Hz, expressed as a 64-bit big-endian integer. This is a
86 required property for all device nodes but devices like power domains. The
87 power domain nodes must have another (implementation dependent) property which
88 uniquely identifies the OPP nodes.
86 89
87Optional properties: 90Optional properties:
88- opp-microvolt: voltage in micro Volts. 91- opp-microvolt: voltage in micro Volts.
@@ -159,7 +162,7 @@ Optional properties:
159 162
160- status: Marks the node enabled/disabled. 163- status: Marks the node enabled/disabled.
161 164
162- required-opp: This contains phandle to an OPP node in another device's OPP 165- required-opps: This contains phandle to an OPP node in another device's OPP
163 table. It may contain an array of phandles, where each phandle points to an 166 table. It may contain an array of phandles, where each phandle points to an
164 OPP of a different device. It should not contain multiple phandles to the OPP 167 OPP of a different device. It should not contain multiple phandles to the OPP
165 nodes in the same OPP table. This specifies the minimum required OPP of the 168 nodes in the same OPP table. This specifies the minimum required OPP of the
diff --git a/Documentation/devicetree/bindings/power/power_domain.txt b/Documentation/devicetree/bindings/power/power_domain.txt
index f3355313c020..4733f76cbe48 100644
--- a/Documentation/devicetree/bindings/power/power_domain.txt
+++ b/Documentation/devicetree/bindings/power/power_domain.txt
@@ -127,7 +127,7 @@ inside a PM domain with index 0 of a power controller represented by a node
127with the label "power". 127with the label "power".
128 128
129Optional properties: 129Optional properties:
130- required-opp: This contains phandle to an OPP node in another device's OPP 130- required-opps: This contains phandle to an OPP node in another device's OPP
131 table. It may contain an array of phandles, where each phandle points to an 131 table. It may contain an array of phandles, where each phandle points to an
132 OPP of a different device. It should not contain multiple phandles to the OPP 132 OPP of a different device. It should not contain multiple phandles to the OPP
133 nodes in the same OPP table. This specifies the minimum required OPP of the 133 nodes in the same OPP table. This specifies the minimum required OPP of the
@@ -175,14 +175,14 @@ Example:
175 compatible = "foo,i-leak-current"; 175 compatible = "foo,i-leak-current";
176 reg = <0x12350000 0x1000>; 176 reg = <0x12350000 0x1000>;
177 power-domains = <&power 0>; 177 power-domains = <&power 0>;
178 required-opp = <&domain0_opp_0>; 178 required-opps = <&domain0_opp_0>;
179 }; 179 };
180 180
181 leaky-device1@12350000 { 181 leaky-device1@12350000 {
182 compatible = "foo,i-leak-current"; 182 compatible = "foo,i-leak-current";
183 reg = <0x12350000 0x1000>; 183 reg = <0x12350000 0x1000>;
184 power-domains = <&power 1>; 184 power-domains = <&power 1>;
185 required-opp = <&domain1_opp_1>; 185 required-opps = <&domain1_opp_1>;
186 }; 186 };
187 187
188[1]. Documentation/devicetree/bindings/power/domain-idle-state.txt 188[1]. Documentation/devicetree/bindings/power/domain-idle-state.txt
diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
index 455ecea6c812..6f403d6fccb2 100644
--- a/drivers/base/power/domain.c
+++ b/drivers/base/power/domain.c
@@ -10,6 +10,7 @@
10#include <linux/kernel.h> 10#include <linux/kernel.h>
11#include <linux/io.h> 11#include <linux/io.h>
12#include <linux/platform_device.h> 12#include <linux/platform_device.h>
13#include <linux/pm_opp.h>
13#include <linux/pm_runtime.h> 14#include <linux/pm_runtime.h>
14#include <linux/pm_domain.h> 15#include <linux/pm_domain.h>
15#include <linux/pm_qos.h> 16#include <linux/pm_qos.h>
@@ -1315,7 +1316,6 @@ EXPORT_SYMBOL_GPL(pm_genpd_syscore_poweron);
1315#endif /* CONFIG_PM_SLEEP */ 1316#endif /* CONFIG_PM_SLEEP */
1316 1317
1317static struct generic_pm_domain_data *genpd_alloc_dev_data(struct device *dev, 1318static struct generic_pm_domain_data *genpd_alloc_dev_data(struct device *dev,
1318 struct generic_pm_domain *genpd,
1319 struct gpd_timing_data *td) 1319 struct gpd_timing_data *td)
1320{ 1320{
1321 struct generic_pm_domain_data *gpd_data; 1321 struct generic_pm_domain_data *gpd_data;
@@ -1384,7 +1384,7 @@ static int genpd_add_device(struct generic_pm_domain *genpd, struct device *dev,
1384 if (IS_ERR_OR_NULL(genpd) || IS_ERR_OR_NULL(dev)) 1384 if (IS_ERR_OR_NULL(genpd) || IS_ERR_OR_NULL(dev))
1385 return -EINVAL; 1385 return -EINVAL;
1386 1386
1387 gpd_data = genpd_alloc_dev_data(dev, genpd, td); 1387 gpd_data = genpd_alloc_dev_data(dev, td);
1388 if (IS_ERR(gpd_data)) 1388 if (IS_ERR(gpd_data))
1389 return PTR_ERR(gpd_data); 1389 return PTR_ERR(gpd_data);
1390 1390
@@ -1413,23 +1413,21 @@ static int genpd_add_device(struct generic_pm_domain *genpd, struct device *dev,
1413} 1413}
1414 1414
1415/** 1415/**
1416 * __pm_genpd_add_device - Add a device to an I/O PM domain. 1416 * pm_genpd_add_device - Add a device to an I/O PM domain.
1417 * @genpd: PM domain to add the device to. 1417 * @genpd: PM domain to add the device to.
1418 * @dev: Device to be added. 1418 * @dev: Device to be added.
1419 * @td: Set of PM QoS timing parameters to attach to the device.
1420 */ 1419 */
1421int __pm_genpd_add_device(struct generic_pm_domain *genpd, struct device *dev, 1420int pm_genpd_add_device(struct generic_pm_domain *genpd, struct device *dev)
1422 struct gpd_timing_data *td)
1423{ 1421{
1424 int ret; 1422 int ret;
1425 1423
1426 mutex_lock(&gpd_list_lock); 1424 mutex_lock(&gpd_list_lock);
1427 ret = genpd_add_device(genpd, dev, td); 1425 ret = genpd_add_device(genpd, dev, NULL);
1428 mutex_unlock(&gpd_list_lock); 1426 mutex_unlock(&gpd_list_lock);
1429 1427
1430 return ret; 1428 return ret;
1431} 1429}
1432EXPORT_SYMBOL_GPL(__pm_genpd_add_device); 1430EXPORT_SYMBOL_GPL(pm_genpd_add_device);
1433 1431
1434static int genpd_remove_device(struct generic_pm_domain *genpd, 1432static int genpd_remove_device(struct generic_pm_domain *genpd,
1435 struct device *dev) 1433 struct device *dev)
@@ -1476,13 +1474,13 @@ static int genpd_remove_device(struct generic_pm_domain *genpd,
1476 1474
1477/** 1475/**
1478 * pm_genpd_remove_device - Remove a device from an I/O PM domain. 1476 * pm_genpd_remove_device - Remove a device from an I/O PM domain.
1479 * @genpd: PM domain to remove the device from.
1480 * @dev: Device to be removed. 1477 * @dev: Device to be removed.
1481 */ 1478 */
1482int pm_genpd_remove_device(struct generic_pm_domain *genpd, 1479int pm_genpd_remove_device(struct device *dev)
1483 struct device *dev)
1484{ 1480{
1485 if (!genpd || genpd != genpd_lookup_dev(dev)) 1481 struct generic_pm_domain *genpd = genpd_lookup_dev(dev);
1482
1483 if (!genpd)
1486 return -EINVAL; 1484 return -EINVAL;
1487 1485
1488 return genpd_remove_device(genpd, dev); 1486 return genpd_remove_device(genpd, dev);
@@ -1691,6 +1689,9 @@ int pm_genpd_init(struct generic_pm_domain *genpd,
1691 return ret; 1689 return ret;
1692 } 1690 }
1693 1691
1692 device_initialize(&genpd->dev);
1693 dev_set_name(&genpd->dev, "%s", genpd->name);
1694
1694 mutex_lock(&gpd_list_lock); 1695 mutex_lock(&gpd_list_lock);
1695 list_add(&genpd->gpd_list_node, &gpd_list); 1696 list_add(&genpd->gpd_list_node, &gpd_list);
1696 mutex_unlock(&gpd_list_lock); 1697 mutex_unlock(&gpd_list_lock);
@@ -1887,14 +1888,33 @@ int of_genpd_add_provider_simple(struct device_node *np,
1887 1888
1888 mutex_lock(&gpd_list_lock); 1889 mutex_lock(&gpd_list_lock);
1889 1890
1890 if (genpd_present(genpd)) { 1891 if (!genpd_present(genpd))
1891 ret = genpd_add_provider(np, genpd_xlate_simple, genpd); 1892 goto unlock;
1892 if (!ret) { 1893
1893 genpd->provider = &np->fwnode; 1894 genpd->dev.of_node = np;
1894 genpd->has_provider = true; 1895
1896 /* Parse genpd OPP table */
1897 if (genpd->set_performance_state) {
1898 ret = dev_pm_opp_of_add_table(&genpd->dev);
1899 if (ret) {
1900 dev_err(&genpd->dev, "Failed to add OPP table: %d\n",
1901 ret);
1902 goto unlock;
1895 } 1903 }
1896 } 1904 }
1897 1905
1906 ret = genpd_add_provider(np, genpd_xlate_simple, genpd);
1907 if (ret) {
1908 if (genpd->set_performance_state)
1909 dev_pm_opp_of_remove_table(&genpd->dev);
1910
1911 goto unlock;
1912 }
1913
1914 genpd->provider = &np->fwnode;
1915 genpd->has_provider = true;
1916
1917unlock:
1898 mutex_unlock(&gpd_list_lock); 1918 mutex_unlock(&gpd_list_lock);
1899 1919
1900 return ret; 1920 return ret;
@@ -1909,6 +1929,7 @@ EXPORT_SYMBOL_GPL(of_genpd_add_provider_simple);
1909int of_genpd_add_provider_onecell(struct device_node *np, 1929int of_genpd_add_provider_onecell(struct device_node *np,
1910 struct genpd_onecell_data *data) 1930 struct genpd_onecell_data *data)
1911{ 1931{
1932 struct generic_pm_domain *genpd;
1912 unsigned int i; 1933 unsigned int i;
1913 int ret = -EINVAL; 1934 int ret = -EINVAL;
1914 1935
@@ -1921,13 +1942,27 @@ int of_genpd_add_provider_onecell(struct device_node *np,
1921 data->xlate = genpd_xlate_onecell; 1942 data->xlate = genpd_xlate_onecell;
1922 1943
1923 for (i = 0; i < data->num_domains; i++) { 1944 for (i = 0; i < data->num_domains; i++) {
1924 if (!data->domains[i]) 1945 genpd = data->domains[i];
1946
1947 if (!genpd)
1925 continue; 1948 continue;
1926 if (!genpd_present(data->domains[i])) 1949 if (!genpd_present(genpd))
1927 goto error; 1950 goto error;
1928 1951
1929 data->domains[i]->provider = &np->fwnode; 1952 genpd->dev.of_node = np;
1930 data->domains[i]->has_provider = true; 1953
1954 /* Parse genpd OPP table */
1955 if (genpd->set_performance_state) {
1956 ret = dev_pm_opp_of_add_table_indexed(&genpd->dev, i);
1957 if (ret) {
1958 dev_err(&genpd->dev, "Failed to add OPP table for index %d: %d\n",
1959 i, ret);
1960 goto error;
1961 }
1962 }
1963
1964 genpd->provider = &np->fwnode;
1965 genpd->has_provider = true;
1931 } 1966 }
1932 1967
1933 ret = genpd_add_provider(np, data->xlate, data); 1968 ret = genpd_add_provider(np, data->xlate, data);
@@ -1940,10 +1975,16 @@ int of_genpd_add_provider_onecell(struct device_node *np,
1940 1975
1941error: 1976error:
1942 while (i--) { 1977 while (i--) {
1943 if (!data->domains[i]) 1978 genpd = data->domains[i];
1979
1980 if (!genpd)
1944 continue; 1981 continue;
1945 data->domains[i]->provider = NULL; 1982
1946 data->domains[i]->has_provider = false; 1983 genpd->provider = NULL;
1984 genpd->has_provider = false;
1985
1986 if (genpd->set_performance_state)
1987 dev_pm_opp_of_remove_table(&genpd->dev);
1947 } 1988 }
1948 1989
1949 mutex_unlock(&gpd_list_lock); 1990 mutex_unlock(&gpd_list_lock);
@@ -1970,10 +2011,17 @@ void of_genpd_del_provider(struct device_node *np)
1970 * provider, set the 'has_provider' to false 2011 * provider, set the 'has_provider' to false
1971 * so that the PM domain can be safely removed. 2012 * so that the PM domain can be safely removed.
1972 */ 2013 */
1973 list_for_each_entry(gpd, &gpd_list, gpd_list_node) 2014 list_for_each_entry(gpd, &gpd_list, gpd_list_node) {
1974 if (gpd->provider == &np->fwnode) 2015 if (gpd->provider == &np->fwnode) {
1975 gpd->has_provider = false; 2016 gpd->has_provider = false;
1976 2017
2018 if (!gpd->set_performance_state)
2019 continue;
2020
2021 dev_pm_opp_of_remove_table(&gpd->dev);
2022 }
2023 }
2024
1977 list_del(&cp->link); 2025 list_del(&cp->link);
1978 of_node_put(cp->node); 2026 of_node_put(cp->node);
1979 kfree(cp); 2027 kfree(cp);
@@ -2346,6 +2394,55 @@ int of_genpd_parse_idle_states(struct device_node *dn,
2346} 2394}
2347EXPORT_SYMBOL_GPL(of_genpd_parse_idle_states); 2395EXPORT_SYMBOL_GPL(of_genpd_parse_idle_states);
2348 2396
2397/**
2398 * of_genpd_opp_to_performance_state- Gets performance state of device's
2399 * power domain corresponding to a DT node's "required-opps" property.
2400 *
2401 * @dev: Device for which the performance-state needs to be found.
2402 * @opp_node: DT node where the "required-opps" property is present. This can be
2403 * the device node itself (if it doesn't have an OPP table) or a node
2404 * within the OPP table of a device (if device has an OPP table).
2405 * @state: Pointer to return performance state.
2406 *
2407 * Returns performance state corresponding to the "required-opps" property of
2408 * a DT node. This calls platform specific genpd->opp_to_performance_state()
2409 * callback to translate power domain OPP to performance state.
2410 *
2411 * Returns performance state on success and 0 on failure.
2412 */
2413unsigned int of_genpd_opp_to_performance_state(struct device *dev,
2414 struct device_node *opp_node)
2415{
2416 struct generic_pm_domain *genpd;
2417 struct dev_pm_opp *opp;
2418 int state = 0;
2419
2420 genpd = dev_to_genpd(dev);
2421 if (IS_ERR(genpd))
2422 return 0;
2423
2424 if (unlikely(!genpd->set_performance_state))
2425 return 0;
2426
2427 genpd_lock(genpd);
2428
2429 opp = of_dev_pm_opp_find_required_opp(&genpd->dev, opp_node);
2430 if (IS_ERR(opp)) {
2431 dev_err(dev, "Failed to find required OPP: %ld\n",
2432 PTR_ERR(opp));
2433 goto unlock;
2434 }
2435
2436 state = genpd->opp_to_performance_state(genpd, opp);
2437 dev_pm_opp_put(opp);
2438
2439unlock:
2440 genpd_unlock(genpd);
2441
2442 return state;
2443}
2444EXPORT_SYMBOL_GPL(of_genpd_opp_to_performance_state);
2445
2349#endif /* CONFIG_PM_GENERIC_DOMAINS_OF */ 2446#endif /* CONFIG_PM_GENERIC_DOMAINS_OF */
2350 2447
2351 2448
@@ -2613,6 +2710,19 @@ static int genpd_devices_show(struct seq_file *s, void *data)
2613 return ret; 2710 return ret;
2614} 2711}
2615 2712
2713static int genpd_perf_state_show(struct seq_file *s, void *data)
2714{
2715 struct generic_pm_domain *genpd = s->private;
2716
2717 if (genpd_lock_interruptible(genpd))
2718 return -ERESTARTSYS;
2719
2720 seq_printf(s, "%u\n", genpd->performance_state);
2721
2722 genpd_unlock(genpd);
2723 return 0;
2724}
2725
2616#define define_genpd_open_function(name) \ 2726#define define_genpd_open_function(name) \
2617static int genpd_##name##_open(struct inode *inode, struct file *file) \ 2727static int genpd_##name##_open(struct inode *inode, struct file *file) \
2618{ \ 2728{ \
@@ -2626,6 +2736,7 @@ define_genpd_open_function(idle_states);
2626define_genpd_open_function(active_time); 2736define_genpd_open_function(active_time);
2627define_genpd_open_function(total_idle_time); 2737define_genpd_open_function(total_idle_time);
2628define_genpd_open_function(devices); 2738define_genpd_open_function(devices);
2739define_genpd_open_function(perf_state);
2629 2740
2630#define define_genpd_debugfs_fops(name) \ 2741#define define_genpd_debugfs_fops(name) \
2631static const struct file_operations genpd_##name##_fops = { \ 2742static const struct file_operations genpd_##name##_fops = { \
@@ -2642,6 +2753,7 @@ define_genpd_debugfs_fops(idle_states);
2642define_genpd_debugfs_fops(active_time); 2753define_genpd_debugfs_fops(active_time);
2643define_genpd_debugfs_fops(total_idle_time); 2754define_genpd_debugfs_fops(total_idle_time);
2644define_genpd_debugfs_fops(devices); 2755define_genpd_debugfs_fops(devices);
2756define_genpd_debugfs_fops(perf_state);
2645 2757
2646static int __init genpd_debug_init(void) 2758static int __init genpd_debug_init(void)
2647{ 2759{
@@ -2675,6 +2787,9 @@ static int __init genpd_debug_init(void)
2675 d, genpd, &genpd_total_idle_time_fops); 2787 d, genpd, &genpd_total_idle_time_fops);
2676 debugfs_create_file("devices", 0444, 2788 debugfs_create_file("devices", 0444,
2677 d, genpd, &genpd_devices_fops); 2789 d, genpd, &genpd_devices_fops);
2790 if (genpd->set_performance_state)
2791 debugfs_create_file("perf_state", 0444,
2792 d, genpd, &genpd_perf_state_fops);
2678 } 2793 }
2679 2794
2680 return 0; 2795 return 0;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c
index a29362f9ef41..12558044acd4 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c
@@ -513,7 +513,7 @@ static int acp_hw_fini(void *handle)
513 if (adev->acp.acp_genpd) { 513 if (adev->acp.acp_genpd) {
514 for (i = 0; i < ACP_DEVS ; i++) { 514 for (i = 0; i < ACP_DEVS ; i++) {
515 dev = get_mfd_cell_dev(adev->acp.acp_cell[i].name, i); 515 dev = get_mfd_cell_dev(adev->acp.acp_cell[i].name, i);
516 ret = pm_genpd_remove_device(&adev->acp.acp_genpd->gpd, dev); 516 ret = pm_genpd_remove_device(dev);
517 /* If removal fails, dont giveup and try rest */ 517 /* If removal fails, dont giveup and try rest */
518 if (ret) 518 if (ret)
519 dev_err(dev, "remove dev from genpd failed\n"); 519 dev_err(dev, "remove dev from genpd failed\n");
diff --git a/drivers/opp/core.c b/drivers/opp/core.c
index 92fa94a6dcc1..ab2f3fead6b1 100644
--- a/drivers/opp/core.c
+++ b/drivers/opp/core.c
@@ -33,8 +33,6 @@ LIST_HEAD(opp_tables);
33/* Lock to allow exclusive modification to the device and opp lists */ 33/* Lock to allow exclusive modification to the device and opp lists */
34DEFINE_MUTEX(opp_table_lock); 34DEFINE_MUTEX(opp_table_lock);
35 35
36static void dev_pm_opp_get(struct dev_pm_opp *opp);
37
38static struct opp_device *_find_opp_dev(const struct device *dev, 36static struct opp_device *_find_opp_dev(const struct device *dev,
39 struct opp_table *opp_table) 37 struct opp_table *opp_table)
40{ 38{
@@ -281,6 +279,23 @@ unsigned long dev_pm_opp_get_suspend_opp_freq(struct device *dev)
281} 279}
282EXPORT_SYMBOL_GPL(dev_pm_opp_get_suspend_opp_freq); 280EXPORT_SYMBOL_GPL(dev_pm_opp_get_suspend_opp_freq);
283 281
282int _get_opp_count(struct opp_table *opp_table)
283{
284 struct dev_pm_opp *opp;
285 int count = 0;
286
287 mutex_lock(&opp_table->lock);
288
289 list_for_each_entry(opp, &opp_table->opp_list, node) {
290 if (opp->available)
291 count++;
292 }
293
294 mutex_unlock(&opp_table->lock);
295
296 return count;
297}
298
284/** 299/**
285 * dev_pm_opp_get_opp_count() - Get number of opps available in the opp table 300 * dev_pm_opp_get_opp_count() - Get number of opps available in the opp table
286 * @dev: device for which we do this operation 301 * @dev: device for which we do this operation
@@ -291,25 +306,17 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_get_suspend_opp_freq);
291int dev_pm_opp_get_opp_count(struct device *dev) 306int dev_pm_opp_get_opp_count(struct device *dev)
292{ 307{
293 struct opp_table *opp_table; 308 struct opp_table *opp_table;
294 struct dev_pm_opp *temp_opp; 309 int count;
295 int count = 0;
296 310
297 opp_table = _find_opp_table(dev); 311 opp_table = _find_opp_table(dev);
298 if (IS_ERR(opp_table)) { 312 if (IS_ERR(opp_table)) {
299 count = PTR_ERR(opp_table); 313 count = PTR_ERR(opp_table);
300 dev_dbg(dev, "%s: OPP table not found (%d)\n", 314 dev_dbg(dev, "%s: OPP table not found (%d)\n",
301 __func__, count); 315 __func__, count);
302 return count; 316 return 0;
303 }
304
305 mutex_lock(&opp_table->lock);
306
307 list_for_each_entry(temp_opp, &opp_table->opp_list, node) {
308 if (temp_opp->available)
309 count++;
310 } 317 }
311 318
312 mutex_unlock(&opp_table->lock); 319 count = _get_opp_count(opp_table);
313 dev_pm_opp_put_opp_table(opp_table); 320 dev_pm_opp_put_opp_table(opp_table);
314 321
315 return count; 322 return count;
@@ -892,7 +899,7 @@ static void _opp_kref_release(struct kref *kref)
892 dev_pm_opp_put_opp_table(opp_table); 899 dev_pm_opp_put_opp_table(opp_table);
893} 900}
894 901
895static void dev_pm_opp_get(struct dev_pm_opp *opp) 902void dev_pm_opp_get(struct dev_pm_opp *opp)
896{ 903{
897 kref_get(&opp->kref); 904 kref_get(&opp->kref);
898} 905}
@@ -985,22 +992,11 @@ static bool _opp_supported_by_regulators(struct dev_pm_opp *opp,
985 return true; 992 return true;
986} 993}
987 994
988/* 995static int _opp_is_duplicate(struct device *dev, struct dev_pm_opp *new_opp,
989 * Returns: 996 struct opp_table *opp_table,
990 * 0: On success. And appropriate error message for duplicate OPPs. 997 struct list_head **head)
991 * -EBUSY: For OPP with same freq/volt and is available. The callers of
992 * _opp_add() must return 0 if they receive -EBUSY from it. This is to make
993 * sure we don't print error messages unnecessarily if different parts of
994 * kernel try to initialize the OPP table.
995 * -EEXIST: For OPP with same freq but different volt or is unavailable. This
996 * should be considered an error by the callers of _opp_add().
997 */
998int _opp_add(struct device *dev, struct dev_pm_opp *new_opp,
999 struct opp_table *opp_table)
1000{ 998{
1001 struct dev_pm_opp *opp; 999 struct dev_pm_opp *opp;
1002 struct list_head *head;
1003 int ret;
1004 1000
1005 /* 1001 /*
1006 * Insert new OPP in order of increasing frequency and discard if 1002 * Insert new OPP in order of increasing frequency and discard if
@@ -1010,17 +1006,14 @@ int _opp_add(struct device *dev, struct dev_pm_opp *new_opp,
1010 * loop, don't replace it with head otherwise it will become an infinite 1006 * loop, don't replace it with head otherwise it will become an infinite
1011 * loop. 1007 * loop.
1012 */ 1008 */
1013 mutex_lock(&opp_table->lock);
1014 head = &opp_table->opp_list;
1015
1016 list_for_each_entry(opp, &opp_table->opp_list, node) { 1009 list_for_each_entry(opp, &opp_table->opp_list, node) {
1017 if (new_opp->rate > opp->rate) { 1010 if (new_opp->rate > opp->rate) {
1018 head = &opp->node; 1011 *head = &opp->node;
1019 continue; 1012 continue;
1020 } 1013 }
1021 1014
1022 if (new_opp->rate < opp->rate) 1015 if (new_opp->rate < opp->rate)
1023 break; 1016 return 0;
1024 1017
1025 /* Duplicate OPPs */ 1018 /* Duplicate OPPs */
1026 dev_warn(dev, "%s: duplicate OPPs detected. Existing: freq: %lu, volt: %lu, enabled: %d. New: freq: %lu, volt: %lu, enabled: %d\n", 1019 dev_warn(dev, "%s: duplicate OPPs detected. Existing: freq: %lu, volt: %lu, enabled: %d. New: freq: %lu, volt: %lu, enabled: %d\n",
@@ -1029,15 +1022,39 @@ int _opp_add(struct device *dev, struct dev_pm_opp *new_opp,
1029 new_opp->supplies[0].u_volt, new_opp->available); 1022 new_opp->supplies[0].u_volt, new_opp->available);
1030 1023
1031 /* Should we compare voltages for all regulators here ? */ 1024 /* Should we compare voltages for all regulators here ? */
1032 ret = opp->available && 1025 return opp->available &&
1033 new_opp->supplies[0].u_volt == opp->supplies[0].u_volt ? -EBUSY : -EEXIST; 1026 new_opp->supplies[0].u_volt == opp->supplies[0].u_volt ? -EBUSY : -EEXIST;
1034
1035 mutex_unlock(&opp_table->lock);
1036 return ret;
1037 } 1027 }
1038 1028
1039 if (opp_table->get_pstate) 1029 return 0;
1040 new_opp->pstate = opp_table->get_pstate(dev, new_opp->rate); 1030}
1031
1032/*
1033 * Returns:
1034 * 0: On success. And appropriate error message for duplicate OPPs.
1035 * -EBUSY: For OPP with same freq/volt and is available. The callers of
1036 * _opp_add() must return 0 if they receive -EBUSY from it. This is to make
1037 * sure we don't print error messages unnecessarily if different parts of
1038 * kernel try to initialize the OPP table.
1039 * -EEXIST: For OPP with same freq but different volt or is unavailable. This
1040 * should be considered an error by the callers of _opp_add().
1041 */
1042int _opp_add(struct device *dev, struct dev_pm_opp *new_opp,
1043 struct opp_table *opp_table, bool rate_not_available)
1044{
1045 struct list_head *head;
1046 int ret;
1047
1048 mutex_lock(&opp_table->lock);
1049 head = &opp_table->opp_list;
1050
1051 if (likely(!rate_not_available)) {
1052 ret = _opp_is_duplicate(dev, new_opp, opp_table, &head);
1053 if (ret) {
1054 mutex_unlock(&opp_table->lock);
1055 return ret;
1056 }
1057 }
1041 1058
1042 list_add(&new_opp->node, head); 1059 list_add(&new_opp->node, head);
1043 mutex_unlock(&opp_table->lock); 1060 mutex_unlock(&opp_table->lock);
@@ -1104,7 +1121,7 @@ int _opp_add_v1(struct opp_table *opp_table, struct device *dev,
1104 new_opp->available = true; 1121 new_opp->available = true;
1105 new_opp->dynamic = dynamic; 1122 new_opp->dynamic = dynamic;
1106 1123
1107 ret = _opp_add(dev, new_opp, opp_table); 1124 ret = _opp_add(dev, new_opp, opp_table, false);
1108 if (ret) { 1125 if (ret) {
1109 /* Don't return error for duplicate OPPs */ 1126 /* Don't return error for duplicate OPPs */
1110 if (ret == -EBUSY) 1127 if (ret == -EBUSY)
@@ -1140,7 +1157,6 @@ struct opp_table *dev_pm_opp_set_supported_hw(struct device *dev,
1140 const u32 *versions, unsigned int count) 1157 const u32 *versions, unsigned int count)
1141{ 1158{
1142 struct opp_table *opp_table; 1159 struct opp_table *opp_table;
1143 int ret;
1144 1160
1145 opp_table = dev_pm_opp_get_opp_table(dev); 1161 opp_table = dev_pm_opp_get_opp_table(dev);
1146 if (!opp_table) 1162 if (!opp_table)
@@ -1149,29 +1165,20 @@ struct opp_table *dev_pm_opp_set_supported_hw(struct device *dev,
1149 /* Make sure there are no concurrent readers while updating opp_table */ 1165 /* Make sure there are no concurrent readers while updating opp_table */
1150 WARN_ON(!list_empty(&opp_table->opp_list)); 1166 WARN_ON(!list_empty(&opp_table->opp_list));
1151 1167
1152 /* Do we already have a version hierarchy associated with opp_table? */ 1168 /* Another CPU that shares the OPP table has set the property ? */
1153 if (opp_table->supported_hw) { 1169 if (opp_table->supported_hw)
1154 dev_err(dev, "%s: Already have supported hardware list\n", 1170 return opp_table;
1155 __func__);
1156 ret = -EBUSY;
1157 goto err;
1158 }
1159 1171
1160 opp_table->supported_hw = kmemdup(versions, count * sizeof(*versions), 1172 opp_table->supported_hw = kmemdup(versions, count * sizeof(*versions),
1161 GFP_KERNEL); 1173 GFP_KERNEL);
1162 if (!opp_table->supported_hw) { 1174 if (!opp_table->supported_hw) {
1163 ret = -ENOMEM; 1175 dev_pm_opp_put_opp_table(opp_table);
1164 goto err; 1176 return ERR_PTR(-ENOMEM);
1165 } 1177 }
1166 1178
1167 opp_table->supported_hw_count = count; 1179 opp_table->supported_hw_count = count;
1168 1180
1169 return opp_table; 1181 return opp_table;
1170
1171err:
1172 dev_pm_opp_put_opp_table(opp_table);
1173
1174 return ERR_PTR(ret);
1175} 1182}
1176EXPORT_SYMBOL_GPL(dev_pm_opp_set_supported_hw); 1183EXPORT_SYMBOL_GPL(dev_pm_opp_set_supported_hw);
1177 1184
@@ -1188,12 +1195,6 @@ void dev_pm_opp_put_supported_hw(struct opp_table *opp_table)
1188 /* Make sure there are no concurrent readers while updating opp_table */ 1195 /* Make sure there are no concurrent readers while updating opp_table */
1189 WARN_ON(!list_empty(&opp_table->opp_list)); 1196 WARN_ON(!list_empty(&opp_table->opp_list));
1190 1197
1191 if (!opp_table->supported_hw) {
1192 pr_err("%s: Doesn't have supported hardware list\n",
1193 __func__);
1194 return;
1195 }
1196
1197 kfree(opp_table->supported_hw); 1198 kfree(opp_table->supported_hw);
1198 opp_table->supported_hw = NULL; 1199 opp_table->supported_hw = NULL;
1199 opp_table->supported_hw_count = 0; 1200 opp_table->supported_hw_count = 0;
@@ -1215,7 +1216,6 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_put_supported_hw);
1215struct opp_table *dev_pm_opp_set_prop_name(struct device *dev, const char *name) 1216struct opp_table *dev_pm_opp_set_prop_name(struct device *dev, const char *name)
1216{ 1217{
1217 struct opp_table *opp_table; 1218 struct opp_table *opp_table;
1218 int ret;
1219 1219
1220 opp_table = dev_pm_opp_get_opp_table(dev); 1220 opp_table = dev_pm_opp_get_opp_table(dev);
1221 if (!opp_table) 1221 if (!opp_table)
@@ -1224,26 +1224,17 @@ struct opp_table *dev_pm_opp_set_prop_name(struct device *dev, const char *name)
1224 /* Make sure there are no concurrent readers while updating opp_table */ 1224 /* Make sure there are no concurrent readers while updating opp_table */
1225 WARN_ON(!list_empty(&opp_table->opp_list)); 1225 WARN_ON(!list_empty(&opp_table->opp_list));
1226 1226
1227 /* Do we already have a prop-name associated with opp_table? */ 1227 /* Another CPU that shares the OPP table has set the property ? */
1228 if (opp_table->prop_name) { 1228 if (opp_table->prop_name)
1229 dev_err(dev, "%s: Already have prop-name %s\n", __func__, 1229 return opp_table;
1230 opp_table->prop_name);
1231 ret = -EBUSY;
1232 goto err;
1233 }
1234 1230
1235 opp_table->prop_name = kstrdup(name, GFP_KERNEL); 1231 opp_table->prop_name = kstrdup(name, GFP_KERNEL);
1236 if (!opp_table->prop_name) { 1232 if (!opp_table->prop_name) {
1237 ret = -ENOMEM; 1233 dev_pm_opp_put_opp_table(opp_table);
1238 goto err; 1234 return ERR_PTR(-ENOMEM);
1239 } 1235 }
1240 1236
1241 return opp_table; 1237 return opp_table;
1242
1243err:
1244 dev_pm_opp_put_opp_table(opp_table);
1245
1246 return ERR_PTR(ret);
1247} 1238}
1248EXPORT_SYMBOL_GPL(dev_pm_opp_set_prop_name); 1239EXPORT_SYMBOL_GPL(dev_pm_opp_set_prop_name);
1249 1240
@@ -1260,11 +1251,6 @@ void dev_pm_opp_put_prop_name(struct opp_table *opp_table)
1260 /* Make sure there are no concurrent readers while updating opp_table */ 1251 /* Make sure there are no concurrent readers while updating opp_table */
1261 WARN_ON(!list_empty(&opp_table->opp_list)); 1252 WARN_ON(!list_empty(&opp_table->opp_list));
1262 1253
1263 if (!opp_table->prop_name) {
1264 pr_err("%s: Doesn't have a prop-name\n", __func__);
1265 return;
1266 }
1267
1268 kfree(opp_table->prop_name); 1254 kfree(opp_table->prop_name);
1269 opp_table->prop_name = NULL; 1255 opp_table->prop_name = NULL;
1270 1256
@@ -1334,11 +1320,9 @@ struct opp_table *dev_pm_opp_set_regulators(struct device *dev,
1334 goto err; 1320 goto err;
1335 } 1321 }
1336 1322
1337 /* Already have regulators set */ 1323 /* Another CPU that shares the OPP table has set the regulators ? */
1338 if (opp_table->regulators) { 1324 if (opp_table->regulators)
1339 ret = -EBUSY; 1325 return opp_table;
1340 goto err;
1341 }
1342 1326
1343 opp_table->regulators = kmalloc_array(count, 1327 opp_table->regulators = kmalloc_array(count,
1344 sizeof(*opp_table->regulators), 1328 sizeof(*opp_table->regulators),
@@ -1392,10 +1376,8 @@ void dev_pm_opp_put_regulators(struct opp_table *opp_table)
1392{ 1376{
1393 int i; 1377 int i;
1394 1378
1395 if (!opp_table->regulators) { 1379 if (!opp_table->regulators)
1396 pr_err("%s: Doesn't have regulators set\n", __func__); 1380 goto put_opp_table;
1397 return;
1398 }
1399 1381
1400 /* Make sure there are no concurrent readers while updating opp_table */ 1382 /* Make sure there are no concurrent readers while updating opp_table */
1401 WARN_ON(!list_empty(&opp_table->opp_list)); 1383 WARN_ON(!list_empty(&opp_table->opp_list));
@@ -1409,6 +1391,7 @@ void dev_pm_opp_put_regulators(struct opp_table *opp_table)
1409 opp_table->regulators = NULL; 1391 opp_table->regulators = NULL;
1410 opp_table->regulator_count = 0; 1392 opp_table->regulator_count = 0;
1411 1393
1394put_opp_table:
1412 dev_pm_opp_put_opp_table(opp_table); 1395 dev_pm_opp_put_opp_table(opp_table);
1413} 1396}
1414EXPORT_SYMBOL_GPL(dev_pm_opp_put_regulators); 1397EXPORT_SYMBOL_GPL(dev_pm_opp_put_regulators);
@@ -1494,7 +1477,6 @@ struct opp_table *dev_pm_opp_register_set_opp_helper(struct device *dev,
1494 int (*set_opp)(struct dev_pm_set_opp_data *data)) 1477 int (*set_opp)(struct dev_pm_set_opp_data *data))
1495{ 1478{
1496 struct opp_table *opp_table; 1479 struct opp_table *opp_table;
1497 int ret;
1498 1480
1499 if (!set_opp) 1481 if (!set_opp)
1500 return ERR_PTR(-EINVAL); 1482 return ERR_PTR(-EINVAL);
@@ -1505,24 +1487,15 @@ struct opp_table *dev_pm_opp_register_set_opp_helper(struct device *dev,
1505 1487
1506 /* This should be called before OPPs are initialized */ 1488 /* This should be called before OPPs are initialized */
1507 if (WARN_ON(!list_empty(&opp_table->opp_list))) { 1489 if (WARN_ON(!list_empty(&opp_table->opp_list))) {
1508 ret = -EBUSY; 1490 dev_pm_opp_put_opp_table(opp_table);
1509 goto err; 1491 return ERR_PTR(-EBUSY);
1510 }
1511
1512 /* Already have custom set_opp helper */
1513 if (WARN_ON(opp_table->set_opp)) {
1514 ret = -EBUSY;
1515 goto err;
1516 } 1492 }
1517 1493
1518 opp_table->set_opp = set_opp; 1494 /* Another CPU that shares the OPP table has set the helper ? */
1495 if (!opp_table->set_opp)
1496 opp_table->set_opp = set_opp;
1519 1497
1520 return opp_table; 1498 return opp_table;
1521
1522err:
1523 dev_pm_opp_put_opp_table(opp_table);
1524
1525 return ERR_PTR(ret);
1526} 1499}
1527EXPORT_SYMBOL_GPL(dev_pm_opp_register_set_opp_helper); 1500EXPORT_SYMBOL_GPL(dev_pm_opp_register_set_opp_helper);
1528 1501
@@ -1535,97 +1508,15 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_register_set_opp_helper);
1535 */ 1508 */
1536void dev_pm_opp_unregister_set_opp_helper(struct opp_table *opp_table) 1509void dev_pm_opp_unregister_set_opp_helper(struct opp_table *opp_table)
1537{ 1510{
1538 if (!opp_table->set_opp) {
1539 pr_err("%s: Doesn't have custom set_opp helper set\n",
1540 __func__);
1541 return;
1542 }
1543
1544 /* Make sure there are no concurrent readers while updating opp_table */ 1511 /* Make sure there are no concurrent readers while updating opp_table */
1545 WARN_ON(!list_empty(&opp_table->opp_list)); 1512 WARN_ON(!list_empty(&opp_table->opp_list));
1546 1513
1547 opp_table->set_opp = NULL; 1514 opp_table->set_opp = NULL;
1548
1549 dev_pm_opp_put_opp_table(opp_table); 1515 dev_pm_opp_put_opp_table(opp_table);
1550} 1516}
1551EXPORT_SYMBOL_GPL(dev_pm_opp_unregister_set_opp_helper); 1517EXPORT_SYMBOL_GPL(dev_pm_opp_unregister_set_opp_helper);
1552 1518
1553/** 1519/**
1554 * dev_pm_opp_register_get_pstate_helper() - Register get_pstate() helper.
1555 * @dev: Device for which the helper is getting registered.
1556 * @get_pstate: Helper.
1557 *
1558 * TODO: Remove this callback after the same information is available via Device
1559 * Tree.
1560 *
1561 * This allows a platform to initialize the performance states of individual
1562 * OPPs for its devices, until we get similar information directly from DT.
1563 *
1564 * This must be called before the OPPs are initialized for the device.
1565 */
1566struct opp_table *dev_pm_opp_register_get_pstate_helper(struct device *dev,
1567 int (*get_pstate)(struct device *dev, unsigned long rate))
1568{
1569 struct opp_table *opp_table;
1570 int ret;
1571
1572 if (!get_pstate)
1573 return ERR_PTR(-EINVAL);
1574
1575 opp_table = dev_pm_opp_get_opp_table(dev);
1576 if (!opp_table)
1577 return ERR_PTR(-ENOMEM);
1578
1579 /* This should be called before OPPs are initialized */
1580 if (WARN_ON(!list_empty(&opp_table->opp_list))) {
1581 ret = -EBUSY;
1582 goto err;
1583 }
1584
1585 /* Already have genpd_performance_state set */
1586 if (WARN_ON(opp_table->genpd_performance_state)) {
1587 ret = -EBUSY;
1588 goto err;
1589 }
1590
1591 opp_table->genpd_performance_state = true;
1592 opp_table->get_pstate = get_pstate;
1593
1594 return opp_table;
1595
1596err:
1597 dev_pm_opp_put_opp_table(opp_table);
1598
1599 return ERR_PTR(ret);
1600}
1601EXPORT_SYMBOL_GPL(dev_pm_opp_register_get_pstate_helper);
1602
1603/**
1604 * dev_pm_opp_unregister_get_pstate_helper() - Releases resources blocked for
1605 * get_pstate() helper
1606 * @opp_table: OPP table returned from dev_pm_opp_register_get_pstate_helper().
1607 *
1608 * Release resources blocked for platform specific get_pstate() helper.
1609 */
1610void dev_pm_opp_unregister_get_pstate_helper(struct opp_table *opp_table)
1611{
1612 if (!opp_table->genpd_performance_state) {
1613 pr_err("%s: Doesn't have performance states set\n",
1614 __func__);
1615 return;
1616 }
1617
1618 /* Make sure there are no concurrent readers while updating opp_table */
1619 WARN_ON(!list_empty(&opp_table->opp_list));
1620
1621 opp_table->genpd_performance_state = false;
1622 opp_table->get_pstate = NULL;
1623
1624 dev_pm_opp_put_opp_table(opp_table);
1625}
1626EXPORT_SYMBOL_GPL(dev_pm_opp_unregister_get_pstate_helper);
1627
1628/**
1629 * dev_pm_opp_add() - Add an OPP table from a table definitions 1520 * dev_pm_opp_add() - Add an OPP table from a table definitions
1630 * @dev: device for which we do this operation 1521 * @dev: device for which we do this operation
1631 * @freq: Frequency in Hz for this OPP 1522 * @freq: Frequency in Hz for this OPP
diff --git a/drivers/opp/debugfs.c b/drivers/opp/debugfs.c
index b03c03576a62..e6828e5f81b0 100644
--- a/drivers/opp/debugfs.c
+++ b/drivers/opp/debugfs.c
@@ -77,10 +77,21 @@ int opp_debug_create_one(struct dev_pm_opp *opp, struct opp_table *opp_table)
77{ 77{
78 struct dentry *pdentry = opp_table->dentry; 78 struct dentry *pdentry = opp_table->dentry;
79 struct dentry *d; 79 struct dentry *d;
80 unsigned long id;
80 char name[25]; /* 20 chars for 64 bit value + 5 (opp:\0) */ 81 char name[25]; /* 20 chars for 64 bit value + 5 (opp:\0) */
81 82
82 /* Rate is unique to each OPP, use it to give opp-name */ 83 /*
83 snprintf(name, sizeof(name), "opp:%lu", opp->rate); 84 * Get directory name for OPP.
85 *
86 * - Normally rate is unique to each OPP, use it to get unique opp-name.
87 * - For some devices rate isn't available, use index instead.
88 */
89 if (likely(opp->rate))
90 id = opp->rate;
91 else
92 id = _get_opp_count(opp_table);
93
94 snprintf(name, sizeof(name), "opp:%lu", id);
84 95
85 /* Create per-opp directory */ 96 /* Create per-opp directory */
86 d = debugfs_create_dir(name, pdentry); 97 d = debugfs_create_dir(name, pdentry);
diff --git a/drivers/opp/of.c b/drivers/opp/of.c
index cb716aa2f44b..7af0ddec936b 100644
--- a/drivers/opp/of.c
+++ b/drivers/opp/of.c
@@ -17,6 +17,7 @@
17#include <linux/errno.h> 17#include <linux/errno.h>
18#include <linux/device.h> 18#include <linux/device.h>
19#include <linux/of_device.h> 19#include <linux/of_device.h>
20#include <linux/pm_domain.h>
20#include <linux/slab.h> 21#include <linux/slab.h>
21#include <linux/export.h> 22#include <linux/export.h>
22 23
@@ -250,20 +251,17 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_of_remove_table);
250 251
251/* Returns opp descriptor node for a device node, caller must 252/* Returns opp descriptor node for a device node, caller must
252 * do of_node_put() */ 253 * do of_node_put() */
253static struct device_node *_opp_of_get_opp_desc_node(struct device_node *np) 254static struct device_node *_opp_of_get_opp_desc_node(struct device_node *np,
255 int index)
254{ 256{
255 /* 257 /* "operating-points-v2" can be an array for power domain providers */
256 * There should be only ONE phandle present in "operating-points-v2" 258 return of_parse_phandle(np, "operating-points-v2", index);
257 * property.
258 */
259
260 return of_parse_phandle(np, "operating-points-v2", 0);
261} 259}
262 260
263/* Returns opp descriptor node for a device, caller must do of_node_put() */ 261/* Returns opp descriptor node for a device, caller must do of_node_put() */
264struct device_node *dev_pm_opp_of_get_opp_desc_node(struct device *dev) 262struct device_node *dev_pm_opp_of_get_opp_desc_node(struct device *dev)
265{ 263{
266 return _opp_of_get_opp_desc_node(dev->of_node); 264 return _opp_of_get_opp_desc_node(dev->of_node, 0);
267} 265}
268EXPORT_SYMBOL_GPL(dev_pm_opp_of_get_opp_desc_node); 266EXPORT_SYMBOL_GPL(dev_pm_opp_of_get_opp_desc_node);
269 267
@@ -289,9 +287,10 @@ static int _opp_add_static_v2(struct opp_table *opp_table, struct device *dev,
289 struct device_node *np) 287 struct device_node *np)
290{ 288{
291 struct dev_pm_opp *new_opp; 289 struct dev_pm_opp *new_opp;
292 u64 rate; 290 u64 rate = 0;
293 u32 val; 291 u32 val;
294 int ret; 292 int ret;
293 bool rate_not_available = false;
295 294
296 new_opp = _opp_allocate(opp_table); 295 new_opp = _opp_allocate(opp_table);
297 if (!new_opp) 296 if (!new_opp)
@@ -299,8 +298,21 @@ static int _opp_add_static_v2(struct opp_table *opp_table, struct device *dev,
299 298
300 ret = of_property_read_u64(np, "opp-hz", &rate); 299 ret = of_property_read_u64(np, "opp-hz", &rate);
301 if (ret < 0) { 300 if (ret < 0) {
302 dev_err(dev, "%s: opp-hz not found\n", __func__); 301 /* "opp-hz" is optional for devices like power domains. */
303 goto free_opp; 302 if (!of_find_property(dev->of_node, "#power-domain-cells",
303 NULL)) {
304 dev_err(dev, "%s: opp-hz not found\n", __func__);
305 goto free_opp;
306 }
307
308 rate_not_available = true;
309 } else {
310 /*
311 * Rate is defined as an unsigned long in clk API, and so
312 * casting explicitly to its type. Must be fixed once rate is 64
313 * bit guaranteed in clk API.
314 */
315 new_opp->rate = (unsigned long)rate;
304 } 316 }
305 317
306 /* Check if the OPP supports hardware's hierarchy of versions or not */ 318 /* Check if the OPP supports hardware's hierarchy of versions or not */
@@ -309,12 +321,6 @@ static int _opp_add_static_v2(struct opp_table *opp_table, struct device *dev,
309 goto free_opp; 321 goto free_opp;
310 } 322 }
311 323
312 /*
313 * Rate is defined as an unsigned long in clk API, and so casting
314 * explicitly to its type. Must be fixed once rate is 64 bit
315 * guaranteed in clk API.
316 */
317 new_opp->rate = (unsigned long)rate;
318 new_opp->turbo = of_property_read_bool(np, "turbo-mode"); 324 new_opp->turbo = of_property_read_bool(np, "turbo-mode");
319 325
320 new_opp->np = np; 326 new_opp->np = np;
@@ -324,11 +330,13 @@ static int _opp_add_static_v2(struct opp_table *opp_table, struct device *dev,
324 if (!of_property_read_u32(np, "clock-latency-ns", &val)) 330 if (!of_property_read_u32(np, "clock-latency-ns", &val))
325 new_opp->clock_latency_ns = val; 331 new_opp->clock_latency_ns = val;
326 332
333 new_opp->pstate = of_genpd_opp_to_performance_state(dev, np);
334
327 ret = opp_parse_supplies(new_opp, dev, opp_table); 335 ret = opp_parse_supplies(new_opp, dev, opp_table);
328 if (ret) 336 if (ret)
329 goto free_opp; 337 goto free_opp;
330 338
331 ret = _opp_add(dev, new_opp, opp_table); 339 ret = _opp_add(dev, new_opp, opp_table, rate_not_available);
332 if (ret) { 340 if (ret) {
333 /* Don't return error for duplicate OPPs */ 341 /* Don't return error for duplicate OPPs */
334 if (ret == -EBUSY) 342 if (ret == -EBUSY)
@@ -374,7 +382,8 @@ static int _of_add_opp_table_v2(struct device *dev, struct device_node *opp_np)
374{ 382{
375 struct device_node *np; 383 struct device_node *np;
376 struct opp_table *opp_table; 384 struct opp_table *opp_table;
377 int ret = 0, count = 0; 385 int ret = 0, count = 0, pstate_count = 0;
386 struct dev_pm_opp *opp;
378 387
379 opp_table = _managed_opp(opp_np); 388 opp_table = _managed_opp(opp_np);
380 if (opp_table) { 389 if (opp_table) {
@@ -408,6 +417,20 @@ static int _of_add_opp_table_v2(struct device *dev, struct device_node *opp_np)
408 goto put_opp_table; 417 goto put_opp_table;
409 } 418 }
410 419
420 list_for_each_entry(opp, &opp_table->opp_list, node)
421 pstate_count += !!opp->pstate;
422
423 /* Either all or none of the nodes shall have performance state set */
424 if (pstate_count && pstate_count != count) {
425 dev_err(dev, "Not all nodes have performance state set (%d: %d)\n",
426 count, pstate_count);
427 ret = -ENOENT;
428 goto put_opp_table;
429 }
430
431 if (pstate_count)
432 opp_table->genpd_performance_state = true;
433
411 opp_table->np = opp_np; 434 opp_table->np = opp_np;
412 if (of_property_read_bool(opp_np, "opp-shared")) 435 if (of_property_read_bool(opp_np, "opp-shared"))
413 opp_table->shared_opp = OPP_TABLE_ACCESS_SHARED; 436 opp_table->shared_opp = OPP_TABLE_ACCESS_SHARED;
@@ -509,6 +532,54 @@ int dev_pm_opp_of_add_table(struct device *dev)
509} 532}
510EXPORT_SYMBOL_GPL(dev_pm_opp_of_add_table); 533EXPORT_SYMBOL_GPL(dev_pm_opp_of_add_table);
511 534
535/**
536 * dev_pm_opp_of_add_table_indexed() - Initialize indexed opp table from device tree
537 * @dev: device pointer used to lookup OPP table.
538 * @index: Index number.
539 *
540 * Register the initial OPP table with the OPP library for given device only
541 * using the "operating-points-v2" property.
542 *
543 * Return:
544 * 0 On success OR
545 * Duplicate OPPs (both freq and volt are same) and opp->available
546 * -EEXIST Freq are same and volt are different OR
547 * Duplicate OPPs (both freq and volt are same) and !opp->available
548 * -ENOMEM Memory allocation failure
549 * -ENODEV when 'operating-points' property is not found or is invalid data
550 * in device node.
551 * -ENODATA when empty 'operating-points' property is found
552 * -EINVAL when invalid entries are found in opp-v2 table
553 */
554int dev_pm_opp_of_add_table_indexed(struct device *dev, int index)
555{
556 struct device_node *opp_np;
557 int ret, count;
558
559again:
560 opp_np = _opp_of_get_opp_desc_node(dev->of_node, index);
561 if (!opp_np) {
562 /*
563 * If only one phandle is present, then the same OPP table
564 * applies for all index requests.
565 */
566 count = of_count_phandle_with_args(dev->of_node,
567 "operating-points-v2", NULL);
568 if (count == 1 && index) {
569 index = 0;
570 goto again;
571 }
572
573 return -ENODEV;
574 }
575
576 ret = _of_add_opp_table_v2(dev, opp_np);
577 of_node_put(opp_np);
578
579 return ret;
580}
581EXPORT_SYMBOL_GPL(dev_pm_opp_of_add_table_indexed);
582
512/* CPU device specific helpers */ 583/* CPU device specific helpers */
513 584
514/** 585/**
@@ -613,7 +684,7 @@ int dev_pm_opp_of_get_sharing_cpus(struct device *cpu_dev,
613 } 684 }
614 685
615 /* Get OPP descriptor node */ 686 /* Get OPP descriptor node */
616 tmp_np = _opp_of_get_opp_desc_node(cpu_np); 687 tmp_np = _opp_of_get_opp_desc_node(cpu_np, 0);
617 of_node_put(cpu_np); 688 of_node_put(cpu_np);
618 if (!tmp_np) { 689 if (!tmp_np) {
619 pr_err("%pOF: Couldn't find opp node\n", cpu_np); 690 pr_err("%pOF: Couldn't find opp node\n", cpu_np);
@@ -633,3 +704,76 @@ put_cpu_node:
633 return ret; 704 return ret;
634} 705}
635EXPORT_SYMBOL_GPL(dev_pm_opp_of_get_sharing_cpus); 706EXPORT_SYMBOL_GPL(dev_pm_opp_of_get_sharing_cpus);
707
708/**
709 * of_dev_pm_opp_find_required_opp() - Search for required OPP.
710 * @dev: The device whose OPP node is referenced by the 'np' DT node.
711 * @np: Node that contains the "required-opps" property.
712 *
713 * Returns the OPP of the device 'dev', whose phandle is present in the "np"
714 * node. Although the "required-opps" property supports having multiple
715 * phandles, this helper routine only parses the very first phandle in the list.
716 *
717 * Return: Matching opp, else returns ERR_PTR in case of error and should be
718 * handled using IS_ERR.
719 *
720 * The callers are required to call dev_pm_opp_put() for the returned OPP after
721 * use.
722 */
723struct dev_pm_opp *of_dev_pm_opp_find_required_opp(struct device *dev,
724 struct device_node *np)
725{
726 struct dev_pm_opp *temp_opp, *opp = ERR_PTR(-ENODEV);
727 struct device_node *required_np;
728 struct opp_table *opp_table;
729
730 opp_table = _find_opp_table(dev);
731 if (IS_ERR(opp_table))
732 return ERR_CAST(opp_table);
733
734 required_np = of_parse_phandle(np, "required-opps", 0);
735 if (unlikely(!required_np)) {
736 dev_err(dev, "Unable to parse required-opps\n");
737 goto put_opp_table;
738 }
739
740 mutex_lock(&opp_table->lock);
741
742 list_for_each_entry(temp_opp, &opp_table->opp_list, node) {
743 if (temp_opp->available && temp_opp->np == required_np) {
744 opp = temp_opp;
745
746 /* Increment the reference count of OPP */
747 dev_pm_opp_get(opp);
748 break;
749 }
750 }
751
752 mutex_unlock(&opp_table->lock);
753
754 of_node_put(required_np);
755put_opp_table:
756 dev_pm_opp_put_opp_table(opp_table);
757
758 return opp;
759}
760EXPORT_SYMBOL_GPL(of_dev_pm_opp_find_required_opp);
761
762/**
763 * dev_pm_opp_get_of_node() - Gets the DT node corresponding to an opp
764 * @opp: opp for which DT node has to be returned for
765 *
766 * Return: DT node corresponding to the opp, else 0 on success.
767 *
768 * The caller needs to put the node with of_node_put() after using it.
769 */
770struct device_node *dev_pm_opp_get_of_node(struct dev_pm_opp *opp)
771{
772 if (IS_ERR_OR_NULL(opp)) {
773 pr_err("%s: Invalid parameters\n", __func__);
774 return NULL;
775 }
776
777 return of_node_get(opp->np);
778}
779EXPORT_SYMBOL_GPL(dev_pm_opp_get_of_node);
diff --git a/drivers/opp/opp.h b/drivers/opp/opp.h
index 4d00061648a3..7c540fd063b2 100644
--- a/drivers/opp/opp.h
+++ b/drivers/opp/opp.h
@@ -140,7 +140,6 @@ enum opp_table_access {
140 * @genpd_performance_state: Device's power domain support performance state. 140 * @genpd_performance_state: Device's power domain support performance state.
141 * @set_opp: Platform specific set_opp callback 141 * @set_opp: Platform specific set_opp callback
142 * @set_opp_data: Data to be passed to set_opp callback 142 * @set_opp_data: Data to be passed to set_opp callback
143 * @get_pstate: Platform specific get_pstate callback
144 * @dentry: debugfs dentry pointer of the real device directory (not links). 143 * @dentry: debugfs dentry pointer of the real device directory (not links).
145 * @dentry_name: Name of the real dentry. 144 * @dentry_name: Name of the real dentry.
146 * 145 *
@@ -178,7 +177,6 @@ struct opp_table {
178 177
179 int (*set_opp)(struct dev_pm_set_opp_data *data); 178 int (*set_opp)(struct dev_pm_set_opp_data *data);
180 struct dev_pm_set_opp_data *set_opp_data; 179 struct dev_pm_set_opp_data *set_opp_data;
181 int (*get_pstate)(struct device *dev, unsigned long rate);
182 180
183#ifdef CONFIG_DEBUG_FS 181#ifdef CONFIG_DEBUG_FS
184 struct dentry *dentry; 182 struct dentry *dentry;
@@ -187,14 +185,16 @@ struct opp_table {
187}; 185};
188 186
189/* Routines internal to opp core */ 187/* Routines internal to opp core */
188void dev_pm_opp_get(struct dev_pm_opp *opp);
190void _get_opp_table_kref(struct opp_table *opp_table); 189void _get_opp_table_kref(struct opp_table *opp_table);
190int _get_opp_count(struct opp_table *opp_table);
191struct opp_table *_find_opp_table(struct device *dev); 191struct opp_table *_find_opp_table(struct device *dev);
192struct opp_device *_add_opp_dev(const struct device *dev, struct opp_table *opp_table); 192struct opp_device *_add_opp_dev(const struct device *dev, struct opp_table *opp_table);
193void _dev_pm_opp_remove_table(struct opp_table *opp_table, struct device *dev, bool remove_all); 193void _dev_pm_opp_remove_table(struct opp_table *opp_table, struct device *dev, bool remove_all);
194void _dev_pm_opp_find_and_remove_table(struct device *dev, bool remove_all); 194void _dev_pm_opp_find_and_remove_table(struct device *dev, bool remove_all);
195struct dev_pm_opp *_opp_allocate(struct opp_table *opp_table); 195struct dev_pm_opp *_opp_allocate(struct opp_table *opp_table);
196void _opp_free(struct dev_pm_opp *opp); 196void _opp_free(struct dev_pm_opp *opp);
197int _opp_add(struct device *dev, struct dev_pm_opp *new_opp, struct opp_table *opp_table); 197int _opp_add(struct device *dev, struct dev_pm_opp *new_opp, struct opp_table *opp_table, bool rate_not_available);
198int _opp_add_v1(struct opp_table *opp_table, struct device *dev, unsigned long freq, long u_volt, bool dynamic); 198int _opp_add_v1(struct opp_table *opp_table, struct device *dev, unsigned long freq, long u_volt, bool dynamic);
199void _dev_pm_opp_cpumask_remove_table(const struct cpumask *cpumask, bool of); 199void _dev_pm_opp_cpumask_remove_table(const struct cpumask *cpumask, bool of);
200struct opp_table *_add_opp_table(struct device *dev); 200struct opp_table *_add_opp_table(struct device *dev);
diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c
index d9fcdb592b39..3e3d12ce4587 100644
--- a/drivers/soc/tegra/pmc.c
+++ b/drivers/soc/tegra/pmc.c
@@ -559,22 +559,28 @@ EXPORT_SYMBOL(tegra_powergate_remove_clamping);
559int tegra_powergate_sequence_power_up(unsigned int id, struct clk *clk, 559int tegra_powergate_sequence_power_up(unsigned int id, struct clk *clk,
560 struct reset_control *rst) 560 struct reset_control *rst)
561{ 561{
562 struct tegra_powergate pg; 562 struct tegra_powergate *pg;
563 int err; 563 int err;
564 564
565 if (!tegra_powergate_is_available(id)) 565 if (!tegra_powergate_is_available(id))
566 return -EINVAL; 566 return -EINVAL;
567 567
568 pg.id = id; 568 pg = kzalloc(sizeof(*pg), GFP_KERNEL);
569 pg.clks = &clk; 569 if (!pg)
570 pg.num_clks = 1; 570 return -ENOMEM;
571 pg.reset = rst;
572 pg.pmc = pmc;
573 571
574 err = tegra_powergate_power_up(&pg, false); 572 pg->id = id;
573 pg->clks = &clk;
574 pg->num_clks = 1;
575 pg->reset = rst;
576 pg->pmc = pmc;
577
578 err = tegra_powergate_power_up(pg, false);
575 if (err) 579 if (err)
576 pr_err("failed to turn on partition %d: %d\n", id, err); 580 pr_err("failed to turn on partition %d: %d\n", id, err);
577 581
582 kfree(pg);
583
578 return err; 584 return err;
579} 585}
580EXPORT_SYMBOL(tegra_powergate_sequence_power_up); 586EXPORT_SYMBOL(tegra_powergate_sequence_power_up);
diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h
index ab1854863a8c..42e0d649e653 100644
--- a/include/linux/pm_domain.h
+++ b/include/linux/pm_domain.h
@@ -47,8 +47,10 @@ struct genpd_power_state {
47}; 47};
48 48
49struct genpd_lock_ops; 49struct genpd_lock_ops;
50struct dev_pm_opp;
50 51
51struct generic_pm_domain { 52struct generic_pm_domain {
53 struct device dev;
52 struct dev_pm_domain domain; /* PM domain operations */ 54 struct dev_pm_domain domain; /* PM domain operations */
53 struct list_head gpd_list_node; /* Node in the global PM domains list */ 55 struct list_head gpd_list_node; /* Node in the global PM domains list */
54 struct list_head master_links; /* Links with PM domain as a master */ 56 struct list_head master_links; /* Links with PM domain as a master */
@@ -67,6 +69,8 @@ struct generic_pm_domain {
67 unsigned int performance_state; /* Aggregated max performance state */ 69 unsigned int performance_state; /* Aggregated max performance state */
68 int (*power_off)(struct generic_pm_domain *domain); 70 int (*power_off)(struct generic_pm_domain *domain);
69 int (*power_on)(struct generic_pm_domain *domain); 71 int (*power_on)(struct generic_pm_domain *domain);
72 unsigned int (*opp_to_performance_state)(struct generic_pm_domain *genpd,
73 struct dev_pm_opp *opp);
70 int (*set_performance_state)(struct generic_pm_domain *genpd, 74 int (*set_performance_state)(struct generic_pm_domain *genpd,
71 unsigned int state); 75 unsigned int state);
72 struct gpd_dev_ops dev_ops; 76 struct gpd_dev_ops dev_ops;
@@ -139,21 +143,16 @@ static inline struct generic_pm_domain_data *dev_gpd_data(struct device *dev)
139 return to_gpd_data(dev->power.subsys_data->domain_data); 143 return to_gpd_data(dev->power.subsys_data->domain_data);
140} 144}
141 145
142extern int __pm_genpd_add_device(struct generic_pm_domain *genpd, 146int pm_genpd_add_device(struct generic_pm_domain *genpd, struct device *dev);
143 struct device *dev, 147int pm_genpd_remove_device(struct device *dev);
144 struct gpd_timing_data *td); 148int pm_genpd_add_subdomain(struct generic_pm_domain *genpd,
145 149 struct generic_pm_domain *new_subdomain);
146extern int pm_genpd_remove_device(struct generic_pm_domain *genpd, 150int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd,
147 struct device *dev); 151 struct generic_pm_domain *target);
148extern int pm_genpd_add_subdomain(struct generic_pm_domain *genpd, 152int pm_genpd_init(struct generic_pm_domain *genpd,
149 struct generic_pm_domain *new_subdomain); 153 struct dev_power_governor *gov, bool is_off);
150extern int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd, 154int pm_genpd_remove(struct generic_pm_domain *genpd);
151 struct generic_pm_domain *target); 155int dev_pm_genpd_set_performance_state(struct device *dev, unsigned int state);
152extern int pm_genpd_init(struct generic_pm_domain *genpd,
153 struct dev_power_governor *gov, bool is_off);
154extern int pm_genpd_remove(struct generic_pm_domain *genpd);
155extern int dev_pm_genpd_set_performance_state(struct device *dev,
156 unsigned int state);
157 156
158extern struct dev_power_governor simple_qos_governor; 157extern struct dev_power_governor simple_qos_governor;
159extern struct dev_power_governor pm_domain_always_on_gov; 158extern struct dev_power_governor pm_domain_always_on_gov;
@@ -163,14 +162,12 @@ static inline struct generic_pm_domain_data *dev_gpd_data(struct device *dev)
163{ 162{
164 return ERR_PTR(-ENOSYS); 163 return ERR_PTR(-ENOSYS);
165} 164}
166static inline int __pm_genpd_add_device(struct generic_pm_domain *genpd, 165static inline int pm_genpd_add_device(struct generic_pm_domain *genpd,
167 struct device *dev, 166 struct device *dev)
168 struct gpd_timing_data *td)
169{ 167{
170 return -ENOSYS; 168 return -ENOSYS;
171} 169}
172static inline int pm_genpd_remove_device(struct generic_pm_domain *genpd, 170static inline int pm_genpd_remove_device(struct device *dev)
173 struct device *dev)
174{ 171{
175 return -ENOSYS; 172 return -ENOSYS;
176} 173}
@@ -204,15 +201,9 @@ static inline int dev_pm_genpd_set_performance_state(struct device *dev,
204#define pm_domain_always_on_gov (*(struct dev_power_governor *)(NULL)) 201#define pm_domain_always_on_gov (*(struct dev_power_governor *)(NULL))
205#endif 202#endif
206 203
207static inline int pm_genpd_add_device(struct generic_pm_domain *genpd,
208 struct device *dev)
209{
210 return __pm_genpd_add_device(genpd, dev, NULL);
211}
212
213#ifdef CONFIG_PM_GENERIC_DOMAINS_SLEEP 204#ifdef CONFIG_PM_GENERIC_DOMAINS_SLEEP
214extern void pm_genpd_syscore_poweroff(struct device *dev); 205void pm_genpd_syscore_poweroff(struct device *dev);
215extern void pm_genpd_syscore_poweron(struct device *dev); 206void pm_genpd_syscore_poweron(struct device *dev);
216#else 207#else
217static inline void pm_genpd_syscore_poweroff(struct device *dev) {} 208static inline void pm_genpd_syscore_poweroff(struct device *dev) {}
218static inline void pm_genpd_syscore_poweron(struct device *dev) {} 209static inline void pm_genpd_syscore_poweron(struct device *dev) {}
@@ -236,13 +227,14 @@ int of_genpd_add_provider_simple(struct device_node *np,
236int of_genpd_add_provider_onecell(struct device_node *np, 227int of_genpd_add_provider_onecell(struct device_node *np,
237 struct genpd_onecell_data *data); 228 struct genpd_onecell_data *data);
238void of_genpd_del_provider(struct device_node *np); 229void of_genpd_del_provider(struct device_node *np);
239extern int of_genpd_add_device(struct of_phandle_args *args, 230int of_genpd_add_device(struct of_phandle_args *args, struct device *dev);
240 struct device *dev); 231int of_genpd_add_subdomain(struct of_phandle_args *parent,
241extern int of_genpd_add_subdomain(struct of_phandle_args *parent, 232 struct of_phandle_args *new_subdomain);
242 struct of_phandle_args *new_subdomain); 233struct generic_pm_domain *of_genpd_remove_last(struct device_node *np);
243extern struct generic_pm_domain *of_genpd_remove_last(struct device_node *np); 234int of_genpd_parse_idle_states(struct device_node *dn,
244extern int of_genpd_parse_idle_states(struct device_node *dn, 235 struct genpd_power_state **states, int *n);
245 struct genpd_power_state **states, int *n); 236unsigned int of_genpd_opp_to_performance_state(struct device *dev,
237 struct device_node *opp_node);
246 238
247int genpd_dev_pm_attach(struct device *dev); 239int genpd_dev_pm_attach(struct device *dev);
248#else /* !CONFIG_PM_GENERIC_DOMAINS_OF */ 240#else /* !CONFIG_PM_GENERIC_DOMAINS_OF */
@@ -278,6 +270,13 @@ static inline int of_genpd_parse_idle_states(struct device_node *dn,
278 return -ENODEV; 270 return -ENODEV;
279} 271}
280 272
273static inline unsigned int
274of_genpd_opp_to_performance_state(struct device *dev,
275 struct device_node *opp_node)
276{
277 return -ENODEV;
278}
279
281static inline int genpd_dev_pm_attach(struct device *dev) 280static inline int genpd_dev_pm_attach(struct device *dev)
282{ 281{
283 return 0; 282 return 0;
@@ -291,9 +290,9 @@ struct generic_pm_domain *of_genpd_remove_last(struct device_node *np)
291#endif /* CONFIG_PM_GENERIC_DOMAINS_OF */ 290#endif /* CONFIG_PM_GENERIC_DOMAINS_OF */
292 291
293#ifdef CONFIG_PM 292#ifdef CONFIG_PM
294extern int dev_pm_domain_attach(struct device *dev, bool power_on); 293int dev_pm_domain_attach(struct device *dev, bool power_on);
295extern void dev_pm_domain_detach(struct device *dev, bool power_off); 294void dev_pm_domain_detach(struct device *dev, bool power_off);
296extern void dev_pm_domain_set(struct device *dev, struct dev_pm_domain *pd); 295void dev_pm_domain_set(struct device *dev, struct dev_pm_domain *pd);
297#else 296#else
298static inline int dev_pm_domain_attach(struct device *dev, bool power_on) 297static inline int dev_pm_domain_attach(struct device *dev, bool power_on)
299{ 298{
diff --git a/include/linux/pm_opp.h b/include/linux/pm_opp.h
index 6c2d2e88f066..099b31960dec 100644
--- a/include/linux/pm_opp.h
+++ b/include/linux/pm_opp.h
@@ -125,8 +125,6 @@ struct opp_table *dev_pm_opp_set_clkname(struct device *dev, const char * name);
125void dev_pm_opp_put_clkname(struct opp_table *opp_table); 125void dev_pm_opp_put_clkname(struct opp_table *opp_table);
126struct opp_table *dev_pm_opp_register_set_opp_helper(struct device *dev, int (*set_opp)(struct dev_pm_set_opp_data *data)); 126struct opp_table *dev_pm_opp_register_set_opp_helper(struct device *dev, int (*set_opp)(struct dev_pm_set_opp_data *data));
127void dev_pm_opp_unregister_set_opp_helper(struct opp_table *opp_table); 127void dev_pm_opp_unregister_set_opp_helper(struct opp_table *opp_table);
128struct opp_table *dev_pm_opp_register_get_pstate_helper(struct device *dev, int (*get_pstate)(struct device *dev, unsigned long rate));
129void dev_pm_opp_unregister_get_pstate_helper(struct opp_table *opp_table);
130int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq); 128int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq);
131int dev_pm_opp_set_sharing_cpus(struct device *cpu_dev, const struct cpumask *cpumask); 129int dev_pm_opp_set_sharing_cpus(struct device *cpu_dev, const struct cpumask *cpumask);
132int dev_pm_opp_get_sharing_cpus(struct device *cpu_dev, struct cpumask *cpumask); 130int dev_pm_opp_get_sharing_cpus(struct device *cpu_dev, struct cpumask *cpumask);
@@ -247,14 +245,6 @@ static inline struct opp_table *dev_pm_opp_register_set_opp_helper(struct device
247 245
248static inline void dev_pm_opp_unregister_set_opp_helper(struct opp_table *opp_table) {} 246static inline void dev_pm_opp_unregister_set_opp_helper(struct opp_table *opp_table) {}
249 247
250static inline struct opp_table *dev_pm_opp_register_get_pstate_helper(struct device *dev,
251 int (*get_pstate)(struct device *dev, unsigned long rate))
252{
253 return ERR_PTR(-ENOTSUPP);
254}
255
256static inline void dev_pm_opp_unregister_get_pstate_helper(struct opp_table *opp_table) {}
257
258static inline struct opp_table *dev_pm_opp_set_prop_name(struct device *dev, const char *name) 248static inline struct opp_table *dev_pm_opp_set_prop_name(struct device *dev, const char *name)
259{ 249{
260 return ERR_PTR(-ENOTSUPP); 250 return ERR_PTR(-ENOTSUPP);
@@ -303,17 +293,25 @@ static inline void dev_pm_opp_cpumask_remove_table(const struct cpumask *cpumask
303 293
304#if defined(CONFIG_PM_OPP) && defined(CONFIG_OF) 294#if defined(CONFIG_PM_OPP) && defined(CONFIG_OF)
305int dev_pm_opp_of_add_table(struct device *dev); 295int dev_pm_opp_of_add_table(struct device *dev);
296int dev_pm_opp_of_add_table_indexed(struct device *dev, int index);
306void dev_pm_opp_of_remove_table(struct device *dev); 297void dev_pm_opp_of_remove_table(struct device *dev);
307int dev_pm_opp_of_cpumask_add_table(const struct cpumask *cpumask); 298int dev_pm_opp_of_cpumask_add_table(const struct cpumask *cpumask);
308void dev_pm_opp_of_cpumask_remove_table(const struct cpumask *cpumask); 299void dev_pm_opp_of_cpumask_remove_table(const struct cpumask *cpumask);
309int dev_pm_opp_of_get_sharing_cpus(struct device *cpu_dev, struct cpumask *cpumask); 300int dev_pm_opp_of_get_sharing_cpus(struct device *cpu_dev, struct cpumask *cpumask);
310struct device_node *dev_pm_opp_of_get_opp_desc_node(struct device *dev); 301struct device_node *dev_pm_opp_of_get_opp_desc_node(struct device *dev);
302struct dev_pm_opp *of_dev_pm_opp_find_required_opp(struct device *dev, struct device_node *np);
303struct device_node *dev_pm_opp_get_of_node(struct dev_pm_opp *opp);
311#else 304#else
312static inline int dev_pm_opp_of_add_table(struct device *dev) 305static inline int dev_pm_opp_of_add_table(struct device *dev)
313{ 306{
314 return -ENOTSUPP; 307 return -ENOTSUPP;
315} 308}
316 309
310static inline int dev_pm_opp_of_add_table_indexed(struct device *dev, int index)
311{
312 return -ENOTSUPP;
313}
314
317static inline void dev_pm_opp_of_remove_table(struct device *dev) 315static inline void dev_pm_opp_of_remove_table(struct device *dev)
318{ 316{
319} 317}
@@ -336,6 +334,15 @@ static inline struct device_node *dev_pm_opp_of_get_opp_desc_node(struct device
336{ 334{
337 return NULL; 335 return NULL;
338} 336}
337
338static inline struct dev_pm_opp *of_dev_pm_opp_find_required_opp(struct device *dev, struct device_node *np)
339{
340 return NULL;
341}
342static inline struct device_node *dev_pm_opp_get_of_node(struct dev_pm_opp *opp)
343{
344 return NULL;
345}
339#endif 346#endif
340 347
341#endif /* __LINUX_OPP_H__ */ 348#endif /* __LINUX_OPP_H__ */