From 64990c839bbffe65641e80249f98f0c19c03cf24 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Fri, 23 Mar 2012 15:21:12 -0700 Subject: [PATCH] clk: Add devm_clk_get() Add a resource managed clk_get() to simplify clock usage in drivers. This allows driver authors to "get and forget" about their clocks by automatically calling clk_put() when the driver is detached. This also encourages clock consumers to use the clk_get() API correctly by passing in a struct device as an argument. Change-Id: I1ed53cd3c26c0390fa30cd3c3dca14bcdd59939f Signed-off-by: Stephen Boyd --- drivers/clk/clkdev.c | 25 +++++++++++++++++++++++++ include/linux/clk.h | 10 ++++++++++ 2 files changed, 35 insertions(+) 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