diff options
Diffstat (limited to 'drivers/clk/clk-devres.c')
| -rw-r--r-- | drivers/clk/clk-devres.c | 55 | 
1 files changed, 55 insertions, 0 deletions
diff --git a/drivers/clk/clk-devres.c b/drivers/clk/clk-devres.c new file mode 100644 index 00000000000..8f571548870 --- /dev/null +++ b/drivers/clk/clk-devres.c @@ -0,0 +1,55 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/clk.h> +#include <linux/device.h> +#include <linux/export.h> +#include <linux/gfp.h> + +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); + +static int devm_clk_match(struct device *dev, void *res, void *data) +{ +	struct clk **c = res; +	if (!c || !*c) { +		WARN_ON(!c || !*c); +		return 0; +	} +	return *c == data; +} + +void devm_clk_put(struct device *dev, struct clk *clk) +{ +	int ret; + +	ret = devres_release(dev, devm_clk_release, devm_clk_match, clk); + +	WARN_ON(ret); +} +EXPORT_SYMBOL(devm_clk_put);  |