aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/clk/ti/interface.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/clk/ti/interface.c')
-rw-r--r--drivers/clk/ti/interface.c98
1 files changed, 74 insertions, 24 deletions
diff --git a/drivers/clk/ti/interface.c b/drivers/clk/ti/interface.c
index 9c3e8c4aaa40..265d91f071c5 100644
--- a/drivers/clk/ti/interface.c
+++ b/drivers/clk/ti/interface.c
@@ -20,6 +20,7 @@
20#include <linux/of.h> 20#include <linux/of.h>
21#include <linux/of_address.h> 21#include <linux/of_address.h>
22#include <linux/clk/ti.h> 22#include <linux/clk/ti.h>
23#include "clock.h"
23 24
24#undef pr_fmt 25#undef pr_fmt
25#define pr_fmt(fmt) "%s: " fmt, __func__ 26#define pr_fmt(fmt) "%s: " fmt, __func__
@@ -31,53 +32,102 @@ static const struct clk_ops ti_interface_clk_ops = {
31 .is_enabled = &omap2_dflt_clk_is_enabled, 32 .is_enabled = &omap2_dflt_clk_is_enabled,
32}; 33};
33 34
34static void __init _of_ti_interface_clk_setup(struct device_node *node, 35static struct clk *_register_interface(struct device *dev, const char *name,
35 const struct clk_hw_omap_ops *ops) 36 const char *parent_name,
37 void __iomem *reg, u8 bit_idx,
38 const struct clk_hw_omap_ops *ops)
36{ 39{
37 struct clk *clk;
38 struct clk_init_data init = { NULL }; 40 struct clk_init_data init = { NULL };
39 struct clk_hw_omap *clk_hw; 41 struct clk_hw_omap *clk_hw;
40 const char *parent_name; 42 struct clk *clk;
41 u32 val;
42 43
43 clk_hw = kzalloc(sizeof(*clk_hw), GFP_KERNEL); 44 clk_hw = kzalloc(sizeof(*clk_hw), GFP_KERNEL);
44 if (!clk_hw) 45 if (!clk_hw)
45 return; 46 return ERR_PTR(-ENOMEM);
46 47
47 clk_hw->hw.init = &init; 48 clk_hw->hw.init = &init;
48 clk_hw->ops = ops; 49 clk_hw->ops = ops;
49 clk_hw->flags = MEMMAP_ADDRESSING; 50 clk_hw->flags = MEMMAP_ADDRESSING;
51 clk_hw->enable_reg = reg;
52 clk_hw->enable_bit = bit_idx;
50 53
51 clk_hw->enable_reg = ti_clk_get_reg_addr(node, 0); 54 init.name = name;
52 if (!clk_hw->enable_reg)
53 goto cleanup;
54
55 if (!of_property_read_u32(node, "ti,bit-shift", &val))
56 clk_hw->enable_bit = val;
57
58 init.name = node->name;
59 init.ops = &ti_interface_clk_ops; 55 init.ops = &ti_interface_clk_ops;
60 init.flags = 0; 56 init.flags = 0;
61 57
62 parent_name = of_clk_get_parent_name(node, 0);
63 if (!parent_name) {
64 pr_err("%s must have a parent\n", node->name);
65 goto cleanup;
66 }
67
68 init.num_parents = 1; 58 init.num_parents = 1;
69 init.parent_names = &parent_name; 59 init.parent_names = &parent_name;
70 60
71 clk = clk_register(NULL, &clk_hw->hw); 61 clk = clk_register(NULL, &clk_hw->hw);
72 62
73 if (!IS_ERR(clk)) { 63 if (IS_ERR(clk))
74 of_clk_add_provider(node, of_clk_src_simple_get, clk); 64 kfree(clk_hw);
65 else
75 omap2_init_clk_hw_omap_clocks(clk); 66 omap2_init_clk_hw_omap_clocks(clk);
67
68 return clk;
69}
70
71#if defined(CONFIG_ARCH_OMAP3) && defined(CONFIG_ATAGS)
72struct clk *ti_clk_register_interface(struct ti_clk *setup)
73{
74 const struct clk_hw_omap_ops *ops = &clkhwops_iclk_wait;
75 u32 reg;
76 struct clk_omap_reg *reg_setup;
77 struct ti_clk_gate *gate;
78
79 gate = setup->data;
80 reg_setup = (struct clk_omap_reg *)&reg;
81 reg_setup->index = gate->module;
82 reg_setup->offset = gate->reg;
83
84 if (gate->flags & CLKF_NO_WAIT)
85 ops = &clkhwops_iclk;
86
87 if (gate->flags & CLKF_HSOTGUSB)
88 ops = &clkhwops_omap3430es2_iclk_hsotgusb_wait;
89
90 if (gate->flags & CLKF_DSS)
91 ops = &clkhwops_omap3430es2_iclk_dss_usbhost_wait;
92
93 if (gate->flags & CLKF_SSI)
94 ops = &clkhwops_omap3430es2_iclk_ssi_wait;
95
96 if (gate->flags & CLKF_AM35XX)
97 ops = &clkhwops_am35xx_ipss_wait;
98
99 return _register_interface(NULL, setup->name, gate->parent,
100 (void __iomem *)reg, gate->bit_shift, ops);
101}
102#endif
103
104static void __init _of_ti_interface_clk_setup(struct device_node *node,
105 const struct clk_hw_omap_ops *ops)
106{
107 struct clk *clk;
108 const char *parent_name;
109 void __iomem *reg;
110 u8 enable_bit = 0;
111 u32 val;
112
113 reg = ti_clk_get_reg_addr(node, 0);
114 if (!reg)
115 return;
116
117 if (!of_property_read_u32(node, "ti,bit-shift", &val))
118 enable_bit = val;
119
120 parent_name = of_clk_get_parent_name(node, 0);
121 if (!parent_name) {
122 pr_err("%s must have a parent\n", node->name);
76 return; 123 return;
77 } 124 }
78 125
79cleanup: 126 clk = _register_interface(NULL, node->name, parent_name, reg,
80 kfree(clk_hw); 127 enable_bit, ops);
128
129 if (!IS_ERR(clk))
130 of_clk_add_provider(node, of_clk_src_simple_get, clk);
81} 131}
82 132
83static void __init of_ti_interface_clk_setup(struct device_node *node) 133static void __init of_ti_interface_clk_setup(struct device_node *node)