Skip to content

Commit 9934a1b

Browse files
Bartosz Golaszewskibebarino
authored andcommitted
clk: provide devm_clk_get_optional_enabled_with_rate()
There are clock users in the kernel that can't use devm_clk_get_optional_enabled() as they need to set rate after getting the clock and before enabling it. Provide a managed helper that wraps these operations in the correct order. Signed-off-by: Bartosz Golaszewski <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Stephen Boyd <[email protected]>
1 parent 706ae64 commit 9934a1b

File tree

2 files changed

+61
-0
lines changed

2 files changed

+61
-0
lines changed

drivers/clk/clk-devres.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,34 @@ struct clk *devm_clk_get_optional_enabled(struct device *dev, const char *id)
9999
}
100100
EXPORT_SYMBOL_GPL(devm_clk_get_optional_enabled);
101101

102+
struct clk *devm_clk_get_optional_enabled_with_rate(struct device *dev,
103+
const char *id,
104+
unsigned long rate)
105+
{
106+
struct clk *clk;
107+
int ret;
108+
109+
clk = __devm_clk_get(dev, id, clk_get_optional, NULL,
110+
clk_disable_unprepare);
111+
if (IS_ERR(clk))
112+
return ERR_CAST(clk);
113+
114+
ret = clk_set_rate(clk, rate);
115+
if (ret)
116+
goto out_put_clk;
117+
118+
ret = clk_prepare_enable(clk);
119+
if (ret)
120+
goto out_put_clk;
121+
122+
return clk;
123+
124+
out_put_clk:
125+
devm_clk_put(dev, clk);
126+
return ERR_PTR(ret);
127+
}
128+
EXPORT_SYMBOL_GPL(devm_clk_get_optional_enabled_with_rate);
129+
102130
struct clk_bulk_devres {
103131
struct clk_bulk_data *clks;
104132
int num_clks;

include/linux/clk.h

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -640,6 +640,32 @@ struct clk *devm_clk_get_optional_prepared(struct device *dev, const char *id);
640640
*/
641641
struct clk *devm_clk_get_optional_enabled(struct device *dev, const char *id);
642642

643+
/**
644+
* devm_clk_get_optional_enabled_with_rate - devm_clk_get_optional() +
645+
* clk_set_rate() +
646+
* clk_prepare_enable()
647+
* @dev: device for clock "consumer"
648+
* @id: clock consumer ID
649+
* @rate: new clock rate
650+
*
651+
* Context: May sleep.
652+
*
653+
* Return: a struct clk corresponding to the clock producer, or
654+
* valid IS_ERR() condition containing errno. The implementation
655+
* uses @dev and @id to determine the clock consumer, and thereby
656+
* the clock producer. If no such clk is found, it returns NULL
657+
* which serves as a dummy clk. That's the only difference compared
658+
* to devm_clk_get_enabled().
659+
*
660+
* The returned clk (if valid) is prepared and enabled and rate was set.
661+
*
662+
* The clock will automatically be disabled, unprepared and freed
663+
* when the device is unbound from the bus.
664+
*/
665+
struct clk *devm_clk_get_optional_enabled_with_rate(struct device *dev,
666+
const char *id,
667+
unsigned long rate);
668+
643669
/**
644670
* devm_get_clk_from_child - lookup and obtain a managed reference to a
645671
* clock producer from child node.
@@ -982,6 +1008,13 @@ static inline struct clk *devm_clk_get_optional_enabled(struct device *dev,
9821008
return NULL;
9831009
}
9841010

1011+
static inline struct clk *
1012+
devm_clk_get_optional_enabled_with_rate(struct device *dev, const char *id,
1013+
unsigned long rate)
1014+
{
1015+
return NULL;
1016+
}
1017+
9851018
static inline int __must_check devm_clk_bulk_get(struct device *dev, int num_clks,
9861019
struct clk_bulk_data *clks)
9871020
{

0 commit comments

Comments
 (0)