Skip to content

Commit 5c83017

Browse files
committed
Merge branch 'opp/linux-next' of git://git.kernel.org/pub/scm/linux/kernel/git/vireshk/pm
Pull operating performance points (OPP) framework updates for 5.16-rc1 from Viresh Kumar: "- Fix return value of _opp_add_static_v2() helper (YueHaibing). - Fix required-opp handle count (Pavankumar Kondeti). - Resource managed OPP helpers, type update to dev_pm_opp_attach_genpd() and update to their devfreq users, and minor DT binding change (Dmitry Osipenko)." * 'opp/linux-next' of git://git.kernel.org/pub/scm/linux/kernel/git/vireshk/pm: 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
2 parents 3906fe9 + 7ca81b6 commit 5c83017

File tree

7 files changed

+137
-79
lines changed

7 files changed

+137
-79
lines changed

Documentation/devicetree/bindings/opp/opp-v2-base.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ properties:
3333
type: boolean
3434

3535
patternProperties:
36-
'^opp-?[0-9]+$':
36+
'^opp(-?[0-9]+)*$':
3737
type: object
3838
description:
3939
One or more OPP nodes describing voltage-current-frequency combinations.

drivers/devfreq/devfreq.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1301,6 +1301,32 @@ int devfreq_add_governor(struct devfreq_governor *governor)
13011301
}
13021302
EXPORT_SYMBOL(devfreq_add_governor);
13031303

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+
13041330
/**
13051331
* devfreq_remove_governor() - Remove devfreq feature from a device.
13061332
* @governor: the devfreq governor to be removed

drivers/devfreq/governor.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,9 @@ void devfreq_update_interval(struct devfreq *devfreq, unsigned int *delay);
8484
int devfreq_add_governor(struct devfreq_governor *governor);
8585
int devfreq_remove_governor(struct devfreq_governor *governor);
8686

87+
int devm_devfreq_add_governor(struct device *dev,
88+
struct devfreq_governor *governor);
89+
8790
int devfreq_update_status(struct devfreq *devfreq, unsigned long freq);
8891
int devfreq_update_target(struct devfreq *devfreq, unsigned long freq);
8992

drivers/devfreq/tegra30-devfreq.c

Lines changed: 47 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,6 @@ struct tegra_devfreq_soc_data {
178178

179179
struct tegra_devfreq {
180180
struct devfreq *devfreq;
181-
struct opp_table *opp_table;
182181

183182
struct reset_control *reset;
184183
struct clk *clock;
@@ -789,6 +788,39 @@ static struct devfreq_governor tegra_devfreq_governor = {
789788
.event_handler = tegra_governor_event_handler,
790789
};
791790

791+
static void devm_tegra_devfreq_deinit_hw(void *data)
792+
{
793+
struct tegra_devfreq *tegra = data;
794+
795+
reset_control_reset(tegra->reset);
796+
clk_disable_unprepare(tegra->clock);
797+
}
798+
799+
static int devm_tegra_devfreq_init_hw(struct device *dev,
800+
struct tegra_devfreq *tegra)
801+
{
802+
int err;
803+
804+
err = clk_prepare_enable(tegra->clock);
805+
if (err) {
806+
dev_err(dev, "Failed to prepare and enable ACTMON clock\n");
807+
return err;
808+
}
809+
810+
err = devm_add_action_or_reset(dev, devm_tegra_devfreq_deinit_hw,
811+
tegra);
812+
if (err)
813+
return err;
814+
815+
err = reset_control_reset(tegra->reset);
816+
if (err) {
817+
dev_err(dev, "Failed to reset hardware: %d\n", err);
818+
return err;
819+
}
820+
821+
return err;
822+
}
823+
792824
static int tegra_devfreq_probe(struct platform_device *pdev)
793825
{
794826
u32 hw_version = BIT(tegra_sku_info.soc_speedo_id);
@@ -842,38 +874,26 @@ static int tegra_devfreq_probe(struct platform_device *pdev)
842874
return err;
843875
}
844876

845-
tegra->opp_table = dev_pm_opp_set_supported_hw(&pdev->dev,
846-
&hw_version, 1);
847-
err = PTR_ERR_OR_ZERO(tegra->opp_table);
877+
err = devm_pm_opp_set_supported_hw(&pdev->dev, &hw_version, 1);
848878
if (err) {
849879
dev_err(&pdev->dev, "Failed to set supported HW: %d\n", err);
850880
return err;
851881
}
852882

853-
err = dev_pm_opp_of_add_table_noclk(&pdev->dev, 0);
883+
err = devm_pm_opp_of_add_table_noclk(&pdev->dev, 0);
854884
if (err) {
855885
dev_err(&pdev->dev, "Failed to add OPP table: %d\n", err);
856-
goto put_hw;
857-
}
858-
859-
err = clk_prepare_enable(tegra->clock);
860-
if (err) {
861-
dev_err(&pdev->dev,
862-
"Failed to prepare and enable ACTMON clock\n");
863-
goto remove_table;
886+
return err;
864887
}
865888

866-
err = reset_control_reset(tegra->reset);
867-
if (err) {
868-
dev_err(&pdev->dev, "Failed to reset hardware: %d\n", err);
869-
goto disable_clk;
870-
}
889+
err = devm_tegra_devfreq_init_hw(&pdev->dev, tegra);
890+
if (err)
891+
return err;
871892

872893
rate = clk_round_rate(tegra->emc_clock, ULONG_MAX);
873-
if (rate < 0) {
894+
if (rate <= 0) {
874895
dev_err(&pdev->dev, "Failed to round clock rate: %ld\n", rate);
875-
err = rate;
876-
goto disable_clk;
896+
return rate ?: -EINVAL;
877897
}
878898

879899
tegra->max_freq = rate / KHZ;
@@ -892,52 +912,18 @@ static int tegra_devfreq_probe(struct platform_device *pdev)
892912
INIT_DELAYED_WORK(&tegra->cpufreq_update_work,
893913
tegra_actmon_delayed_update);
894914

895-
err = devfreq_add_governor(&tegra_devfreq_governor);
915+
err = devm_devfreq_add_governor(&pdev->dev, &tegra_devfreq_governor);
896916
if (err) {
897917
dev_err(&pdev->dev, "Failed to add governor: %d\n", err);
898-
goto remove_opps;
918+
return err;
899919
}
900920

901921
tegra_devfreq_profile.initial_freq = clk_get_rate(tegra->emc_clock);
902922

903-
devfreq = devfreq_add_device(&pdev->dev, &tegra_devfreq_profile,
904-
"tegra_actmon", NULL);
905-
if (IS_ERR(devfreq)) {
906-
err = PTR_ERR(devfreq);
907-
goto remove_governor;
908-
}
909-
910-
return 0;
911-
912-
remove_governor:
913-
devfreq_remove_governor(&tegra_devfreq_governor);
914-
915-
remove_opps:
916-
dev_pm_opp_remove_all_dynamic(&pdev->dev);
917-
918-
reset_control_reset(tegra->reset);
919-
disable_clk:
920-
clk_disable_unprepare(tegra->clock);
921-
remove_table:
922-
dev_pm_opp_of_remove_table(&pdev->dev);
923-
put_hw:
924-
dev_pm_opp_put_supported_hw(tegra->opp_table);
925-
926-
return err;
927-
}
928-
929-
static int tegra_devfreq_remove(struct platform_device *pdev)
930-
{
931-
struct tegra_devfreq *tegra = platform_get_drvdata(pdev);
932-
933-
devfreq_remove_device(tegra->devfreq);
934-
devfreq_remove_governor(&tegra_devfreq_governor);
935-
936-
reset_control_reset(tegra->reset);
937-
clk_disable_unprepare(tegra->clock);
938-
939-
dev_pm_opp_of_remove_table(&pdev->dev);
940-
dev_pm_opp_put_supported_hw(tegra->opp_table);
923+
devfreq = devm_devfreq_add_device(&pdev->dev, &tegra_devfreq_profile,
924+
"tegra_actmon", NULL);
925+
if (IS_ERR(devfreq))
926+
return PTR_ERR(devfreq);
941927

942928
return 0;
943929
}
@@ -967,7 +953,6 @@ MODULE_DEVICE_TABLE(of, tegra_devfreq_of_match);
967953

968954
static struct platform_driver tegra_devfreq_driver = {
969955
.probe = tegra_devfreq_probe,
970-
.remove = tegra_devfreq_remove,
971956
.driver = {
972957
.name = "tegra-devfreq",
973958
.of_match_table = tegra_devfreq_of_match,

drivers/opp/core.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2348,12 +2348,12 @@ static void _opp_detach_genpd(struct opp_table *opp_table)
23482348
* "required-opps" are added in DT.
23492349
*/
23502350
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)
23522352
{
23532353
struct opp_table *opp_table;
23542354
struct device *virt_dev;
23552355
int index = 0, ret = -EINVAL;
2356-
const char **name = names;
2356+
const char * const *name = names;
23572357

23582358
opp_table = _add_opp_table(dev, false);
23592359
if (IS_ERR(opp_table))
@@ -2457,7 +2457,7 @@ static void devm_pm_opp_detach_genpd(void *data)
24572457
*
24582458
* Return: 0 on success and errorno otherwise.
24592459
*/
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,
24612461
struct device ***virt_devs)
24622462
{
24632463
struct opp_table *opp_table;

drivers/opp/of.c

Lines changed: 41 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ static void _opp_table_alloc_required_tables(struct opp_table *opp_table,
170170
}
171171

172172
count = of_count_phandle_with_args(np, "required-opps", NULL);
173-
if (!count)
173+
if (count <= 0)
174174
goto put_np;
175175

176176
required_opp_tables = kcalloc(count, sizeof(*required_opp_tables),
@@ -921,7 +921,7 @@ static struct dev_pm_opp *_opp_add_static_v2(struct opp_table *opp_table,
921921
free_opp:
922922
_opp_free(new_opp);
923923

924-
return ERR_PTR(ret);
924+
return ret ? ERR_PTR(ret) : NULL;
925925
}
926926

927927
/* Initializes OPP tables based on new bindings */
@@ -1081,6 +1081,17 @@ static void devm_pm_opp_of_table_release(void *data)
10811081
dev_pm_opp_of_remove_table(data);
10821082
}
10831083

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+
10841095
/**
10851096
* devm_pm_opp_of_add_table() - Initialize opp table from device tree
10861097
* @dev: device pointer used to lookup OPP table.
@@ -1102,13 +1113,7 @@ static void devm_pm_opp_of_table_release(void *data)
11021113
*/
11031114
int devm_pm_opp_of_add_table(struct device *dev)
11041115
{
1105-
int ret;
1106-
1107-
ret = dev_pm_opp_of_add_table(dev);
1108-
if (ret)
1109-
return ret;
1110-
1111-
return devm_add_action_or_reset(dev, devm_pm_opp_of_table_release, dev);
1116+
return _devm_of_add_table_indexed(dev, 0, true);
11121117
}
11131118
EXPORT_SYMBOL_GPL(devm_pm_opp_of_add_table);
11141119

@@ -1151,6 +1156,19 @@ int dev_pm_opp_of_add_table_indexed(struct device *dev, int index)
11511156
}
11521157
EXPORT_SYMBOL_GPL(dev_pm_opp_of_add_table_indexed);
11531158

1159+
/**
1160+
* devm_pm_opp_of_add_table_indexed() - Initialize indexed opp table from device tree
1161+
* @dev: device pointer used to lookup OPP table.
1162+
* @index: Index number.
1163+
*
1164+
* This is a resource-managed variant of dev_pm_opp_of_add_table_indexed().
1165+
*/
1166+
int devm_pm_opp_of_add_table_indexed(struct device *dev, int index)
1167+
{
1168+
return _devm_of_add_table_indexed(dev, index, true);
1169+
}
1170+
EXPORT_SYMBOL_GPL(devm_pm_opp_of_add_table_indexed);
1171+
11541172
/**
11551173
* dev_pm_opp_of_add_table_noclk() - Initialize indexed opp table from device
11561174
* tree without getting clk for device.
@@ -1169,6 +1187,20 @@ int dev_pm_opp_of_add_table_noclk(struct device *dev, int index)
11691187
}
11701188
EXPORT_SYMBOL_GPL(dev_pm_opp_of_add_table_noclk);
11711189

1190+
/**
1191+
* devm_pm_opp_of_add_table_noclk() - Initialize indexed opp table from device
1192+
* tree without getting clk for device.
1193+
* @dev: device pointer used to lookup OPP table.
1194+
* @index: Index number.
1195+
*
1196+
* This is a resource-managed variant of dev_pm_opp_of_add_table_noclk().
1197+
*/
1198+
int devm_pm_opp_of_add_table_noclk(struct device *dev, int index)
1199+
{
1200+
return _devm_of_add_table_indexed(dev, index, false);
1201+
}
1202+
EXPORT_SYMBOL_GPL(devm_pm_opp_of_add_table_noclk);
1203+
11721204
/* CPU device specific helpers */
11731205

11741206
/**

include/linux/pm_opp.h

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -156,9 +156,9 @@ int devm_pm_opp_set_clkname(struct device *dev, const char *name);
156156
struct opp_table *dev_pm_opp_register_set_opp_helper(struct device *dev, int (*set_opp)(struct dev_pm_set_opp_data *data));
157157
void dev_pm_opp_unregister_set_opp_helper(struct opp_table *opp_table);
158158
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);
160160
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);
162162
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);
163163
int dev_pm_opp_xlate_performance_state(struct opp_table *src_table, struct opp_table *dst_table, unsigned int pstate);
164164
int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq);
@@ -376,15 +376,15 @@ static inline int devm_pm_opp_set_clkname(struct device *dev, const char *name)
376376
return -EOPNOTSUPP;
377377
}
378378

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)
380380
{
381381
return ERR_PTR(-EOPNOTSUPP);
382382
}
383383

384384
static inline void dev_pm_opp_detach_genpd(struct opp_table *opp_table) {}
385385

386386
static inline int devm_pm_opp_attach_genpd(struct device *dev,
387-
const char **names,
387+
const char * const *names,
388388
struct device ***virt_devs)
389389
{
390390
return -EOPNOTSUPP;
@@ -439,7 +439,9 @@ static inline int dev_pm_opp_sync_regulators(struct device *dev)
439439
#if defined(CONFIG_PM_OPP) && defined(CONFIG_OF)
440440
int dev_pm_opp_of_add_table(struct device *dev);
441441
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);
442443
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);
443445
void dev_pm_opp_of_remove_table(struct device *dev);
444446
int devm_pm_opp_of_add_table(struct device *dev);
445447
int dev_pm_opp_of_cpumask_add_table(const struct cpumask *cpumask);
@@ -465,11 +467,21 @@ static inline int dev_pm_opp_of_add_table_indexed(struct device *dev, int index)
465467
return -EOPNOTSUPP;
466468
}
467469

470+
static inline int devm_pm_opp_of_add_table_indexed(struct device *dev, int index)
471+
{
472+
return -EOPNOTSUPP;
473+
}
474+
468475
static inline int dev_pm_opp_of_add_table_noclk(struct device *dev, int index)
469476
{
470477
return -EOPNOTSUPP;
471478
}
472479

480+
static inline int devm_pm_opp_of_add_table_noclk(struct device *dev, int index)
481+
{
482+
return -EOPNOTSUPP;
483+
}
484+
473485
static inline void dev_pm_opp_of_remove_table(struct device *dev)
474486
{
475487
}

0 commit comments

Comments
 (0)