aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/clk/clk.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/clk/clk.c')
-rw-r--r--drivers/clk/clk.c222
1 files changed, 218 insertions, 4 deletions
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index fb74dc1f7520..d584004f7af7 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -574,6 +574,9 @@ static void clk_core_unprepare(struct clk_core *core)
574 if (WARN_ON(core->prepare_count == 0)) 574 if (WARN_ON(core->prepare_count == 0))
575 return; 575 return;
576 576
577 if (WARN_ON(core->prepare_count == 1 && core->flags & CLK_IS_CRITICAL))
578 return;
579
577 if (--core->prepare_count > 0) 580 if (--core->prepare_count > 0)
578 return; 581 return;
579 582
@@ -679,6 +682,9 @@ static void clk_core_disable(struct clk_core *core)
679 if (WARN_ON(core->enable_count == 0)) 682 if (WARN_ON(core->enable_count == 0))
680 return; 683 return;
681 684
685 if (WARN_ON(core->enable_count == 1 && core->flags & CLK_IS_CRITICAL))
686 return;
687
682 if (--core->enable_count > 0) 688 if (--core->enable_count > 0)
683 return; 689 return;
684 690
@@ -2397,6 +2403,16 @@ static int __clk_core_init(struct clk_core *core)
2397 if (core->ops->init) 2403 if (core->ops->init)
2398 core->ops->init(core->hw); 2404 core->ops->init(core->hw);
2399 2405
2406 if (core->flags & CLK_IS_CRITICAL) {
2407 unsigned long flags;
2408
2409 clk_core_prepare(core);
2410
2411 flags = clk_enable_lock();
2412 clk_core_enable(core);
2413 clk_enable_unlock(flags);
2414 }
2415
2400 kref_init(&core->ref); 2416 kref_init(&core->ref);
2401out: 2417out:
2402 clk_prepare_unlock(); 2418 clk_prepare_unlock();
@@ -2536,6 +2552,22 @@ fail_out:
2536} 2552}
2537EXPORT_SYMBOL_GPL(clk_register); 2553EXPORT_SYMBOL_GPL(clk_register);
2538 2554
2555/**
2556 * clk_hw_register - register a clk_hw and return an error code
2557 * @dev: device that is registering this clock
2558 * @hw: link to hardware-specific clock data
2559 *
2560 * clk_hw_register is the primary interface for populating the clock tree with
2561 * new clock nodes. It returns an integer equal to zero indicating success or
2562 * less than zero indicating failure. Drivers must test for an error code after
2563 * calling clk_hw_register().
2564 */
2565int clk_hw_register(struct device *dev, struct clk_hw *hw)
2566{
2567 return PTR_ERR_OR_ZERO(clk_register(dev, hw));
2568}
2569EXPORT_SYMBOL_GPL(clk_hw_register);
2570
2539/* Free memory allocated for a clock. */ 2571/* Free memory allocated for a clock. */
2540static void __clk_release(struct kref *ref) 2572static void __clk_release(struct kref *ref)
2541{ 2573{
@@ -2637,11 +2669,26 @@ unlock:
2637} 2669}
2638EXPORT_SYMBOL_GPL(clk_unregister); 2670EXPORT_SYMBOL_GPL(clk_unregister);
2639 2671
2672/**
2673 * clk_hw_unregister - unregister a currently registered clk_hw
2674 * @hw: hardware-specific clock data to unregister
2675 */
2676void clk_hw_unregister(struct clk_hw *hw)
2677{
2678 clk_unregister(hw->clk);
2679}
2680EXPORT_SYMBOL_GPL(clk_hw_unregister);
2681
2640static void devm_clk_release(struct device *dev, void *res) 2682static void devm_clk_release(struct device *dev, void *res)
2641{ 2683{
2642 clk_unregister(*(struct clk **)res); 2684 clk_unregister(*(struct clk **)res);
2643} 2685}
2644 2686
2687static void devm_clk_hw_release(struct device *dev, void *res)
2688{
2689 clk_hw_unregister(*(struct clk_hw **)res);
2690}
2691
2645/** 2692/**
2646 * devm_clk_register - resource managed clk_register() 2693 * devm_clk_register - resource managed clk_register()
2647 * @dev: device that is registering this clock 2694 * @dev: device that is registering this clock
@@ -2672,6 +2719,36 @@ struct clk *devm_clk_register(struct device *dev, struct clk_hw *hw)
2672} 2719}
2673EXPORT_SYMBOL_GPL(devm_clk_register); 2720EXPORT_SYMBOL_GPL(devm_clk_register);
2674 2721
2722/**
2723 * devm_clk_hw_register - resource managed clk_hw_register()
2724 * @dev: device that is registering this clock
2725 * @hw: link to hardware-specific clock data
2726 *
2727 * Managed clk_hw_register(). Clocks registered by this function are
2728 * automatically clk_hw_unregister()ed on driver detach. See clk_hw_register()
2729 * for more information.
2730 */
2731int devm_clk_hw_register(struct device *dev, struct clk_hw *hw)
2732{
2733 struct clk_hw **hwp;
2734 int ret;
2735
2736 hwp = devres_alloc(devm_clk_hw_release, sizeof(*hwp), GFP_KERNEL);
2737 if (!hwp)
2738 return -ENOMEM;
2739
2740 ret = clk_hw_register(dev, hw);
2741 if (!ret) {
2742 *hwp = hw;
2743 devres_add(dev, hwp);
2744 } else {
2745 devres_free(hwp);
2746 }
2747
2748 return ret;
2749}
2750EXPORT_SYMBOL_GPL(devm_clk_hw_register);
2751
2675static int devm_clk_match(struct device *dev, void *res, void *data) 2752static int devm_clk_match(struct device *dev, void *res, void *data)
2676{ 2753{
2677 struct clk *c = res; 2754 struct clk *c = res;
@@ -2680,6 +2757,15 @@ static int devm_clk_match(struct device *dev, void *res, void *data)
2680 return c == data; 2757 return c == data;
2681} 2758}
2682 2759
2760static int devm_clk_hw_match(struct device *dev, void *res, void *data)
2761{
2762 struct clk_hw *hw = res;
2763
2764 if (WARN_ON(!hw))
2765 return 0;
2766 return hw == data;
2767}
2768
2683/** 2769/**
2684 * devm_clk_unregister - resource managed clk_unregister() 2770 * devm_clk_unregister - resource managed clk_unregister()
2685 * @clk: clock to unregister 2771 * @clk: clock to unregister
@@ -2694,6 +2780,22 @@ void devm_clk_unregister(struct device *dev, struct clk *clk)
2694} 2780}
2695EXPORT_SYMBOL_GPL(devm_clk_unregister); 2781EXPORT_SYMBOL_GPL(devm_clk_unregister);
2696 2782
2783/**
2784 * devm_clk_hw_unregister - resource managed clk_hw_unregister()
2785 * @dev: device that is unregistering the hardware-specific clock data
2786 * @hw: link to hardware-specific clock data
2787 *
2788 * Unregister a clk_hw registered with devm_clk_hw_register(). Normally
2789 * this function will not need to be called and the resource management
2790 * code will ensure that the resource is freed.
2791 */
2792void devm_clk_hw_unregister(struct device *dev, struct clk_hw *hw)
2793{
2794 WARN_ON(devres_release(dev, devm_clk_hw_release, devm_clk_hw_match,
2795 hw));
2796}
2797EXPORT_SYMBOL_GPL(devm_clk_hw_unregister);
2798
2697/* 2799/*
2698 * clkdev helpers 2800 * clkdev helpers
2699 */ 2801 */
@@ -2855,6 +2957,7 @@ struct of_clk_provider {
2855 2957
2856 struct device_node *node; 2958 struct device_node *node;
2857 struct clk *(*get)(struct of_phandle_args *clkspec, void *data); 2959 struct clk *(*get)(struct of_phandle_args *clkspec, void *data);
2960 struct clk_hw *(*get_hw)(struct of_phandle_args *clkspec, void *data);
2858 void *data; 2961 void *data;
2859}; 2962};
2860 2963
@@ -2871,6 +2974,12 @@ struct clk *of_clk_src_simple_get(struct of_phandle_args *clkspec,
2871} 2974}
2872EXPORT_SYMBOL_GPL(of_clk_src_simple_get); 2975EXPORT_SYMBOL_GPL(of_clk_src_simple_get);
2873 2976
2977struct clk_hw *of_clk_hw_simple_get(struct of_phandle_args *clkspec, void *data)
2978{
2979 return data;
2980}
2981EXPORT_SYMBOL_GPL(of_clk_hw_simple_get);
2982
2874struct clk *of_clk_src_onecell_get(struct of_phandle_args *clkspec, void *data) 2983struct clk *of_clk_src_onecell_get(struct of_phandle_args *clkspec, void *data)
2875{ 2984{
2876 struct clk_onecell_data *clk_data = data; 2985 struct clk_onecell_data *clk_data = data;
@@ -2885,6 +2994,21 @@ struct clk *of_clk_src_onecell_get(struct of_phandle_args *clkspec, void *data)
2885} 2994}
2886EXPORT_SYMBOL_GPL(of_clk_src_onecell_get); 2995EXPORT_SYMBOL_GPL(of_clk_src_onecell_get);
2887 2996
2997struct clk_hw *
2998of_clk_hw_onecell_get(struct of_phandle_args *clkspec, void *data)
2999{
3000 struct clk_hw_onecell_data *hw_data = data;
3001 unsigned int idx = clkspec->args[0];
3002
3003 if (idx >= hw_data->num) {
3004 pr_err("%s: invalid index %u\n", __func__, idx);
3005 return ERR_PTR(-EINVAL);
3006 }
3007
3008 return hw_data->hws[idx];
3009}
3010EXPORT_SYMBOL_GPL(of_clk_hw_onecell_get);
3011
2888/** 3012/**
2889 * of_clk_add_provider() - Register a clock provider for a node 3013 * of_clk_add_provider() - Register a clock provider for a node
2890 * @np: Device node pointer associated with clock provider 3014 * @np: Device node pointer associated with clock provider
@@ -2921,6 +3045,41 @@ int of_clk_add_provider(struct device_node *np,
2921EXPORT_SYMBOL_GPL(of_clk_add_provider); 3045EXPORT_SYMBOL_GPL(of_clk_add_provider);
2922 3046
2923/** 3047/**
3048 * of_clk_add_hw_provider() - Register a clock provider for a node
3049 * @np: Device node pointer associated with clock provider
3050 * @get: callback for decoding clk_hw
3051 * @data: context pointer for @get callback.
3052 */
3053int of_clk_add_hw_provider(struct device_node *np,
3054 struct clk_hw *(*get)(struct of_phandle_args *clkspec,
3055 void *data),
3056 void *data)
3057{
3058 struct of_clk_provider *cp;
3059 int ret;
3060
3061 cp = kzalloc(sizeof(*cp), GFP_KERNEL);
3062 if (!cp)
3063 return -ENOMEM;
3064
3065 cp->node = of_node_get(np);
3066 cp->data = data;
3067 cp->get_hw = get;
3068
3069 mutex_lock(&of_clk_mutex);
3070 list_add(&cp->link, &of_clk_providers);
3071 mutex_unlock(&of_clk_mutex);
3072 pr_debug("Added clk_hw provider from %s\n", np->full_name);
3073
3074 ret = of_clk_set_defaults(np, true);
3075 if (ret < 0)
3076 of_clk_del_provider(np);
3077
3078 return ret;
3079}
3080EXPORT_SYMBOL_GPL(of_clk_add_hw_provider);
3081
3082/**
2924 * of_clk_del_provider() - Remove a previously registered clock provider 3083 * of_clk_del_provider() - Remove a previously registered clock provider
2925 * @np: Device node pointer associated with clock provider 3084 * @np: Device node pointer associated with clock provider
2926 */ 3085 */
@@ -2941,11 +3100,32 @@ void of_clk_del_provider(struct device_node *np)
2941} 3100}
2942EXPORT_SYMBOL_GPL(of_clk_del_provider); 3101EXPORT_SYMBOL_GPL(of_clk_del_provider);
2943 3102
3103static struct clk_hw *
3104__of_clk_get_hw_from_provider(struct of_clk_provider *provider,
3105 struct of_phandle_args *clkspec)
3106{
3107 struct clk *clk;
3108 struct clk_hw *hw = ERR_PTR(-EPROBE_DEFER);
3109
3110 if (provider->get_hw) {
3111 hw = provider->get_hw(clkspec, provider->data);
3112 } else if (provider->get) {
3113 clk = provider->get(clkspec, provider->data);
3114 if (!IS_ERR(clk))
3115 hw = __clk_get_hw(clk);
3116 else
3117 hw = ERR_CAST(clk);
3118 }
3119
3120 return hw;
3121}
3122
2944struct clk *__of_clk_get_from_provider(struct of_phandle_args *clkspec, 3123struct clk *__of_clk_get_from_provider(struct of_phandle_args *clkspec,
2945 const char *dev_id, const char *con_id) 3124 const char *dev_id, const char *con_id)
2946{ 3125{
2947 struct of_clk_provider *provider; 3126 struct of_clk_provider *provider;
2948 struct clk *clk = ERR_PTR(-EPROBE_DEFER); 3127 struct clk *clk = ERR_PTR(-EPROBE_DEFER);
3128 struct clk_hw *hw = ERR_PTR(-EPROBE_DEFER);
2949 3129
2950 if (!clkspec) 3130 if (!clkspec)
2951 return ERR_PTR(-EINVAL); 3131 return ERR_PTR(-EINVAL);
@@ -2954,10 +3134,9 @@ struct clk *__of_clk_get_from_provider(struct of_phandle_args *clkspec,
2954 mutex_lock(&of_clk_mutex); 3134 mutex_lock(&of_clk_mutex);
2955 list_for_each_entry(provider, &of_clk_providers, link) { 3135 list_for_each_entry(provider, &of_clk_providers, link) {
2956 if (provider->node == clkspec->np) 3136 if (provider->node == clkspec->np)
2957 clk = provider->get(clkspec, provider->data); 3137 hw = __of_clk_get_hw_from_provider(provider, clkspec);
2958 if (!IS_ERR(clk)) { 3138 if (!IS_ERR(hw)) {
2959 clk = __clk_create_clk(__clk_get_hw(clk), dev_id, 3139 clk = __clk_create_clk(hw, dev_id, con_id);
2960 con_id);
2961 3140
2962 if (!IS_ERR(clk) && !__clk_get(clk)) { 3141 if (!IS_ERR(clk) && !__clk_get(clk)) {
2963 __clk_free_clk(clk); 3142 __clk_free_clk(clk);
@@ -3127,6 +3306,41 @@ static int parent_ready(struct device_node *np)
3127} 3306}
3128 3307
3129/** 3308/**
3309 * of_clk_detect_critical() - set CLK_IS_CRITICAL flag from Device Tree
3310 * @np: Device node pointer associated with clock provider
3311 * @index: clock index
3312 * @flags: pointer to clk_core->flags
3313 *
3314 * Detects if the clock-critical property exists and, if so, sets the
3315 * corresponding CLK_IS_CRITICAL flag.
3316 *
3317 * Do not use this function. It exists only for legacy Device Tree
3318 * bindings, such as the one-clock-per-node style that are outdated.
3319 * Those bindings typically put all clock data into .dts and the Linux
3320 * driver has no clock data, thus making it impossible to set this flag
3321 * correctly from the driver. Only those drivers may call
3322 * of_clk_detect_critical from their setup functions.
3323 *
3324 * Return: error code or zero on success
3325 */
3326int of_clk_detect_critical(struct device_node *np,
3327 int index, unsigned long *flags)
3328{
3329 struct property *prop;
3330 const __be32 *cur;
3331 uint32_t idx;
3332
3333 if (!np || !flags)
3334 return -EINVAL;
3335
3336 of_property_for_each_u32(np, "clock-critical", prop, cur, idx)
3337 if (index == idx)
3338 *flags |= CLK_IS_CRITICAL;
3339
3340 return 0;
3341}
3342
3343/**
3130 * of_clk_init() - Scan and init clock providers from the DT 3344 * of_clk_init() - Scan and init clock providers from the DT
3131 * @matches: array of compatible values and init functions for providers. 3345 * @matches: array of compatible values and init functions for providers.
3132 * 3346 *