Commit 909aa10e authored by Michael Turquette's avatar Michael Turquette

Merge branch 'ccf/atmel-fixes-for-4.1' of https://github.com/bbrezillon/linux-at91 into clk-fixes

parents 0f57d867 28df9c2f
...@@ -248,7 +248,7 @@ Required properties for peripheral clocks: ...@@ -248,7 +248,7 @@ Required properties for peripheral clocks:
- #address-cells : shall be 1 (reg is used to encode clk id). - #address-cells : shall be 1 (reg is used to encode clk id).
- clocks : shall be the master clock phandle. - clocks : shall be the master clock phandle.
e.g. clocks = <&mck>; e.g. clocks = <&mck>;
- name: device tree node describing a specific system clock. - name: device tree node describing a specific peripheral clock.
* #clock-cells : from common clock binding; shall be set to 0. * #clock-cells : from common clock binding; shall be set to 0.
* reg: peripheral id. See Atmel's datasheets to get a full * reg: peripheral id. See Atmel's datasheets to get a full
list of peripheral ids. list of peripheral ids.
......
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
#define PERIPHERAL_RSHIFT_MASK 0x3 #define PERIPHERAL_RSHIFT_MASK 0x3
#define PERIPHERAL_RSHIFT(val) (((val) >> 16) & PERIPHERAL_RSHIFT_MASK) #define PERIPHERAL_RSHIFT(val) (((val) >> 16) & PERIPHERAL_RSHIFT_MASK)
#define PERIPHERAL_MAX_SHIFT 4 #define PERIPHERAL_MAX_SHIFT 3
struct clk_peripheral { struct clk_peripheral {
struct clk_hw hw; struct clk_hw hw;
...@@ -242,7 +242,7 @@ static long clk_sam9x5_peripheral_round_rate(struct clk_hw *hw, ...@@ -242,7 +242,7 @@ static long clk_sam9x5_peripheral_round_rate(struct clk_hw *hw,
return *parent_rate; return *parent_rate;
if (periph->range.max) { if (periph->range.max) {
for (; shift < PERIPHERAL_MAX_SHIFT; shift++) { for (; shift <= PERIPHERAL_MAX_SHIFT; shift++) {
cur_rate = *parent_rate >> shift; cur_rate = *parent_rate >> shift;
if (cur_rate <= periph->range.max) if (cur_rate <= periph->range.max)
break; break;
...@@ -254,7 +254,7 @@ static long clk_sam9x5_peripheral_round_rate(struct clk_hw *hw, ...@@ -254,7 +254,7 @@ static long clk_sam9x5_peripheral_round_rate(struct clk_hw *hw,
best_diff = cur_rate - rate; best_diff = cur_rate - rate;
best_rate = cur_rate; best_rate = cur_rate;
for (; shift < PERIPHERAL_MAX_SHIFT; shift++) { for (; shift <= PERIPHERAL_MAX_SHIFT; shift++) {
cur_rate = *parent_rate >> shift; cur_rate = *parent_rate >> shift;
if (cur_rate < rate) if (cur_rate < rate)
cur_diff = rate - cur_rate; cur_diff = rate - cur_rate;
...@@ -289,7 +289,7 @@ static int clk_sam9x5_peripheral_set_rate(struct clk_hw *hw, ...@@ -289,7 +289,7 @@ static int clk_sam9x5_peripheral_set_rate(struct clk_hw *hw,
if (periph->range.max && rate > periph->range.max) if (periph->range.max && rate > periph->range.max)
return -EINVAL; return -EINVAL;
for (shift = 0; shift < PERIPHERAL_MAX_SHIFT; shift++) { for (shift = 0; shift <= PERIPHERAL_MAX_SHIFT; shift++) {
if (parent_rate >> shift == rate) { if (parent_rate >> shift == rate) {
periph->auto_div = false; periph->auto_div = false;
periph->div = shift; periph->div = shift;
......
...@@ -173,8 +173,7 @@ static long clk_pll_get_best_div_mul(struct clk_pll *pll, unsigned long rate, ...@@ -173,8 +173,7 @@ static long clk_pll_get_best_div_mul(struct clk_pll *pll, unsigned long rate,
int i = 0; int i = 0;
/* Check if parent_rate is a valid input rate */ /* Check if parent_rate is a valid input rate */
if (parent_rate < characteristics->input.min || if (parent_rate < characteristics->input.min)
parent_rate > characteristics->input.max)
return -ERANGE; return -ERANGE;
/* /*
...@@ -187,6 +186,15 @@ static long clk_pll_get_best_div_mul(struct clk_pll *pll, unsigned long rate, ...@@ -187,6 +186,15 @@ static long clk_pll_get_best_div_mul(struct clk_pll *pll, unsigned long rate,
if (!mindiv) if (!mindiv)
mindiv = 1; mindiv = 1;
if (parent_rate > characteristics->input.max) {
tmpdiv = DIV_ROUND_UP(parent_rate, characteristics->input.max);
if (tmpdiv > PLL_DIV_MAX)
return -ERANGE;
if (tmpdiv > mindiv)
mindiv = tmpdiv;
}
/* /*
* Calculate the maximum divider which is limited by PLL register * Calculate the maximum divider which is limited by PLL register
* layout (limited by the MUL or DIV field size). * layout (limited by the MUL or DIV field size).
......
...@@ -121,7 +121,7 @@ extern void __init of_at91sam9x5_clk_smd_setup(struct device_node *np, ...@@ -121,7 +121,7 @@ extern void __init of_at91sam9x5_clk_smd_setup(struct device_node *np,
struct at91_pmc *pmc); struct at91_pmc *pmc);
#endif #endif
#if defined(CONFIG_HAVE_AT91_SMD) #if defined(CONFIG_HAVE_AT91_H32MX)
extern void __init of_sama5d4_clk_h32mx_setup(struct device_node *np, extern void __init of_sama5d4_clk_h32mx_setup(struct device_node *np,
struct at91_pmc *pmc); struct at91_pmc *pmc);
#endif #endif
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment