diff options
author | Alex Elder <elder@linaro.org> | 2014-04-21 17:11:40 -0400 |
---|---|---|
committer | Mike Turquette <mturquette@linaro.org> | 2014-04-30 14:51:33 -0400 |
commit | b12151ca5cd76e5ed9c75ef02b2f5d2aa5b45808 (patch) | |
tree | 9d652df3ddbffed17b6a7f9145534de7f727b56e /drivers/clk/bcm/clk-kona-setup.c | |
parent | 9d3d87c750f30af0e8e268c122ffec4489bc9638 (diff) |
clk: bcm281xx: initialize CCU structures statically
We know up front how many CCU's we'll support, so there's no need to
allocate their data structures dynamically. Define a macro
KONA_CCU_COMMON() to simplify the initialization of many of the
fields in a ccu_data structure. Pass the address of a statically
defined CCU structure to kona_dt_ccu_setup() rather than having that
function allocate one.
We also know at build time how many clocks a given CCU will provide,
though the number of of them for each CCU is different. Record the
number of clocks we need in the CCU's clk_onecell_data struct
(which is used when we register the CCU with the common clock code
as a clock provider). Rename that struct field "clk_data" (because
"data" alone gets a little confusing).
Use the known clock count to move the allocation of each CCU's
clocks array into ccu_clks_setup() rather than having each CCU's
setup callback function do it.
(The real motivation behind all of this is that we'll be doing some
static initialization of some additional CCU-specific data soon.)
Signed-off-by: Alex Elder <elder@linaro.org>
Signed-off-by: Mike Turquette <mturquette@linaro.org>
Diffstat (limited to 'drivers/clk/bcm/clk-kona-setup.c')
-rw-r--r-- | drivers/clk/bcm/clk-kona-setup.c | 47 |
1 files changed, 21 insertions, 26 deletions
diff --git a/drivers/clk/bcm/clk-kona-setup.c b/drivers/clk/bcm/clk-kona-setup.c index 9e7a9c11c951..4d1ca5372eff 100644 --- a/drivers/clk/bcm/clk-kona-setup.c +++ b/drivers/clk/bcm/clk-kona-setup.c | |||
@@ -675,50 +675,49 @@ static void ccu_clks_teardown(struct ccu_data *ccu) | |||
675 | { | 675 | { |
676 | u32 i; | 676 | u32 i; |
677 | 677 | ||
678 | for (i = 0; i < ccu->data.clk_num; i++) | 678 | for (i = 0; i < ccu->clk_data.clk_num; i++) |
679 | kona_clk_teardown(ccu->data.clks[i]); | 679 | kona_clk_teardown(ccu->clk_data.clks[i]); |
680 | kfree(ccu->data.clks); | 680 | kfree(ccu->clk_data.clks); |
681 | } | 681 | } |
682 | 682 | ||
683 | static void kona_ccu_teardown(struct ccu_data *ccu) | 683 | static void kona_ccu_teardown(struct ccu_data *ccu) |
684 | { | 684 | { |
685 | if (!ccu) | 685 | kfree(ccu->clk_data.clks); |
686 | return; | 686 | ccu->clk_data.clks = NULL; |
687 | |||
688 | if (!ccu->base) | 687 | if (!ccu->base) |
689 | goto done; | 688 | return; |
690 | 689 | ||
691 | of_clk_del_provider(ccu->node); /* safe if never added */ | 690 | of_clk_del_provider(ccu->node); /* safe if never added */ |
692 | ccu_clks_teardown(ccu); | 691 | ccu_clks_teardown(ccu); |
693 | list_del(&ccu->links); | 692 | list_del(&ccu->links); |
694 | of_node_put(ccu->node); | 693 | of_node_put(ccu->node); |
694 | ccu->node = NULL; | ||
695 | iounmap(ccu->base); | 695 | iounmap(ccu->base); |
696 | done: | 696 | ccu->base = NULL; |
697 | kfree(ccu->name); | ||
698 | kfree(ccu); | ||
699 | } | 697 | } |
700 | 698 | ||
701 | /* | 699 | /* |
702 | * Set up a CCU. Call the provided ccu_clks_setup callback to | 700 | * Set up a CCU. Call the provided ccu_clks_setup callback to |
703 | * initialize the array of clocks provided by the CCU. | 701 | * initialize the array of clocks provided by the CCU. |
704 | */ | 702 | */ |
705 | void __init kona_dt_ccu_setup(struct device_node *node, | 703 | void __init kona_dt_ccu_setup(struct ccu_data *ccu, |
704 | struct device_node *node, | ||
706 | int (*ccu_clks_setup)(struct ccu_data *)) | 705 | int (*ccu_clks_setup)(struct ccu_data *)) |
707 | { | 706 | { |
708 | struct ccu_data *ccu; | ||
709 | struct resource res = { 0 }; | 707 | struct resource res = { 0 }; |
710 | resource_size_t range; | 708 | resource_size_t range; |
711 | int ret; | 709 | int ret; |
712 | 710 | ||
713 | ccu = kzalloc(sizeof(*ccu), GFP_KERNEL); | 711 | if (ccu->clk_data.clk_num) { |
714 | if (ccu) | 712 | size_t size; |
715 | ccu->name = kstrdup(node->name, GFP_KERNEL); | ||
716 | if (!ccu || !ccu->name) { | ||
717 | pr_err("%s: unable to allocate CCU struct for %s\n", | ||
718 | __func__, node->name); | ||
719 | kfree(ccu); | ||
720 | 713 | ||
721 | return; | 714 | size = ccu->clk_data.clk_num * sizeof(*ccu->clk_data.clks); |
715 | ccu->clk_data.clks = kzalloc(size, GFP_KERNEL); | ||
716 | if (!ccu->clk_data.clks) { | ||
717 | pr_err("%s: unable to allocate %u clocks for %s\n", | ||
718 | __func__, ccu->clk_data.clk_num, node->name); | ||
719 | return; | ||
720 | } | ||
722 | } | 721 | } |
723 | 722 | ||
724 | ret = of_address_to_resource(node, 0, &res); | 723 | ret = of_address_to_resource(node, 0, &res); |
@@ -742,18 +741,14 @@ void __init kona_dt_ccu_setup(struct device_node *node, | |||
742 | node->name); | 741 | node->name); |
743 | goto out_err; | 742 | goto out_err; |
744 | } | 743 | } |
745 | |||
746 | spin_lock_init(&ccu->lock); | ||
747 | INIT_LIST_HEAD(&ccu->links); | ||
748 | ccu->node = of_node_get(node); | 744 | ccu->node = of_node_get(node); |
749 | |||
750 | list_add_tail(&ccu->links, &ccu_list); | 745 | list_add_tail(&ccu->links, &ccu_list); |
751 | 746 | ||
752 | /* Set up clocks array (in ccu->data) */ | 747 | /* Set up clocks array (in ccu->clk_data) */ |
753 | if (ccu_clks_setup(ccu)) | 748 | if (ccu_clks_setup(ccu)) |
754 | goto out_err; | 749 | goto out_err; |
755 | 750 | ||
756 | ret = of_clk_add_provider(node, of_clk_src_onecell_get, &ccu->data); | 751 | ret = of_clk_add_provider(node, of_clk_src_onecell_get, &ccu->clk_data); |
757 | if (ret) { | 752 | if (ret) { |
758 | pr_err("%s: error adding ccu %s as provider (%d)\n", __func__, | 753 | pr_err("%s: error adding ccu %s as provider (%d)\n", __func__, |
759 | node->name, ret); | 754 | node->name, ret); |