clk: Provide new devm_clk helpers for prepared and enabled clocks

[ Upstream commit 7ef9651e9792b08eb310c6beb202cbc947f43cab ]

When a driver keeps a clock prepared (or enabled) during the whole
lifetime of the driver, these helpers allow to simplify the drivers.

Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Reviewed-by: Alexandru Ardelean <aardelean@deviqon.com>
Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Link: https://lore.kernel.org/r/20220520075737.758761-4-u.kleine-koenig@pengutronix.de
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
Stable-dep-of: 340cb392a038 ("memory: atmel-sdramc: Fix missing clk_disable_unprepare in atmel_ramc_probe()")
Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
Uwe Kleine-König 2022-05-20 09:57:36 +02:00 committed by Greg Kroah-Hartman
parent c7ef7185a1
commit 310268050d
2 changed files with 136 additions and 0 deletions

View File

@ -66,12 +66,39 @@ struct clk *devm_clk_get(struct device *dev, const char *id)
}
EXPORT_SYMBOL(devm_clk_get);
struct clk *devm_clk_get_prepared(struct device *dev, const char *id)
{
return __devm_clk_get(dev, id, clk_get, clk_prepare, clk_unprepare);
}
EXPORT_SYMBOL_GPL(devm_clk_get_prepared);
struct clk *devm_clk_get_enabled(struct device *dev, const char *id)
{
return __devm_clk_get(dev, id, clk_get,
clk_prepare_enable, clk_disable_unprepare);
}
EXPORT_SYMBOL_GPL(devm_clk_get_enabled);
struct clk *devm_clk_get_optional(struct device *dev, const char *id)
{
return __devm_clk_get(dev, id, clk_get_optional, NULL, NULL);
}
EXPORT_SYMBOL(devm_clk_get_optional);
struct clk *devm_clk_get_optional_prepared(struct device *dev, const char *id)
{
return __devm_clk_get(dev, id, clk_get_optional,
clk_prepare, clk_unprepare);
}
EXPORT_SYMBOL_GPL(devm_clk_get_optional_prepared);
struct clk *devm_clk_get_optional_enabled(struct device *dev, const char *id)
{
return __devm_clk_get(dev, id, clk_get_optional,
clk_prepare_enable, clk_disable_unprepare);
}
EXPORT_SYMBOL_GPL(devm_clk_get_optional_enabled);
struct clk_bulk_devres {
struct clk_bulk_data *clks;
int num_clks;

View File

@ -418,6 +418,47 @@ int __must_check devm_clk_bulk_get_all(struct device *dev,
*/
struct clk *devm_clk_get(struct device *dev, const char *id);
/**
* devm_clk_get_prepared - devm_clk_get() + clk_prepare()
* @dev: device for clock "consumer"
* @id: clock consumer ID
*
* Context: May sleep.
*
* Return: a struct clk corresponding to the clock producer, or
* valid IS_ERR() condition containing errno. The implementation
* uses @dev and @id to determine the clock consumer, and thereby
* the clock producer. (IOW, @id may be identical strings, but
* clk_get may return different clock producers depending on @dev.)
*
* The returned clk (if valid) is prepared. Drivers must however assume
* that the clock is not enabled.
*
* The clock will automatically be unprepared and freed when the device
* is unbound from the bus.
*/
struct clk *devm_clk_get_prepared(struct device *dev, const char *id);
/**
* devm_clk_get_enabled - devm_clk_get() + clk_prepare_enable()
* @dev: device for clock "consumer"
* @id: clock consumer ID
*
* Context: May sleep.
*
* Return: a struct clk corresponding to the clock producer, or
* valid IS_ERR() condition containing errno. The implementation
* uses @dev and @id to determine the clock consumer, and thereby
* the clock producer. (IOW, @id may be identical strings, but
* clk_get may return different clock producers depending on @dev.)
*
* The returned clk (if valid) is prepared and enabled.
*
* The clock will automatically be disabled, unprepared and freed
* when the device is unbound from the bus.
*/
struct clk *devm_clk_get_enabled(struct device *dev, const char *id);
/**
* devm_clk_get_optional - lookup and obtain a managed reference to an optional
* clock producer.
@ -429,6 +470,50 @@ struct clk *devm_clk_get(struct device *dev, const char *id);
*/
struct clk *devm_clk_get_optional(struct device *dev, const char *id);
/**
* devm_clk_get_optional_prepared - devm_clk_get_optional() + clk_prepare()
* @dev: device for clock "consumer"
* @id: clock consumer ID
*
* Context: May sleep.
*
* Return: a struct clk corresponding to the clock producer, or
* valid IS_ERR() condition containing errno. The implementation
* uses @dev and @id to determine the clock consumer, and thereby
* the clock producer. If no such clk is found, it returns NULL
* which serves as a dummy clk. That's the only difference compared
* to devm_clk_get_prepared().
*
* The returned clk (if valid) is prepared. Drivers must however
* assume that the clock is not enabled.
*
* The clock will automatically be unprepared and freed when the
* device is unbound from the bus.
*/
struct clk *devm_clk_get_optional_prepared(struct device *dev, const char *id);
/**
* devm_clk_get_optional_enabled - devm_clk_get_optional() +
* clk_prepare_enable()
* @dev: device for clock "consumer"
* @id: clock consumer ID
*
* Context: May sleep.
*
* Return: a struct clk corresponding to the clock producer, or
* valid IS_ERR() condition containing errno. The implementation
* uses @dev and @id to determine the clock consumer, and thereby
* the clock producer. If no such clk is found, it returns NULL
* which serves as a dummy clk. That's the only difference compared
* to devm_clk_get_enabled().
*
* The returned clk (if valid) is prepared and enabled.
*
* The clock will automatically be disabled, unprepared and freed
* when the device is unbound from the bus.
*/
struct clk *devm_clk_get_optional_enabled(struct device *dev, const char *id);
/**
* devm_get_clk_from_child - lookup and obtain a managed reference to a
* clock producer from child node.
@ -770,12 +855,36 @@ static inline struct clk *devm_clk_get(struct device *dev, const char *id)
return NULL;
}
static inline struct clk *devm_clk_get_prepared(struct device *dev,
const char *id)
{
return NULL;
}
static inline struct clk *devm_clk_get_enabled(struct device *dev,
const char *id)
{
return NULL;
}
static inline struct clk *devm_clk_get_optional(struct device *dev,
const char *id)
{
return NULL;
}
static inline struct clk *devm_clk_get_optional_prepared(struct device *dev,
const char *id)
{
return NULL;
}
static inline struct clk *devm_clk_get_optional_enabled(struct device *dev,
const char *id)
{
return NULL;
}
static inline int __must_check devm_clk_bulk_get(struct device *dev, int num_clks,
struct clk_bulk_data *clks)
{