Skip to content

Commit 6785c16

Browse files
committed
pmdomain: core: Set the required dev for a required OPP during genpd attach
JIRA: https://issues.redhat.com/browse/RHEL-75956 commit e130ca9 Author: Ulf Hansson <ulf.hansson@linaro.org> Date: Wed Oct 2 14:22:27 2024 +0200 pmdomain: core: Set the required dev for a required OPP during genpd attach In the single PM domain case there is no need for platform code to specify the index of the corresponding required OPP in DT, as the index must be zero. This allows us to assign a required dev for the required OPP from genpd, while attaching a device to its PM domain. In this way, we can remove some of the genpd specific code in the OPP core for the single PM domain case. Although, this cleanup is made from a subsequent change. Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org> Acked-by: Viresh Kumar <viresh.kumar@linaro.org> Link: https://lore.kernel.org/r/20241002122232.194245-7-ulf.hansson@linaro.org Signed-off-by: José Expósito <jexposit@redhat.com>
1 parent f19e069 commit 6785c16

File tree

2 files changed

+40
-3
lines changed

2 files changed

+40
-3
lines changed

drivers/pmdomain/core.c

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1727,6 +1727,7 @@ static void genpd_free_dev_data(struct device *dev,
17271727

17281728
spin_unlock_irq(&dev->power.lock);
17291729

1730+
dev_pm_opp_clear_config(gpd_data->opp_token);
17301731
kfree(gpd_data->td);
17311732
kfree(gpd_data);
17321733
dev_pm_put_subsys_data(dev);
@@ -2903,6 +2904,29 @@ static void genpd_dev_pm_sync(struct device *dev)
29032904
genpd_queue_power_off_work(pd);
29042905
}
29052906

2907+
static int genpd_set_required_opp_dev(struct device *dev,
2908+
struct device *base_dev)
2909+
{
2910+
struct dev_pm_opp_config config = {
2911+
.required_dev = dev,
2912+
};
2913+
int ret;
2914+
2915+
/* Limit support to non-providers for now. */
2916+
if (of_property_present(base_dev->of_node, "#power-domain-cells"))
2917+
return 0;
2918+
2919+
if (!dev_pm_opp_of_has_required_opp(base_dev))
2920+
return 0;
2921+
2922+
ret = dev_pm_opp_set_config(base_dev, &config);
2923+
if (ret < 0)
2924+
return ret;
2925+
2926+
dev_gpd_data(dev)->opp_token = ret;
2927+
return 0;
2928+
}
2929+
29062930
static int genpd_set_required_opp(struct device *dev, unsigned int index)
29072931
{
29082932
int ret, pstate;
@@ -2927,7 +2951,8 @@ static int genpd_set_required_opp(struct device *dev, unsigned int index)
29272951
}
29282952

29292953
static int __genpd_dev_pm_attach(struct device *dev, struct device *base_dev,
2930-
unsigned int index, bool power_on)
2954+
unsigned int index, unsigned int num_domains,
2955+
bool power_on)
29312956
{
29322957
struct of_phandle_args pd_args;
29332958
struct generic_pm_domain *pd;
@@ -2959,6 +2984,17 @@ static int __genpd_dev_pm_attach(struct device *dev, struct device *base_dev,
29592984
dev->pm_domain->detach = genpd_dev_pm_detach;
29602985
dev->pm_domain->sync = genpd_dev_pm_sync;
29612986

2987+
/*
2988+
* For a single PM domain the index of the required OPP must be zero, so
2989+
* let's try to assign a required dev in that case. In the multiple PM
2990+
* domains case, we need platform code to specify the index.
2991+
*/
2992+
if (num_domains == 1) {
2993+
ret = genpd_set_required_opp_dev(dev, base_dev);
2994+
if (ret)
2995+
goto err;
2996+
}
2997+
29622998
ret = genpd_set_required_opp(dev, index);
29632999
if (ret)
29643000
goto err;
@@ -3013,7 +3049,7 @@ int genpd_dev_pm_attach(struct device *dev)
30133049
"#power-domain-cells") != 1)
30143050
return 0;
30153051

3016-
return __genpd_dev_pm_attach(dev, dev, 0, true);
3052+
return __genpd_dev_pm_attach(dev, dev, 0, 1, true);
30173053
}
30183054
EXPORT_SYMBOL_GPL(genpd_dev_pm_attach);
30193055

@@ -3066,7 +3102,7 @@ struct device *genpd_dev_pm_attach_by_id(struct device *dev,
30663102
}
30673103

30683104
/* Try to attach the device to the PM domain at the specified index. */
3069-
ret = __genpd_dev_pm_attach(virt_dev, dev, index, false);
3105+
ret = __genpd_dev_pm_attach(virt_dev, dev, index, num_domains, false);
30703106
if (ret < 1) {
30713107
device_unregister(virt_dev);
30723108
return ret ? ERR_PTR(ret) : NULL;

include/linux/pm_domain.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,7 @@ struct generic_pm_domain_data {
258258
unsigned int performance_state;
259259
unsigned int default_pstate;
260260
unsigned int rpm_pstate;
261+
unsigned int opp_token;
261262
bool hw_mode;
262263
void *data;
263264
};

0 commit comments

Comments
 (0)