diff options
author | Tony Prisk <linux@prisktech.co.nz> | 2012-10-18 05:26:53 -0400 |
---|---|---|
committer | Mike Turquette <mturquette@linaro.org> | 2012-11-09 20:03:55 -0500 |
commit | 973e1d1de0f8af2be7f8c94418f2cda559bd7543 (patch) | |
tree | 2e3896527b4dc2f4c3d1d9e14521ba7029d7b6dd /drivers/clk | |
parent | 0de9f23a2859a4aec5db210887c7457e0c24b9ca (diff) |
CLK: vt8500: Fix SDMMC clk special cases
This patch adds some additional handling for the SDMMC special case
in round_rate and set_rate which results in invalid divisor messages
at boot time.
Signed-off-by: Tony Prisk <linux@prisktech.co.nz>
Signed-off-by: Mike Turquette <mturquette@linaro.org>
Diffstat (limited to 'drivers/clk')
-rw-r--r-- | drivers/clk/clk-vt8500.c | 18 |
1 files changed, 18 insertions, 0 deletions
diff --git a/drivers/clk/clk-vt8500.c b/drivers/clk/clk-vt8500.c index a885600f5270..fe25570874d6 100644 --- a/drivers/clk/clk-vt8500.c +++ b/drivers/clk/clk-vt8500.c | |||
@@ -120,8 +120,17 @@ static unsigned long vt8500_dclk_recalc_rate(struct clk_hw *hw, | |||
120 | static long vt8500_dclk_round_rate(struct clk_hw *hw, unsigned long rate, | 120 | static long vt8500_dclk_round_rate(struct clk_hw *hw, unsigned long rate, |
121 | unsigned long *prate) | 121 | unsigned long *prate) |
122 | { | 122 | { |
123 | struct clk_device *cdev = to_clk_device(hw); | ||
123 | u32 divisor = *prate / rate; | 124 | u32 divisor = *prate / rate; |
124 | 125 | ||
126 | /* | ||
127 | * If this is a request for SDMMC we have to adjust the divisor | ||
128 | * when >31 to use the fixed predivisor | ||
129 | */ | ||
130 | if ((cdev->div_mask == 0x3F) && (divisor > 31)) { | ||
131 | divisor = 64 * ((divisor / 64) + 1); | ||
132 | } | ||
133 | |||
125 | return *prate / divisor; | 134 | return *prate / divisor; |
126 | } | 135 | } |
127 | 136 | ||
@@ -135,6 +144,15 @@ static int vt8500_dclk_set_rate(struct clk_hw *hw, unsigned long rate, | |||
135 | if (divisor == cdev->div_mask + 1) | 144 | if (divisor == cdev->div_mask + 1) |
136 | divisor = 0; | 145 | divisor = 0; |
137 | 146 | ||
147 | /* SDMMC mask may need to be corrected before testing if its valid */ | ||
148 | if ((cdev->div_mask == 0x3F) && (divisor > 31)) { | ||
149 | /* | ||
150 | * Bit 5 is a fixed /64 predivisor. If the requested divisor | ||
151 | * is >31 then correct for the fixed divisor being required. | ||
152 | */ | ||
153 | divisor = 0x20 + (divisor / 64); | ||
154 | } | ||
155 | |||
138 | if (divisor > cdev->div_mask) { | 156 | if (divisor > cdev->div_mask) { |
139 | pr_err("%s: invalid divisor for clock\n", __func__); | 157 | pr_err("%s: invalid divisor for clock\n", __func__); |
140 | return -EINVAL; | 158 | return -EINVAL; |