diff options
Diffstat (limited to 'target/linux/generic/pending-4.4/083-0001-clk-Add-devm_-clk_hw_-register-unregister-APIs.patch')
-rw-r--r-- | target/linux/generic/pending-4.4/083-0001-clk-Add-devm_-clk_hw_-register-unregister-APIs.patch | 182 |
1 files changed, 182 insertions, 0 deletions
diff --git a/target/linux/generic/pending-4.4/083-0001-clk-Add-devm_-clk_hw_-register-unregister-APIs.patch b/target/linux/generic/pending-4.4/083-0001-clk-Add-devm_-clk_hw_-register-unregister-APIs.patch new file mode 100644 index 0000000000..0408353138 --- /dev/null +++ b/target/linux/generic/pending-4.4/083-0001-clk-Add-devm_-clk_hw_-register-unregister-APIs.patch @@ -0,0 +1,182 @@ +From 4143804c4fdef40358c654d1fb2271a1a0f1fedf Mon Sep 17 00:00:00 2001 +From: Stephen Boyd <sboyd@codeaurora.org> +Date: Fri, 5 Feb 2016 17:02:52 -0800 +Subject: [PATCH] clk: Add {devm_}clk_hw_{register,unregister}() APIs + +We've largely split the clk consumer and provider APIs along +struct clk and struct clk_hw, but clk_register() still returns a +struct clk pointer for each struct clk_hw that's registered. +Eventually we'd like to only allocate struct clks when there's a +user, because struct clk is per-user now, so clk_register() needs +to change. + +Let's add new APIs to register struct clk_hws, but this time +we'll hide the struct clk from the caller by returning an int +error code. Also add an unregistration API that takes the clk_hw +structure that was passed to the registration API. This way +provider drivers never have to deal with a struct clk pointer +unless they're using the clk consumer APIs. + +Signed-off-by: Stephen Boyd <sboyd@codeaurora.org> +--- + Documentation/driver-model/devres.txt | 1 + + drivers/clk/clk.c | 86 +++++++++++++++++++++++++++++++++++ + include/linux/clk-provider.h | 6 +++ + 3 files changed, 93 insertions(+) + +--- a/Documentation/driver-model/devres.txt ++++ b/Documentation/driver-model/devres.txt +@@ -236,6 +236,7 @@ certainly invest a bit more effort into + CLOCK + devm_clk_get() + devm_clk_put() ++ devm_clk_hw_register() + + DMA + dmam_alloc_coherent() +--- a/drivers/clk/clk.c ++++ b/drivers/clk/clk.c +@@ -2595,6 +2595,22 @@ fail_out: + } + EXPORT_SYMBOL_GPL(clk_register); + ++/** ++ * clk_hw_register - register a clk_hw and return an error code ++ * @dev: device that is registering this clock ++ * @hw: link to hardware-specific clock data ++ * ++ * clk_hw_register is the primary interface for populating the clock tree with ++ * new clock nodes. It returns an integer equal to zero indicating success or ++ * less than zero indicating failure. Drivers must test for an error code after ++ * calling clk_hw_register(). ++ */ ++int clk_hw_register(struct device *dev, struct clk_hw *hw) ++{ ++ return PTR_ERR_OR_ZERO(clk_register(dev, hw)); ++} ++EXPORT_SYMBOL_GPL(clk_hw_register); ++ + /* Free memory allocated for a clock. */ + static void __clk_release(struct kref *ref) + { +@@ -2696,11 +2712,26 @@ void clk_unregister(struct clk *clk) + } + EXPORT_SYMBOL_GPL(clk_unregister); + ++/** ++ * clk_hw_unregister - unregister a currently registered clk_hw ++ * @hw: hardware-specific clock data to unregister ++ */ ++void clk_hw_unregister(struct clk_hw *hw) ++{ ++ clk_unregister(hw->clk); ++} ++EXPORT_SYMBOL_GPL(clk_hw_unregister); ++ + static void devm_clk_release(struct device *dev, void *res) + { + clk_unregister(*(struct clk **)res); + } + ++static void devm_clk_hw_release(struct device *dev, void *res) ++{ ++ clk_hw_unregister(*(struct clk_hw **)res); ++} ++ + /** + * devm_clk_register - resource managed clk_register() + * @dev: device that is registering this clock +@@ -2731,6 +2762,36 @@ struct clk *devm_clk_register(struct dev + } + EXPORT_SYMBOL_GPL(devm_clk_register); + ++/** ++ * devm_clk_hw_register - resource managed clk_hw_register() ++ * @dev: device that is registering this clock ++ * @hw: link to hardware-specific clock data ++ * ++ * Managed clk_hw_register(). Clocks returned from this function are ++ * automatically clk_hw_unregister()ed on driver detach. See clk_hw_register() ++ * for more information. ++ */ ++int devm_clk_hw_register(struct device *dev, struct clk_hw *hw) ++{ ++ struct clk_hw **hwp; ++ int ret; ++ ++ hwp = devres_alloc(devm_clk_hw_release, sizeof(*hwp), GFP_KERNEL); ++ if (!hwp) ++ return -ENOMEM; ++ ++ ret = clk_hw_register(dev, hw); ++ if (!ret) { ++ *hwp = hw; ++ devres_add(dev, hwp); ++ } else { ++ devres_free(hwp); ++ } ++ ++ return ret; ++} ++EXPORT_SYMBOL_GPL(devm_clk_hw_register); ++ + static int devm_clk_match(struct device *dev, void *res, void *data) + { + struct clk *c = res; +@@ -2739,6 +2800,15 @@ static int devm_clk_match(struct device + return c == data; + } + ++static int devm_clk_hw_match(struct device *dev, void *res, void *data) ++{ ++ struct clk_hw *hw = res; ++ ++ if (WARN_ON(!hw)) ++ return 0; ++ return hw == data; ++} ++ + /** + * devm_clk_unregister - resource managed clk_unregister() + * @clk: clock to unregister +@@ -2753,6 +2823,22 @@ void devm_clk_unregister(struct device * + } + EXPORT_SYMBOL_GPL(devm_clk_unregister); + ++/** ++ * devm_clk_hw_unregister - resource managed clk_hw_unregister() ++ * @dev: device that is unregistering the hardware-specific clock data ++ * @hw: link to hardware-specific clock data ++ * ++ * Unregister a clk_hw registered with devm_clk_hw_register(). Normally ++ * this function will not need to be called and the resource management ++ * code will ensure that the resource is freed. ++ */ ++void devm_clk_hw_unregister(struct device *dev, struct clk_hw *hw) ++{ ++ WARN_ON(devres_release(dev, devm_clk_hw_release, devm_clk_hw_match, ++ hw)); ++} ++EXPORT_SYMBOL_GPL(devm_clk_hw_unregister); ++ + /* + * clkdev helpers + */ +--- a/include/linux/clk-provider.h ++++ b/include/linux/clk-provider.h +@@ -639,9 +639,15 @@ void of_gpio_mux_clk_setup(struct device + struct clk *clk_register(struct device *dev, struct clk_hw *hw); + struct clk *devm_clk_register(struct device *dev, struct clk_hw *hw); + ++int __must_check clk_hw_register(struct device *dev, struct clk_hw *hw); ++int __must_check devm_clk_hw_register(struct device *dev, struct clk_hw *hw); ++ + void clk_unregister(struct clk *clk); + void devm_clk_unregister(struct device *dev, struct clk *clk); + ++void clk_hw_unregister(struct clk_hw *hw); ++void devm_clk_hw_unregister(struct device *dev, struct clk_hw *hw); ++ + /* helper functions */ + const char *__clk_get_name(const struct clk *clk); + const char *clk_hw_get_name(const struct clk_hw *hw); |