summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/sh/clk/cpg.c38
-rw-r--r--include/linux/sh_clk.h19
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
39static unsigned int r8(const void __iomem *addr)
40{
41 return ioread8(addr);
42}
43
44static unsigned int r16(const void __iomem *addr)
45{
46 return ioread16(addr);
47}
48
49static unsigned int r32(const void __iomem *addr)
50{
51 return ioread32(addr);
52}
53
39static int sh_clk_mstp_enable(struct clk *clk) 54static 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
136int sh_clk_mstp_register(struct clk *clks, int nr); 141int sh_clk_mstp_register(struct clk *clks, int nr);
137 142