diff options
-rw-r--r-- | drivers/sh/clk/cpg.c | 38 | ||||
-rw-r--r-- | include/linux/sh_clk.h | 19 |
2 files changed, 50 insertions, 7 deletions
diff --git a/drivers/sh/clk/cpg.c b/drivers/sh/clk/cpg.c index 1ebe67cd1833..7442bc130055 100644 --- a/drivers/sh/clk/cpg.c +++ b/drivers/sh/clk/cpg.c | |||
@@ -36,9 +36,47 @@ static void sh_clk_write(int value, struct clk *clk) | |||
36 | iowrite32(value, clk->mapped_reg); | 36 | iowrite32(value, clk->mapped_reg); |
37 | } | 37 | } |
38 | 38 | ||
39 | static unsigned int r8(const void __iomem *addr) | ||
40 | { | ||
41 | return ioread8(addr); | ||
42 | } | ||
43 | |||
44 | static unsigned int r16(const void __iomem *addr) | ||
45 | { | ||
46 | return ioread16(addr); | ||
47 | } | ||
48 | |||
49 | static unsigned int r32(const void __iomem *addr) | ||
50 | { | ||
51 | return ioread32(addr); | ||
52 | } | ||
53 | |||
39 | static int sh_clk_mstp_enable(struct clk *clk) | 54 | static int sh_clk_mstp_enable(struct clk *clk) |
40 | { | 55 | { |
41 | sh_clk_write(sh_clk_read(clk) & ~(1 << clk->enable_bit), clk); | 56 | sh_clk_write(sh_clk_read(clk) & ~(1 << clk->enable_bit), clk); |
57 | if (clk->status_reg) { | ||
58 | unsigned int (*read)(const void __iomem *addr); | ||
59 | int i; | ||
60 | void __iomem *mapped_status = (phys_addr_t)clk->status_reg - | ||
61 | (phys_addr_t)clk->enable_reg + clk->mapped_reg; | ||
62 | |||
63 | if (clk->flags & CLK_ENABLE_REG_8BIT) | ||
64 | read = r8; | ||
65 | else if (clk->flags & CLK_ENABLE_REG_16BIT) | ||
66 | read = r16; | ||
67 | else | ||
68 | read = r32; | ||
69 | |||
70 | for (i = 1000; | ||
71 | (read(mapped_status) & (1 << clk->enable_bit)) && i; | ||
72 | i--) | ||
73 | cpu_relax(); | ||
74 | if (!i) { | ||
75 | pr_err("cpg: failed to enable %p[%d]\n", | ||
76 | clk->enable_reg, clk->enable_bit); | ||
77 | return -ETIMEDOUT; | ||
78 | } | ||
79 | } | ||
42 | return 0; | 80 | return 0; |
43 | } | 81 | } |
44 | 82 | ||
diff --git a/include/linux/sh_clk.h b/include/linux/sh_clk.h index 60c72395ec6b..1f208b2a1ed6 100644 --- a/include/linux/sh_clk.h +++ b/include/linux/sh_clk.h | |||
@@ -52,6 +52,7 @@ struct clk { | |||
52 | unsigned long flags; | 52 | unsigned long flags; |
53 | 53 | ||
54 | void __iomem *enable_reg; | 54 | void __iomem *enable_reg; |
55 | void __iomem *status_reg; | ||
55 | unsigned int enable_bit; | 56 | unsigned int enable_bit; |
56 | void __iomem *mapped_reg; | 57 | void __iomem *mapped_reg; |
57 | 58 | ||
@@ -116,22 +117,26 @@ long clk_round_parent(struct clk *clk, unsigned long target, | |||
116 | unsigned long *best_freq, unsigned long *parent_freq, | 117 | unsigned long *best_freq, unsigned long *parent_freq, |
117 | unsigned int div_min, unsigned int div_max); | 118 | unsigned int div_min, unsigned int div_max); |
118 | 119 | ||
119 | #define SH_CLK_MSTP(_parent, _enable_reg, _enable_bit, _flags) \ | 120 | #define SH_CLK_MSTP(_parent, _enable_reg, _enable_bit, _status_reg, _flags) \ |
120 | { \ | 121 | { \ |
121 | .parent = _parent, \ | 122 | .parent = _parent, \ |
122 | .enable_reg = (void __iomem *)_enable_reg, \ | 123 | .enable_reg = (void __iomem *)_enable_reg, \ |
123 | .enable_bit = _enable_bit, \ | 124 | .enable_bit = _enable_bit, \ |
125 | .status_reg = _status_reg, \ | ||
124 | .flags = _flags, \ | 126 | .flags = _flags, \ |
125 | } | 127 | } |
126 | 128 | ||
127 | #define SH_CLK_MSTP32(_p, _r, _b, _f) \ | 129 | #define SH_CLK_MSTP32(_p, _r, _b, _f) \ |
128 | SH_CLK_MSTP(_p, _r, _b, _f | CLK_ENABLE_REG_32BIT) | 130 | SH_CLK_MSTP(_p, _r, _b, 0, _f | CLK_ENABLE_REG_32BIT) |
129 | 131 | ||
130 | #define SH_CLK_MSTP16(_p, _r, _b, _f) \ | 132 | #define SH_CLK_MSTP32_STS(_p, _r, _b, _s, _f) \ |
131 | SH_CLK_MSTP(_p, _r, _b, _f | CLK_ENABLE_REG_16BIT) | 133 | SH_CLK_MSTP(_p, _r, _b, _s, _f | CLK_ENABLE_REG_32BIT) |
132 | 134 | ||
133 | #define SH_CLK_MSTP8(_p, _r, _b, _f) \ | 135 | #define SH_CLK_MSTP16(_p, _r, _b, _f) \ |
134 | SH_CLK_MSTP(_p, _r, _b, _f | CLK_ENABLE_REG_8BIT) | 136 | SH_CLK_MSTP(_p, _r, _b, 0, _f | CLK_ENABLE_REG_16BIT) |
137 | |||
138 | #define SH_CLK_MSTP8(_p, _r, _b, _f) \ | ||
139 | SH_CLK_MSTP(_p, _r, _b, 0, _f | CLK_ENABLE_REG_8BIT) | ||
135 | 140 | ||
136 | int sh_clk_mstp_register(struct clk *clks, int nr); | 141 | int sh_clk_mstp_register(struct clk *clks, int nr); |
137 | 142 | ||