]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/clk/sunxi/clk-sun9i-core.c
Merge remote-tracking branch 'device-mapper/for-next'
[karo-tx-linux.git] / drivers / clk / sunxi / clk-sun9i-core.c
index 6c4c98324d3cc6800bace1b4a918707e2b4cc53f..43f014f85803109aa5cca03dbe045d05a7a4b120 100644 (file)
@@ -15,6 +15,7 @@
  */
 
 #include <linux/clk.h>
+#include <linux/clkdev.h>
 #include <linux/clk-provider.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
  * p and m are named div1 and div2 in Allwinner's SDK
  */
 
-static void sun9i_a80_get_pll4_factors(u32 *freq, u32 parent_rate,
-                                      u8 *n_ret, u8 *k, u8 *m_ret, u8 *p_ret)
+static void sun9i_a80_get_pll4_factors(struct factors_request *req)
 {
        int n;
        int m = 1;
        int p = 1;
 
        /* Normalize value to a 6 MHz multiple (24 MHz / 4) */
-       n = DIV_ROUND_UP(*freq, 6000000);
+       n = DIV_ROUND_UP(req->rate, 6000000);
 
        /* If n is too large switch to steps of 12 MHz */
        if (n > 255) {
@@ -60,18 +60,13 @@ static void sun9i_a80_get_pll4_factors(u32 *freq, u32 parent_rate,
        else if (n < 12)
                n = 12;
 
-       *freq = ((24000000 * n) >> p) / (m + 1);
-
-       /* we were called to round the frequency, we can now return */
-       if (n_ret == NULL)
-               return;
-
-       *n_ret = n;
-       *m_ret = m;
-       *p_ret = p;
+       req->rate = ((24000000 * n) >> p) / (m + 1);
+       req->n = n;
+       req->m = m;
+       req->p = p;
 }
 
-static struct clk_factors_config sun9i_a80_pll4_config = {
+static const struct clk_factors_config sun9i_a80_pll4_config = {
        .mshift = 18,
        .mwidth = 1,
        .nshift = 8,
@@ -111,30 +106,24 @@ CLK_OF_DECLARE(sun9i_a80_pll4, "allwinner,sun9i-a80-pll4-clk", sun9i_a80_pll4_se
  * rate = parent_rate / (m + 1);
  */
 
-static void sun9i_a80_get_gt_factors(u32 *freq, u32 parent_rate,
-                                    u8 *n, u8 *k, u8 *m, u8 *p)
+static void sun9i_a80_get_gt_factors(struct factors_request *req)
 {
        u32 div;
 
-       if (parent_rate < *freq)
-               *freq = parent_rate;
+       if (req->parent_rate < req->rate)
+               req->rate = req->parent_rate;
 
-       div = DIV_ROUND_UP(parent_rate, *freq);
+       div = DIV_ROUND_UP(req->parent_rate, req->rate);
 
        /* maximum divider is 4 */
        if (div > 4)
                div = 4;
 
-       *freq = parent_rate / div;
-
-       /* we were called to round the frequency, we can now return */
-       if (!m)
-               return;
-
-       *m = div;
+       req->rate = req->parent_rate / div;
+       req->m = div;
 }
 
-static struct clk_factors_config sun9i_a80_gt_config = {
+static const struct clk_factors_config sun9i_a80_gt_config = {
        .mshift = 0,
        .mwidth = 2,
 };
@@ -176,30 +165,24 @@ CLK_OF_DECLARE(sun9i_a80_gt, "allwinner,sun9i-a80-gt-clk", sun9i_a80_gt_setup);
  * rate = parent_rate >> p;
  */
 
-static void sun9i_a80_get_ahb_factors(u32 *freq, u32 parent_rate,
-                                     u8 *n, u8 *k, u8 *m, u8 *p)
+static void sun9i_a80_get_ahb_factors(struct factors_request *req)
 {
        u32 _p;
 
-       if (parent_rate < *freq)
-               *freq = parent_rate;
+       if (req->parent_rate < req->rate)
+               req->rate = req->parent_rate;
 
-       _p = order_base_2(DIV_ROUND_UP(parent_rate, *freq));
+       _p = order_base_2(DIV_ROUND_UP(req->parent_rate, req->rate));
 
        /* maximum p is 3 */
        if (_p > 3)
                _p = 3;
 
-       *freq = parent_rate >> _p;
-
-       /* we were called to round the frequency, we can now return */
-       if (!p)
-               return;
-
-       *p = _p;
+       req->rate = req->parent_rate >> _p;
+       req->p = _p;
 }
 
-static struct clk_factors_config sun9i_a80_ahb_config = {
+static const struct clk_factors_config sun9i_a80_ahb_config = {
        .pshift = 0,
        .pwidth = 2,
 };
@@ -262,34 +245,25 @@ CLK_OF_DECLARE(sun9i_a80_apb0, "allwinner,sun9i-a80-apb0-clk", sun9i_a80_apb0_se
  * rate = (parent_rate >> p) / (m + 1);
  */
 
-static void sun9i_a80_get_apb1_factors(u32 *freq, u32 parent_rate,
-                                      u8 *n, u8 *k, u8 *m, u8 *p)
+static void sun9i_a80_get_apb1_factors(struct factors_request *req)
 {
        u32 div;
-       u8 calcm, calcp;
 
-       if (parent_rate < *freq)
-               *freq = parent_rate;
+       if (req->parent_rate < req->rate)
+               req->rate = req->parent_rate;
 
-       div = DIV_ROUND_UP(parent_rate, *freq);
+       div = DIV_ROUND_UP(req->parent_rate, req->rate);
 
        /* Highest possible divider is 256 (p = 3, m = 31) */
        if (div > 256)
                div = 256;
 
-       calcp = order_base_2(div);
-       calcm = (parent_rate >> calcp) - 1;
-       *freq = (parent_rate >> calcp) / (calcm + 1);
-
-       /* we were called to round the frequency, we can now return */
-       if (n == NULL)
-               return;
-
-       *m = calcm;
-       *p = calcp;
+       req->p = order_base_2(div);
+       req->m = (req->parent_rate >> req->p) - 1;
+       req->rate = (req->parent_rate >> req->p) / (req->m + 1);
 }
 
-static struct clk_factors_config sun9i_a80_apb1_config = {
+static const struct clk_factors_config sun9i_a80_apb1_config = {
        .mshift = 0,
        .mwidth = 5,
        .pshift = 16,