diff options
author | Stephen Boyd <sboyd@codeaurora.org> | 2014-03-21 20:59:37 -0400 |
---|---|---|
committer | Mike Turquette <mturquette@linaro.org> | 2014-04-30 14:51:51 -0400 |
commit | 49fc825f0cc221768c5711b8ec6a71bd49f2663e (patch) | |
tree | 4c358a9db39a28e9ba79d77a021a13a59637eefb /drivers/clk/qcom | |
parent | 63589e92c2d975cc63222e5bd4a9a1fa2a1187ac (diff) |
clk: qcom: Consolidate common probe code
Most of the probe code is the same between all the different
clock controllers. Consolidate the code into a common.c file.
This makes changes to the common probe parts easier and reduces
chances for bugs.
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Mike Turquette <mturquette@linaro.org>
Diffstat (limited to 'drivers/clk/qcom')
-rw-r--r-- | drivers/clk/qcom/Makefile | 1 | ||||
-rw-r--r-- | drivers/clk/qcom/common.c | 99 | ||||
-rw-r--r-- | drivers/clk/qcom/common.h | 34 | ||||
-rw-r--r-- | drivers/clk/qcom/gcc-msm8660.c | 87 | ||||
-rw-r--r-- | drivers/clk/qcom/gcc-msm8960.c | 77 | ||||
-rw-r--r-- | drivers/clk/qcom/gcc-msm8974.c | 77 | ||||
-rw-r--r-- | drivers/clk/qcom/mmcc-msm8960.c | 78 | ||||
-rw-r--r-- | drivers/clk/qcom/mmcc-msm8974.c | 80 |
8 files changed, 196 insertions, 337 deletions
diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index f60db2ef1aee..689e05bf4f95 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile | |||
@@ -1,5 +1,6 @@ | |||
1 | obj-$(CONFIG_COMMON_CLK_QCOM) += clk-qcom.o | 1 | obj-$(CONFIG_COMMON_CLK_QCOM) += clk-qcom.o |
2 | 2 | ||
3 | clk-qcom-y += common.o | ||
3 | clk-qcom-y += clk-regmap.o | 4 | clk-qcom-y += clk-regmap.o |
4 | clk-qcom-y += clk-pll.o | 5 | clk-qcom-y += clk-pll.o |
5 | clk-qcom-y += clk-rcg.o | 6 | clk-qcom-y += clk-rcg.o |
diff --git a/drivers/clk/qcom/common.c b/drivers/clk/qcom/common.c new file mode 100644 index 000000000000..86b45fba5f90 --- /dev/null +++ b/drivers/clk/qcom/common.c | |||
@@ -0,0 +1,99 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. | ||
3 | * | ||
4 | * This software is licensed under the terms of the GNU General Public | ||
5 | * License version 2, as published by the Free Software Foundation, and | ||
6 | * may be copied, distributed, and modified under those terms. | ||
7 | * | ||
8 | * This program is distributed in the hope that it will be useful, | ||
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
11 | * GNU General Public License for more details. | ||
12 | */ | ||
13 | |||
14 | #include <linux/export.h> | ||
15 | #include <linux/regmap.h> | ||
16 | #include <linux/platform_device.h> | ||
17 | #include <linux/clk-provider.h> | ||
18 | #include <linux/reset-controller.h> | ||
19 | |||
20 | #include "common.h" | ||
21 | #include "clk-regmap.h" | ||
22 | #include "reset.h" | ||
23 | |||
24 | struct qcom_cc { | ||
25 | struct qcom_reset_controller reset; | ||
26 | struct clk_onecell_data data; | ||
27 | struct clk *clks[]; | ||
28 | }; | ||
29 | |||
30 | int qcom_cc_probe(struct platform_device *pdev, const struct qcom_cc_desc *desc) | ||
31 | { | ||
32 | void __iomem *base; | ||
33 | struct resource *res; | ||
34 | int i, ret; | ||
35 | struct device *dev = &pdev->dev; | ||
36 | struct clk *clk; | ||
37 | struct clk_onecell_data *data; | ||
38 | struct clk **clks; | ||
39 | struct regmap *regmap; | ||
40 | struct qcom_reset_controller *reset; | ||
41 | struct qcom_cc *cc; | ||
42 | size_t num_clks = desc->num_clks; | ||
43 | struct clk_regmap **rclks = desc->clks; | ||
44 | |||
45 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
46 | base = devm_ioremap_resource(dev, res); | ||
47 | if (IS_ERR(base)) | ||
48 | return PTR_ERR(base); | ||
49 | |||
50 | regmap = devm_regmap_init_mmio(dev, base, desc->config); | ||
51 | if (IS_ERR(regmap)) | ||
52 | return PTR_ERR(regmap); | ||
53 | |||
54 | cc = devm_kzalloc(dev, sizeof(*cc) + sizeof(*clks) * num_clks, | ||
55 | GFP_KERNEL); | ||
56 | if (!cc) | ||
57 | return -ENOMEM; | ||
58 | |||
59 | clks = cc->clks; | ||
60 | data = &cc->data; | ||
61 | data->clks = clks; | ||
62 | data->clk_num = num_clks; | ||
63 | |||
64 | for (i = 0; i < num_clks; i++) { | ||
65 | if (!rclks[i]) | ||
66 | continue; | ||
67 | clk = devm_clk_register_regmap(dev, rclks[i]); | ||
68 | if (IS_ERR(clk)) | ||
69 | return PTR_ERR(clk); | ||
70 | clks[i] = clk; | ||
71 | } | ||
72 | |||
73 | ret = of_clk_add_provider(dev->of_node, of_clk_src_onecell_get, data); | ||
74 | if (ret) | ||
75 | return ret; | ||
76 | |||
77 | reset = &cc->reset; | ||
78 | reset->rcdev.of_node = dev->of_node; | ||
79 | reset->rcdev.ops = &qcom_reset_ops; | ||
80 | reset->rcdev.owner = dev->driver->owner; | ||
81 | reset->rcdev.nr_resets = desc->num_resets; | ||
82 | reset->regmap = regmap; | ||
83 | reset->reset_map = desc->resets; | ||
84 | platform_set_drvdata(pdev, &reset->rcdev); | ||
85 | |||
86 | ret = reset_controller_register(&reset->rcdev); | ||
87 | if (ret) | ||
88 | of_clk_del_provider(dev->of_node); | ||
89 | |||
90 | return ret; | ||
91 | } | ||
92 | EXPORT_SYMBOL_GPL(qcom_cc_probe); | ||
93 | |||
94 | void qcom_cc_remove(struct platform_device *pdev) | ||
95 | { | ||
96 | of_clk_del_provider(pdev->dev.of_node); | ||
97 | reset_controller_unregister(platform_get_drvdata(pdev)); | ||
98 | } | ||
99 | EXPORT_SYMBOL_GPL(qcom_cc_remove); | ||
diff --git a/drivers/clk/qcom/common.h b/drivers/clk/qcom/common.h new file mode 100644 index 000000000000..2c3cfc860348 --- /dev/null +++ b/drivers/clk/qcom/common.h | |||
@@ -0,0 +1,34 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2014, The Linux Foundation. All rights reserved. | ||
3 | * | ||
4 | * This software is licensed under the terms of the GNU General Public | ||
5 | * License version 2, as published by the Free Software Foundation, and | ||
6 | * may be copied, distributed, and modified under those terms. | ||
7 | * | ||
8 | * This program is distributed in the hope that it will be useful, | ||
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
11 | * GNU General Public License for more details. | ||
12 | */ | ||
13 | #ifndef __QCOM_CLK_COMMON_H__ | ||
14 | #define __QCOM_CLK_COMMON_H__ | ||
15 | |||
16 | struct platform_device; | ||
17 | struct regmap_config; | ||
18 | struct clk_regmap; | ||
19 | struct qcom_reset_map; | ||
20 | |||
21 | struct qcom_cc_desc { | ||
22 | const struct regmap_config *config; | ||
23 | struct clk_regmap **clks; | ||
24 | size_t num_clks; | ||
25 | const struct qcom_reset_map *resets; | ||
26 | size_t num_resets; | ||
27 | }; | ||
28 | |||
29 | extern int qcom_cc_probe(struct platform_device *pdev, | ||
30 | const struct qcom_cc_desc *desc); | ||
31 | |||
32 | extern void qcom_cc_remove(struct platform_device *pdev); | ||
33 | |||
34 | #endif | ||
diff --git a/drivers/clk/qcom/gcc-msm8660.c b/drivers/clk/qcom/gcc-msm8660.c index bc0b7f1fcfbe..44bc6fa64d78 100644 --- a/drivers/clk/qcom/gcc-msm8660.c +++ b/drivers/clk/qcom/gcc-msm8660.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <dt-bindings/clock/qcom,gcc-msm8660.h> | 25 | #include <dt-bindings/clock/qcom,gcc-msm8660.h> |
26 | #include <dt-bindings/reset/qcom,gcc-msm8660.h> | 26 | #include <dt-bindings/reset/qcom,gcc-msm8660.h> |
27 | 27 | ||
28 | #include "common.h" | ||
28 | #include "clk-regmap.h" | 29 | #include "clk-regmap.h" |
29 | #include "clk-pll.h" | 30 | #include "clk-pll.h" |
30 | #include "clk-rcg.h" | 31 | #include "clk-rcg.h" |
@@ -2701,94 +2702,28 @@ static const struct regmap_config gcc_msm8660_regmap_config = { | |||
2701 | .fast_io = true, | 2702 | .fast_io = true, |
2702 | }; | 2703 | }; |
2703 | 2704 | ||
2705 | static const struct qcom_cc_desc gcc_msm8660_desc = { | ||
2706 | .config = &gcc_msm8660_regmap_config, | ||
2707 | .clks = gcc_msm8660_clks, | ||
2708 | .num_clks = ARRAY_SIZE(gcc_msm8660_clks), | ||
2709 | .resets = gcc_msm8660_resets, | ||
2710 | .num_resets = ARRAY_SIZE(gcc_msm8660_resets), | ||
2711 | }; | ||
2712 | |||
2704 | static const struct of_device_id gcc_msm8660_match_table[] = { | 2713 | static const struct of_device_id gcc_msm8660_match_table[] = { |
2705 | { .compatible = "qcom,gcc-msm8660" }, | 2714 | { .compatible = "qcom,gcc-msm8660" }, |
2706 | { } | 2715 | { } |
2707 | }; | 2716 | }; |
2708 | MODULE_DEVICE_TABLE(of, gcc_msm8660_match_table); | 2717 | MODULE_DEVICE_TABLE(of, gcc_msm8660_match_table); |
2709 | 2718 | ||
2710 | struct qcom_cc { | ||
2711 | struct qcom_reset_controller reset; | ||
2712 | struct clk_onecell_data data; | ||
2713 | struct clk *clks[]; | ||
2714 | }; | ||
2715 | |||
2716 | static int gcc_msm8660_probe(struct platform_device *pdev) | 2719 | static int gcc_msm8660_probe(struct platform_device *pdev) |
2717 | { | 2720 | { |
2718 | void __iomem *base; | 2721 | return qcom_cc_probe(pdev, &gcc_msm8660_desc); |
2719 | struct resource *res; | ||
2720 | int i, ret; | ||
2721 | struct device *dev = &pdev->dev; | ||
2722 | struct clk *clk; | ||
2723 | struct clk_onecell_data *data; | ||
2724 | struct clk **clks; | ||
2725 | struct regmap *regmap; | ||
2726 | size_t num_clks; | ||
2727 | struct qcom_reset_controller *reset; | ||
2728 | struct qcom_cc *cc; | ||
2729 | |||
2730 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
2731 | base = devm_ioremap_resource(dev, res); | ||
2732 | if (IS_ERR(base)) | ||
2733 | return PTR_ERR(base); | ||
2734 | |||
2735 | regmap = devm_regmap_init_mmio(dev, base, &gcc_msm8660_regmap_config); | ||
2736 | if (IS_ERR(regmap)) | ||
2737 | return PTR_ERR(regmap); | ||
2738 | |||
2739 | num_clks = ARRAY_SIZE(gcc_msm8660_clks); | ||
2740 | cc = devm_kzalloc(dev, sizeof(*cc) + sizeof(*clks) * num_clks, | ||
2741 | GFP_KERNEL); | ||
2742 | if (!cc) | ||
2743 | return -ENOMEM; | ||
2744 | |||
2745 | clks = cc->clks; | ||
2746 | data = &cc->data; | ||
2747 | data->clks = clks; | ||
2748 | data->clk_num = num_clks; | ||
2749 | |||
2750 | /* Temporary until RPM clocks supported */ | ||
2751 | clk = clk_register_fixed_rate(dev, "cxo", NULL, CLK_IS_ROOT, 19200000); | ||
2752 | if (IS_ERR(clk)) | ||
2753 | return PTR_ERR(clk); | ||
2754 | |||
2755 | clk = clk_register_fixed_rate(dev, "pxo", NULL, CLK_IS_ROOT, 27000000); | ||
2756 | if (IS_ERR(clk)) | ||
2757 | return PTR_ERR(clk); | ||
2758 | |||
2759 | for (i = 0; i < num_clks; i++) { | ||
2760 | if (!gcc_msm8660_clks[i]) | ||
2761 | continue; | ||
2762 | clk = devm_clk_register_regmap(dev, gcc_msm8660_clks[i]); | ||
2763 | if (IS_ERR(clk)) | ||
2764 | return PTR_ERR(clk); | ||
2765 | clks[i] = clk; | ||
2766 | } | ||
2767 | |||
2768 | ret = of_clk_add_provider(dev->of_node, of_clk_src_onecell_get, data); | ||
2769 | if (ret) | ||
2770 | return ret; | ||
2771 | |||
2772 | reset = &cc->reset; | ||
2773 | reset->rcdev.of_node = dev->of_node; | ||
2774 | reset->rcdev.ops = &qcom_reset_ops, | ||
2775 | reset->rcdev.owner = THIS_MODULE, | ||
2776 | reset->rcdev.nr_resets = ARRAY_SIZE(gcc_msm8660_resets), | ||
2777 | reset->regmap = regmap; | ||
2778 | reset->reset_map = gcc_msm8660_resets, | ||
2779 | platform_set_drvdata(pdev, &reset->rcdev); | ||
2780 | |||
2781 | ret = reset_controller_register(&reset->rcdev); | ||
2782 | if (ret) | ||
2783 | of_clk_del_provider(dev->of_node); | ||
2784 | |||
2785 | return ret; | ||
2786 | } | 2722 | } |
2787 | 2723 | ||
2788 | static int gcc_msm8660_remove(struct platform_device *pdev) | 2724 | static int gcc_msm8660_remove(struct platform_device *pdev) |
2789 | { | 2725 | { |
2790 | of_clk_del_provider(pdev->dev.of_node); | 2726 | qcom_cc_remove(pdev); |
2791 | reset_controller_unregister(platform_get_drvdata(pdev)); | ||
2792 | return 0; | 2727 | return 0; |
2793 | } | 2728 | } |
2794 | 2729 | ||
diff --git a/drivers/clk/qcom/gcc-msm8960.c b/drivers/clk/qcom/gcc-msm8960.c index fd446ab2fd98..633b019891bb 100644 --- a/drivers/clk/qcom/gcc-msm8960.c +++ b/drivers/clk/qcom/gcc-msm8960.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <dt-bindings/clock/qcom,gcc-msm8960.h> | 25 | #include <dt-bindings/clock/qcom,gcc-msm8960.h> |
26 | #include <dt-bindings/reset/qcom,gcc-msm8960.h> | 26 | #include <dt-bindings/reset/qcom,gcc-msm8960.h> |
27 | 27 | ||
28 | #include "common.h" | ||
28 | #include "clk-regmap.h" | 29 | #include "clk-regmap.h" |
29 | #include "clk-pll.h" | 30 | #include "clk-pll.h" |
30 | #include "clk-rcg.h" | 31 | #include "clk-rcg.h" |
@@ -2875,51 +2876,24 @@ static const struct regmap_config gcc_msm8960_regmap_config = { | |||
2875 | .fast_io = true, | 2876 | .fast_io = true, |
2876 | }; | 2877 | }; |
2877 | 2878 | ||
2879 | static const struct qcom_cc_desc gcc_msm8960_desc = { | ||
2880 | .config = &gcc_msm8960_regmap_config, | ||
2881 | .clks = gcc_msm8960_clks, | ||
2882 | .num_clks = ARRAY_SIZE(gcc_msm8960_clks), | ||
2883 | .resets = gcc_msm8960_resets, | ||
2884 | .num_resets = ARRAY_SIZE(gcc_msm8960_resets), | ||
2885 | }; | ||
2886 | |||
2878 | static const struct of_device_id gcc_msm8960_match_table[] = { | 2887 | static const struct of_device_id gcc_msm8960_match_table[] = { |
2879 | { .compatible = "qcom,gcc-msm8960" }, | 2888 | { .compatible = "qcom,gcc-msm8960" }, |
2880 | { } | 2889 | { } |
2881 | }; | 2890 | }; |
2882 | MODULE_DEVICE_TABLE(of, gcc_msm8960_match_table); | 2891 | MODULE_DEVICE_TABLE(of, gcc_msm8960_match_table); |
2883 | 2892 | ||
2884 | struct qcom_cc { | ||
2885 | struct qcom_reset_controller reset; | ||
2886 | struct clk_onecell_data data; | ||
2887 | struct clk *clks[]; | ||
2888 | }; | ||
2889 | |||
2890 | static int gcc_msm8960_probe(struct platform_device *pdev) | 2893 | static int gcc_msm8960_probe(struct platform_device *pdev) |
2891 | { | 2894 | { |
2892 | void __iomem *base; | ||
2893 | struct resource *res; | ||
2894 | int i, ret; | ||
2895 | struct device *dev = &pdev->dev; | ||
2896 | struct clk *clk; | 2895 | struct clk *clk; |
2897 | struct clk_onecell_data *data; | 2896 | struct device *dev = &pdev->dev; |
2898 | struct clk **clks; | ||
2899 | struct regmap *regmap; | ||
2900 | size_t num_clks; | ||
2901 | struct qcom_reset_controller *reset; | ||
2902 | struct qcom_cc *cc; | ||
2903 | |||
2904 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
2905 | base = devm_ioremap_resource(dev, res); | ||
2906 | if (IS_ERR(base)) | ||
2907 | return PTR_ERR(base); | ||
2908 | |||
2909 | regmap = devm_regmap_init_mmio(dev, base, &gcc_msm8960_regmap_config); | ||
2910 | if (IS_ERR(regmap)) | ||
2911 | return PTR_ERR(regmap); | ||
2912 | |||
2913 | num_clks = ARRAY_SIZE(gcc_msm8960_clks); | ||
2914 | cc = devm_kzalloc(dev, sizeof(*cc) + sizeof(*clks) * num_clks, | ||
2915 | GFP_KERNEL); | ||
2916 | if (!cc) | ||
2917 | return -ENOMEM; | ||
2918 | |||
2919 | clks = cc->clks; | ||
2920 | data = &cc->data; | ||
2921 | data->clks = clks; | ||
2922 | data->clk_num = num_clks; | ||
2923 | 2897 | ||
2924 | /* Temporary until RPM clocks supported */ | 2898 | /* Temporary until RPM clocks supported */ |
2925 | clk = clk_register_fixed_rate(dev, "cxo", NULL, CLK_IS_ROOT, 19200000); | 2899 | clk = clk_register_fixed_rate(dev, "cxo", NULL, CLK_IS_ROOT, 19200000); |
@@ -2930,39 +2904,12 @@ static int gcc_msm8960_probe(struct platform_device *pdev) | |||
2930 | if (IS_ERR(clk)) | 2904 | if (IS_ERR(clk)) |
2931 | return PTR_ERR(clk); | 2905 | return PTR_ERR(clk); |
2932 | 2906 | ||
2933 | for (i = 0; i < num_clks; i++) { | 2907 | return qcom_cc_probe(pdev, &gcc_msm8960_desc); |
2934 | if (!gcc_msm8960_clks[i]) | ||
2935 | continue; | ||
2936 | clk = devm_clk_register_regmap(dev, gcc_msm8960_clks[i]); | ||
2937 | if (IS_ERR(clk)) | ||
2938 | return PTR_ERR(clk); | ||
2939 | clks[i] = clk; | ||
2940 | } | ||
2941 | |||
2942 | ret = of_clk_add_provider(dev->of_node, of_clk_src_onecell_get, data); | ||
2943 | if (ret) | ||
2944 | return ret; | ||
2945 | |||
2946 | reset = &cc->reset; | ||
2947 | reset->rcdev.of_node = dev->of_node; | ||
2948 | reset->rcdev.ops = &qcom_reset_ops, | ||
2949 | reset->rcdev.owner = THIS_MODULE, | ||
2950 | reset->rcdev.nr_resets = ARRAY_SIZE(gcc_msm8960_resets), | ||
2951 | reset->regmap = regmap; | ||
2952 | reset->reset_map = gcc_msm8960_resets, | ||
2953 | platform_set_drvdata(pdev, &reset->rcdev); | ||
2954 | |||
2955 | ret = reset_controller_register(&reset->rcdev); | ||
2956 | if (ret) | ||
2957 | of_clk_del_provider(dev->of_node); | ||
2958 | |||
2959 | return ret; | ||
2960 | } | 2908 | } |
2961 | 2909 | ||
2962 | static int gcc_msm8960_remove(struct platform_device *pdev) | 2910 | static int gcc_msm8960_remove(struct platform_device *pdev) |
2963 | { | 2911 | { |
2964 | of_clk_del_provider(pdev->dev.of_node); | 2912 | qcom_cc_remove(pdev); |
2965 | reset_controller_unregister(platform_get_drvdata(pdev)); | ||
2966 | return 0; | 2913 | return 0; |
2967 | } | 2914 | } |
2968 | 2915 | ||
diff --git a/drivers/clk/qcom/gcc-msm8974.c b/drivers/clk/qcom/gcc-msm8974.c index 51d457e2b959..0d1edc1e9b31 100644 --- a/drivers/clk/qcom/gcc-msm8974.c +++ b/drivers/clk/qcom/gcc-msm8974.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <dt-bindings/clock/qcom,gcc-msm8974.h> | 25 | #include <dt-bindings/clock/qcom,gcc-msm8974.h> |
26 | #include <dt-bindings/reset/qcom,gcc-msm8974.h> | 26 | #include <dt-bindings/reset/qcom,gcc-msm8974.h> |
27 | 27 | ||
28 | #include "common.h" | ||
28 | #include "clk-regmap.h" | 29 | #include "clk-regmap.h" |
29 | #include "clk-pll.h" | 30 | #include "clk-pll.h" |
30 | #include "clk-rcg.h" | 31 | #include "clk-rcg.h" |
@@ -2574,51 +2575,24 @@ static const struct regmap_config gcc_msm8974_regmap_config = { | |||
2574 | .fast_io = true, | 2575 | .fast_io = true, |
2575 | }; | 2576 | }; |
2576 | 2577 | ||
2578 | static const struct qcom_cc_desc gcc_msm8974_desc = { | ||
2579 | .config = &gcc_msm8974_regmap_config, | ||
2580 | .clks = gcc_msm8974_clocks, | ||
2581 | .num_clks = ARRAY_SIZE(gcc_msm8974_clocks), | ||
2582 | .resets = gcc_msm8974_resets, | ||
2583 | .num_resets = ARRAY_SIZE(gcc_msm8974_resets), | ||
2584 | }; | ||
2585 | |||
2577 | static const struct of_device_id gcc_msm8974_match_table[] = { | 2586 | static const struct of_device_id gcc_msm8974_match_table[] = { |
2578 | { .compatible = "qcom,gcc-msm8974" }, | 2587 | { .compatible = "qcom,gcc-msm8974" }, |
2579 | { } | 2588 | { } |
2580 | }; | 2589 | }; |
2581 | MODULE_DEVICE_TABLE(of, gcc_msm8974_match_table); | 2590 | MODULE_DEVICE_TABLE(of, gcc_msm8974_match_table); |
2582 | 2591 | ||
2583 | struct qcom_cc { | ||
2584 | struct qcom_reset_controller reset; | ||
2585 | struct clk_onecell_data data; | ||
2586 | struct clk *clks[]; | ||
2587 | }; | ||
2588 | |||
2589 | static int gcc_msm8974_probe(struct platform_device *pdev) | 2592 | static int gcc_msm8974_probe(struct platform_device *pdev) |
2590 | { | 2593 | { |
2591 | void __iomem *base; | ||
2592 | struct resource *res; | ||
2593 | int i, ret; | ||
2594 | struct device *dev = &pdev->dev; | ||
2595 | struct clk *clk; | 2594 | struct clk *clk; |
2596 | struct clk_onecell_data *data; | 2595 | struct device *dev = &pdev->dev; |
2597 | struct clk **clks; | ||
2598 | struct regmap *regmap; | ||
2599 | size_t num_clks; | ||
2600 | struct qcom_reset_controller *reset; | ||
2601 | struct qcom_cc *cc; | ||
2602 | |||
2603 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
2604 | base = devm_ioremap_resource(dev, res); | ||
2605 | if (IS_ERR(base)) | ||
2606 | return PTR_ERR(base); | ||
2607 | |||
2608 | regmap = devm_regmap_init_mmio(dev, base, &gcc_msm8974_regmap_config); | ||
2609 | if (IS_ERR(regmap)) | ||
2610 | return PTR_ERR(regmap); | ||
2611 | |||
2612 | num_clks = ARRAY_SIZE(gcc_msm8974_clocks); | ||
2613 | cc = devm_kzalloc(dev, sizeof(*cc) + sizeof(*clks) * num_clks, | ||
2614 | GFP_KERNEL); | ||
2615 | if (!cc) | ||
2616 | return -ENOMEM; | ||
2617 | |||
2618 | clks = cc->clks; | ||
2619 | data = &cc->data; | ||
2620 | data->clks = clks; | ||
2621 | data->clk_num = num_clks; | ||
2622 | 2596 | ||
2623 | /* Temporary until RPM clocks supported */ | 2597 | /* Temporary until RPM clocks supported */ |
2624 | clk = clk_register_fixed_rate(dev, "xo", NULL, CLK_IS_ROOT, 19200000); | 2598 | clk = clk_register_fixed_rate(dev, "xo", NULL, CLK_IS_ROOT, 19200000); |
@@ -2631,39 +2605,12 @@ static int gcc_msm8974_probe(struct platform_device *pdev) | |||
2631 | if (IS_ERR(clk)) | 2605 | if (IS_ERR(clk)) |
2632 | return PTR_ERR(clk); | 2606 | return PTR_ERR(clk); |
2633 | 2607 | ||
2634 | for (i = 0; i < num_clks; i++) { | 2608 | return qcom_cc_probe(pdev, &gcc_msm8974_desc); |
2635 | if (!gcc_msm8974_clocks[i]) | ||
2636 | continue; | ||
2637 | clk = devm_clk_register_regmap(dev, gcc_msm8974_clocks[i]); | ||
2638 | if (IS_ERR(clk)) | ||
2639 | return PTR_ERR(clk); | ||
2640 | clks[i] = clk; | ||
2641 | } | ||
2642 | |||
2643 | ret = of_clk_add_provider(dev->of_node, of_clk_src_onecell_get, data); | ||
2644 | if (ret) | ||
2645 | return ret; | ||
2646 | |||
2647 | reset = &cc->reset; | ||
2648 | reset->rcdev.of_node = dev->of_node; | ||
2649 | reset->rcdev.ops = &qcom_reset_ops, | ||
2650 | reset->rcdev.owner = THIS_MODULE, | ||
2651 | reset->rcdev.nr_resets = ARRAY_SIZE(gcc_msm8974_resets), | ||
2652 | reset->regmap = regmap; | ||
2653 | reset->reset_map = gcc_msm8974_resets, | ||
2654 | platform_set_drvdata(pdev, &reset->rcdev); | ||
2655 | |||
2656 | ret = reset_controller_register(&reset->rcdev); | ||
2657 | if (ret) | ||
2658 | of_clk_del_provider(dev->of_node); | ||
2659 | |||
2660 | return ret; | ||
2661 | } | 2609 | } |
2662 | 2610 | ||
2663 | static int gcc_msm8974_remove(struct platform_device *pdev) | 2611 | static int gcc_msm8974_remove(struct platform_device *pdev) |
2664 | { | 2612 | { |
2665 | of_clk_del_provider(pdev->dev.of_node); | 2613 | qcom_cc_remove(pdev); |
2666 | reset_controller_unregister(platform_get_drvdata(pdev)); | ||
2667 | return 0; | 2614 | return 0; |
2668 | } | 2615 | } |
2669 | 2616 | ||
diff --git a/drivers/clk/qcom/mmcc-msm8960.c b/drivers/clk/qcom/mmcc-msm8960.c index f9b59c7e48e9..12f3c0b64fcd 100644 --- a/drivers/clk/qcom/mmcc-msm8960.c +++ b/drivers/clk/qcom/mmcc-msm8960.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <dt-bindings/clock/qcom,mmcc-msm8960.h> | 26 | #include <dt-bindings/clock/qcom,mmcc-msm8960.h> |
27 | #include <dt-bindings/reset/qcom,mmcc-msm8960.h> | 27 | #include <dt-bindings/reset/qcom,mmcc-msm8960.h> |
28 | 28 | ||
29 | #include "common.h" | ||
29 | #include "clk-regmap.h" | 30 | #include "clk-regmap.h" |
30 | #include "clk-pll.h" | 31 | #include "clk-pll.h" |
31 | #include "clk-rcg.h" | 32 | #include "clk-rcg.h" |
@@ -2222,85 +2223,28 @@ static const struct regmap_config mmcc_msm8960_regmap_config = { | |||
2222 | .fast_io = true, | 2223 | .fast_io = true, |
2223 | }; | 2224 | }; |
2224 | 2225 | ||
2226 | static const struct qcom_cc_desc mmcc_msm8960_desc = { | ||
2227 | .config = &mmcc_msm8960_regmap_config, | ||
2228 | .clks = mmcc_msm8960_clks, | ||
2229 | .num_clks = ARRAY_SIZE(mmcc_msm8960_clks), | ||
2230 | .resets = mmcc_msm8960_resets, | ||
2231 | .num_resets = ARRAY_SIZE(mmcc_msm8960_resets), | ||
2232 | }; | ||
2233 | |||
2225 | static const struct of_device_id mmcc_msm8960_match_table[] = { | 2234 | static const struct of_device_id mmcc_msm8960_match_table[] = { |
2226 | { .compatible = "qcom,mmcc-msm8960" }, | 2235 | { .compatible = "qcom,mmcc-msm8960" }, |
2227 | { } | 2236 | { } |
2228 | }; | 2237 | }; |
2229 | MODULE_DEVICE_TABLE(of, mmcc_msm8960_match_table); | 2238 | MODULE_DEVICE_TABLE(of, mmcc_msm8960_match_table); |
2230 | 2239 | ||
2231 | struct qcom_cc { | ||
2232 | struct qcom_reset_controller reset; | ||
2233 | struct clk_onecell_data data; | ||
2234 | struct clk *clks[]; | ||
2235 | }; | ||
2236 | |||
2237 | static int mmcc_msm8960_probe(struct platform_device *pdev) | 2240 | static int mmcc_msm8960_probe(struct platform_device *pdev) |
2238 | { | 2241 | { |
2239 | void __iomem *base; | 2242 | return qcom_cc_probe(pdev, &mmcc_msm8960_desc); |
2240 | struct resource *res; | ||
2241 | int i, ret; | ||
2242 | struct device *dev = &pdev->dev; | ||
2243 | struct clk *clk; | ||
2244 | struct clk_onecell_data *data; | ||
2245 | struct clk **clks; | ||
2246 | struct regmap *regmap; | ||
2247 | size_t num_clks; | ||
2248 | struct qcom_reset_controller *reset; | ||
2249 | struct qcom_cc *cc; | ||
2250 | |||
2251 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
2252 | base = devm_ioremap_resource(dev, res); | ||
2253 | if (IS_ERR(base)) | ||
2254 | return PTR_ERR(base); | ||
2255 | |||
2256 | regmap = devm_regmap_init_mmio(dev, base, &mmcc_msm8960_regmap_config); | ||
2257 | if (IS_ERR(regmap)) | ||
2258 | return PTR_ERR(regmap); | ||
2259 | |||
2260 | num_clks = ARRAY_SIZE(mmcc_msm8960_clks); | ||
2261 | cc = devm_kzalloc(dev, sizeof(*cc) + sizeof(*clks) * num_clks, | ||
2262 | GFP_KERNEL); | ||
2263 | if (!cc) | ||
2264 | return -ENOMEM; | ||
2265 | |||
2266 | clks = cc->clks; | ||
2267 | data = &cc->data; | ||
2268 | data->clks = clks; | ||
2269 | data->clk_num = num_clks; | ||
2270 | |||
2271 | for (i = 0; i < num_clks; i++) { | ||
2272 | if (!mmcc_msm8960_clks[i]) | ||
2273 | continue; | ||
2274 | clk = devm_clk_register_regmap(dev, mmcc_msm8960_clks[i]); | ||
2275 | if (IS_ERR(clk)) | ||
2276 | return PTR_ERR(clk); | ||
2277 | clks[i] = clk; | ||
2278 | } | ||
2279 | |||
2280 | ret = of_clk_add_provider(dev->of_node, of_clk_src_onecell_get, data); | ||
2281 | if (ret) | ||
2282 | return ret; | ||
2283 | |||
2284 | reset = &cc->reset; | ||
2285 | reset->rcdev.of_node = dev->of_node; | ||
2286 | reset->rcdev.ops = &qcom_reset_ops, | ||
2287 | reset->rcdev.owner = THIS_MODULE, | ||
2288 | reset->rcdev.nr_resets = ARRAY_SIZE(mmcc_msm8960_resets), | ||
2289 | reset->regmap = regmap; | ||
2290 | reset->reset_map = mmcc_msm8960_resets, | ||
2291 | platform_set_drvdata(pdev, &reset->rcdev); | ||
2292 | |||
2293 | ret = reset_controller_register(&reset->rcdev); | ||
2294 | if (ret) | ||
2295 | of_clk_del_provider(dev->of_node); | ||
2296 | |||
2297 | return ret; | ||
2298 | } | 2243 | } |
2299 | 2244 | ||
2300 | static int mmcc_msm8960_remove(struct platform_device *pdev) | 2245 | static int mmcc_msm8960_remove(struct platform_device *pdev) |
2301 | { | 2246 | { |
2302 | of_clk_del_provider(pdev->dev.of_node); | 2247 | qcom_cc_remove(pdev); |
2303 | reset_controller_unregister(platform_get_drvdata(pdev)); | ||
2304 | return 0; | 2248 | return 0; |
2305 | } | 2249 | } |
2306 | 2250 | ||
diff --git a/drivers/clk/qcom/mmcc-msm8974.c b/drivers/clk/qcom/mmcc-msm8974.c index c95774514b81..60b7c24a5cd6 100644 --- a/drivers/clk/qcom/mmcc-msm8974.c +++ b/drivers/clk/qcom/mmcc-msm8974.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <dt-bindings/clock/qcom,mmcc-msm8974.h> | 25 | #include <dt-bindings/clock/qcom,mmcc-msm8974.h> |
26 | #include <dt-bindings/reset/qcom,mmcc-msm8974.h> | 26 | #include <dt-bindings/reset/qcom,mmcc-msm8974.h> |
27 | 27 | ||
28 | #include "common.h" | ||
28 | #include "clk-regmap.h" | 29 | #include "clk-regmap.h" |
29 | #include "clk-pll.h" | 30 | #include "clk-pll.h" |
30 | #include "clk-rcg.h" | 31 | #include "clk-rcg.h" |
@@ -2524,88 +2525,39 @@ static const struct regmap_config mmcc_msm8974_regmap_config = { | |||
2524 | .fast_io = true, | 2525 | .fast_io = true, |
2525 | }; | 2526 | }; |
2526 | 2527 | ||
2528 | static const struct qcom_cc_desc mmcc_msm8974_desc = { | ||
2529 | .config = &mmcc_msm8974_regmap_config, | ||
2530 | .clks = mmcc_msm8974_clocks, | ||
2531 | .num_clks = ARRAY_SIZE(mmcc_msm8974_clocks), | ||
2532 | .resets = mmcc_msm8974_resets, | ||
2533 | .num_resets = ARRAY_SIZE(mmcc_msm8974_resets), | ||
2534 | }; | ||
2535 | |||
2527 | static const struct of_device_id mmcc_msm8974_match_table[] = { | 2536 | static const struct of_device_id mmcc_msm8974_match_table[] = { |
2528 | { .compatible = "qcom,mmcc-msm8974" }, | 2537 | { .compatible = "qcom,mmcc-msm8974" }, |
2529 | { } | 2538 | { } |
2530 | }; | 2539 | }; |
2531 | MODULE_DEVICE_TABLE(of, mmcc_msm8974_match_table); | 2540 | MODULE_DEVICE_TABLE(of, mmcc_msm8974_match_table); |
2532 | 2541 | ||
2533 | struct qcom_cc { | ||
2534 | struct qcom_reset_controller reset; | ||
2535 | struct clk_onecell_data data; | ||
2536 | struct clk *clks[]; | ||
2537 | }; | ||
2538 | |||
2539 | static int mmcc_msm8974_probe(struct platform_device *pdev) | 2542 | static int mmcc_msm8974_probe(struct platform_device *pdev) |
2540 | { | 2543 | { |
2541 | void __iomem *base; | 2544 | int ret; |
2542 | struct resource *res; | ||
2543 | int i, ret; | ||
2544 | struct device *dev = &pdev->dev; | ||
2545 | struct clk *clk; | ||
2546 | struct clk_onecell_data *data; | ||
2547 | struct clk **clks; | ||
2548 | struct regmap *regmap; | 2545 | struct regmap *regmap; |
2549 | size_t num_clks; | ||
2550 | struct qcom_reset_controller *reset; | ||
2551 | struct qcom_cc *cc; | ||
2552 | |||
2553 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
2554 | base = devm_ioremap_resource(dev, res); | ||
2555 | if (IS_ERR(base)) | ||
2556 | return PTR_ERR(base); | ||
2557 | |||
2558 | regmap = devm_regmap_init_mmio(dev, base, &mmcc_msm8974_regmap_config); | ||
2559 | if (IS_ERR(regmap)) | ||
2560 | return PTR_ERR(regmap); | ||
2561 | |||
2562 | num_clks = ARRAY_SIZE(mmcc_msm8974_clocks); | ||
2563 | cc = devm_kzalloc(dev, sizeof(*cc) + sizeof(*clks) * num_clks, | ||
2564 | GFP_KERNEL); | ||
2565 | if (!cc) | ||
2566 | return -ENOMEM; | ||
2567 | |||
2568 | clks = cc->clks; | ||
2569 | data = &cc->data; | ||
2570 | data->clks = clks; | ||
2571 | data->clk_num = num_clks; | ||
2572 | |||
2573 | clk_pll_configure_sr_hpm_lp(&mmpll1, regmap, &mmpll1_config, true); | ||
2574 | clk_pll_configure_sr_hpm_lp(&mmpll3, regmap, &mmpll3_config, false); | ||
2575 | 2546 | ||
2576 | for (i = 0; i < num_clks; i++) { | 2547 | ret = qcom_cc_probe(pdev, &mmcc_msm8974_desc); |
2577 | if (!mmcc_msm8974_clocks[i]) | ||
2578 | continue; | ||
2579 | clk = devm_clk_register_regmap(dev, mmcc_msm8974_clocks[i]); | ||
2580 | if (IS_ERR(clk)) | ||
2581 | return PTR_ERR(clk); | ||
2582 | clks[i] = clk; | ||
2583 | } | ||
2584 | |||
2585 | ret = of_clk_add_provider(dev->of_node, of_clk_src_onecell_get, data); | ||
2586 | if (ret) | 2548 | if (ret) |
2587 | return ret; | 2549 | return ret; |
2588 | 2550 | ||
2589 | reset = &cc->reset; | 2551 | regmap = dev_get_regmap(&pdev->dev, NULL); |
2590 | reset->rcdev.of_node = dev->of_node; | 2552 | clk_pll_configure_sr_hpm_lp(&mmpll1, regmap, &mmpll1_config, true); |
2591 | reset->rcdev.ops = &qcom_reset_ops, | 2553 | clk_pll_configure_sr_hpm_lp(&mmpll3, regmap, &mmpll3_config, false); |
2592 | reset->rcdev.owner = THIS_MODULE, | ||
2593 | reset->rcdev.nr_resets = ARRAY_SIZE(mmcc_msm8974_resets), | ||
2594 | reset->regmap = regmap; | ||
2595 | reset->reset_map = mmcc_msm8974_resets, | ||
2596 | platform_set_drvdata(pdev, &reset->rcdev); | ||
2597 | |||
2598 | ret = reset_controller_register(&reset->rcdev); | ||
2599 | if (ret) | ||
2600 | of_clk_del_provider(dev->of_node); | ||
2601 | 2554 | ||
2602 | return ret; | 2555 | return 0; |
2603 | } | 2556 | } |
2604 | 2557 | ||
2605 | static int mmcc_msm8974_remove(struct platform_device *pdev) | 2558 | static int mmcc_msm8974_remove(struct platform_device *pdev) |
2606 | { | 2559 | { |
2607 | of_clk_del_provider(pdev->dev.of_node); | 2560 | qcom_cc_remove(pdev); |
2608 | reset_controller_unregister(platform_get_drvdata(pdev)); | ||
2609 | return 0; | 2561 | return 0; |
2610 | } | 2562 | } |
2611 | 2563 | ||