clk: mediatek: add support to configure clock driver parent
[platform/kernel/u-boot.git] / drivers / clk / clk_fixed_rate.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (C) 2016 Masahiro Yamada <yamada.masahiro@socionext.com>
4  */
5
6 #define LOG_CATEGORY UCLASS_CLK
7
8 #include <common.h>
9 #include <clk-uclass.h>
10 #include <dm.h>
11 #include <log.h>
12 #include <dm/device-internal.h>
13 #include <linux/clk-provider.h>
14
15 #define UBOOT_DM_CLK_FIXED_RATE "fixed_rate_clock"
16 #define UBOOT_DM_CLK_FIXED_RATE_RAW "fixed_rate_raw_clock"
17
18 static ulong clk_fixed_rate_get_rate(struct clk *clk)
19 {
20         return to_clk_fixed_rate(clk->dev)->fixed_rate;
21 }
22
23 /* avoid clk_enable() return -ENOSYS */
24 static int dummy_enable(struct clk *clk)
25 {
26         return 0;
27 }
28
29 const struct clk_ops clk_fixed_rate_ops = {
30         .get_rate = clk_fixed_rate_get_rate,
31         .enable = dummy_enable,
32         .disable = dummy_enable,
33 };
34
35 void clk_fixed_rate_ofdata_to_plat_(struct udevice *dev,
36                                     struct clk_fixed_rate *plat)
37 {
38         struct clk *clk = &plat->clk;
39         if (CONFIG_IS_ENABLED(OF_REAL))
40                 plat->fixed_rate = dev_read_u32_default(dev, "clock-frequency",
41                                                         0);
42
43         /* Make fixed rate clock accessible from higher level struct clk */
44         /* FIXME: This is not allowed */
45         dev_set_uclass_priv(dev, clk);
46
47         clk->dev = dev;
48         clk->enable_count = 0;
49 }
50
51 static ulong clk_fixed_rate_raw_get_rate(struct clk *clk)
52 {
53         return container_of(clk, struct clk_fixed_rate, clk)->fixed_rate;
54 }
55
56 const struct clk_ops clk_fixed_rate_raw_ops = {
57         .get_rate = clk_fixed_rate_raw_get_rate,
58 };
59
60 static int clk_fixed_rate_of_to_plat(struct udevice *dev)
61 {
62         clk_fixed_rate_ofdata_to_plat_(dev, to_clk_fixed_rate(dev));
63
64         return 0;
65 }
66
67 #if CONFIG_IS_ENABLED(CLK_CCF)
68 struct clk *clk_register_fixed_rate(struct device *dev, const char *name,
69                                     ulong rate)
70 {
71         struct clk *clk;
72         struct clk_fixed_rate *fixed;
73         int ret;
74
75         fixed = kzalloc(sizeof(*fixed), GFP_KERNEL);
76         if (!fixed)
77                 return ERR_PTR(-ENOMEM);
78
79         fixed->fixed_rate = rate;
80
81         clk = &fixed->clk;
82
83         ret = clk_register(clk, UBOOT_DM_CLK_FIXED_RATE_RAW, name, NULL);
84         if (ret) {
85                 kfree(fixed);
86                 return ERR_PTR(ret);
87         }
88
89         return clk;
90 }
91 #endif
92
93 static const struct udevice_id clk_fixed_rate_match[] = {
94         {
95                 .compatible = "fixed-clock",
96         },
97         { /* sentinel */ }
98 };
99
100 U_BOOT_DRIVER(fixed_clock) = {
101         .name = "fixed_clock",
102         .id = UCLASS_CLK,
103         .of_match = clk_fixed_rate_match,
104         .of_to_plat = clk_fixed_rate_of_to_plat,
105         .plat_auto      = sizeof(struct clk_fixed_rate),
106         .ops = &clk_fixed_rate_ops,
107         .flags = DM_FLAG_PRE_RELOC,
108 };
109
110 U_BOOT_DRIVER(clk_fixed_rate_raw) = {
111         .name = UBOOT_DM_CLK_FIXED_RATE_RAW,
112         .id = UCLASS_CLK,
113         .ops = &clk_fixed_rate_raw_ops,
114         .flags = DM_FLAG_PRE_RELOC,
115 };