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 | ||
