diff --git a/drivers/clk/clkdev.c b/drivers/clk/clkdev.c index 6db161f64ae..fdff32e9c05 100644 --- a/drivers/clk/clkdev.c +++ b/drivers/clk/clkdev.c @@ -83,6 +83,31 @@ struct clk *clk_get(struct device *dev, const char *con_id) } EXPORT_SYMBOL(clk_get); +static void devm_clk_release(struct device *dev, void *res) +{ + clk_put(*(struct clk **)res); +} + +struct clk *devm_clk_get(struct device *dev, const char *id) +{ + struct clk **ptr, *clk; + + ptr = devres_alloc(devm_clk_release, sizeof(*ptr), GFP_KERNEL); + if (!ptr) + return ERR_PTR(-ENOMEM); + + clk = clk_get(dev, id); + if (!IS_ERR(clk)) { + *ptr = clk; + devres_add(dev, ptr); + } else { + devres_free(ptr); + } + + return clk; +} +EXPORT_SYMBOL(devm_clk_get); + void clk_put(struct clk *clk) { __clk_put(clk); diff --git a/include/linux/clk.h b/include/linux/clk.h index b0252726df6..bb5d6f87814 100644 --- a/include/linux/clk.h +++ b/include/linux/clk.h @@ -100,6 +100,16 @@ int clk_notifier_unregister(struct clk *clk, struct notifier_block *nb); */ struct clk *clk_get(struct device *dev, const char *id); +/** + * devm_clk_get - Resource managed clk_get() + * @dev: device for clk "consumer" + * @id: clk ID. + * + * Managed clk_get(). Clocks returned from this function are + * automatically clk_put() on driver detach. + */ +struct clk *devm_clk_get(struct device *dev, const char *id); + /** * clk_prepare - prepare a clock source * @clk: clock source