{
struct clk_lookup *cl;
-- --- if (IS_ERR(hw))
-- --- return PTR_ERR(hw);
++ +++ return do_clk_register_clkdev(hw, &cl, con_id, dev_id);
++ +++}
++ +++EXPORT_SYMBOL(clk_hw_register_clkdev);
-- --- /*
-- --- * Since dev_id can be NULL, and NULL is handled specially, we must
-- --- * pass it as either a NULL format string, or with "%s".
-- --- */
-- --- if (dev_id)
-- --- cl = __clk_register_clkdev(hw, con_id, "%s", dev_id);
-- --- else
-- --- cl = __clk_register_clkdev(hw, con_id, NULL);
++ +++static void devm_clkdev_release(struct device *dev, void *res)
++ +++{
++ +++ clkdev_drop(*(struct clk_lookup **)res);
++ +++}
+ +++
- return cl ? 0 : -ENOMEM;
++ +++static int devm_clk_match_clkdev(struct device *dev, void *res, void *data)
++ +++{
++ +++ struct clk_lookup **l = res;
+
- --- return cl ? 0 : -ENOMEM;
++ +++ return *l == data;
}
-- ---EXPORT_SYMBOL(clk_hw_register_clkdev);
++ +++
++ +++/**
++ +++ * devm_clk_release_clkdev - Resource managed clkdev lookup release
++ +++ * @dev: device this lookup is bound
++ +++ * @con_id: connection ID string on device
++ +++ * @dev_id: format string describing device name
++ +++ *
++ +++ * Drop the clkdev lookup created with devm_clk_hw_register_clkdev.
++ +++ * Normally this function will not need to be called and the resource
++ +++ * management code will ensure that the resource is freed.
++ +++ */
++ +++void devm_clk_release_clkdev(struct device *dev, const char *con_id,
++ +++ const char *dev_id)
++ +++{
++ +++ struct clk_lookup *cl;
++ +++ int rval;
++ +++
++ +++ cl = clk_find(dev_id, con_id);
++ +++ WARN_ON(!cl);
++ +++ rval = devres_release(dev, devm_clkdev_release,
++ +++ devm_clk_match_clkdev, cl);
++ +++ WARN_ON(rval);
++ +++}
++ +++EXPORT_SYMBOL(devm_clk_release_clkdev);
++ +++
++ +++/**
++ +++ * devm_clk_hw_register_clkdev - managed clk lookup registration for clk_hw
++ +++ * @dev: device this lookup is bound
++ +++ * @hw: struct clk_hw to associate with all clk_lookups
++ +++ * @con_id: connection ID string on device
++ +++ * @dev_id: format string describing device name
++ +++ *
++ +++ * con_id or dev_id may be NULL as a wildcard, just as in the rest of
++ +++ * clkdev.
++ +++ *
++ +++ * To make things easier for mass registration, we detect error clk_hws
++ +++ * from a previous clk_hw_register_*() call, and return the error code for
++ +++ * those. This is to permit this function to be called immediately
++ +++ * after clk_hw_register_*().
++ +++ */
++ +++int devm_clk_hw_register_clkdev(struct device *dev, struct clk_hw *hw,
++ +++ const char *con_id, const char *dev_id)
++ +++{
++ +++ int rval = -ENOMEM;
++ +++ struct clk_lookup **cl;
++ +++
++ +++ cl = devres_alloc(devm_clkdev_release, sizeof(*cl), GFP_KERNEL);
++ +++ if (cl) {
++ +++ rval = do_clk_register_clkdev(hw, cl, con_id, dev_id);
++ +++ if (!rval)
++ +++ devres_add(dev, cl);
++ +++ else
++ +++ devres_free(cl);
++ +++ }
++ +++ return rval;
++ +++}
++ +++EXPORT_SYMBOL(devm_clk_hw_register_clkdev);