Merge branch 'master' of git://git.denx.de/u-boot-socfpga
[oweals/u-boot.git] / drivers / i2c / stm32f7_i2c.c
index bf5fefab7bfb72cb4acb1d5c48c1999819119ed1..50c4fd0de23ab7e8d54ab918a65336a2a56adc99 100644 (file)
@@ -1,7 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * (C) Copyright 2017 STMicroelectronics
- *
- * SPDX-License-Identifier:    GPL-2.0+
  */
 
 #include <common.h>
@@ -59,7 +58,7 @@ struct stm32_i2c_regs {
 #define STM32_I2C_CR2_ADD10                    BIT(11)
 #define STM32_I2C_CR2_RD_WRN                   BIT(10)
 #define STM32_I2C_CR2_SADD10_MASK              GENMASK(9, 0)
-#define STM32_I2C_CR2_SADD10(n)                        ((n & STM32_I2C_CR2_SADD10_MASK))
+#define STM32_I2C_CR2_SADD10(n)                        (n & STM32_I2C_CR2_SADD10_MASK)
 #define STM32_I2C_CR2_SADD7_MASK               GENMASK(7, 1)
 #define STM32_I2C_CR2_SADD7(n)                 ((n & 0x7f) << 1)
 #define STM32_I2C_CR2_RESET_MASK               (STM32_I2C_CR2_HEAD10R \
@@ -198,7 +197,7 @@ struct stm32_i2c_priv {
        int speed;
 };
 
-static struct stm32_i2c_spec i2c_specs[] = {
+static const struct stm32_i2c_spec i2c_specs[] = {
        [STM32_I2C_SPEED_STANDARD] = {
                .rate = STANDARD_RATE,
                .rate_min = 8000,
@@ -237,15 +236,13 @@ static struct stm32_i2c_spec i2c_specs[] = {
        },
 };
 
-static struct stm32_i2c_setup stm32f7_setup = {
+static const struct stm32_i2c_setup stm32f7_setup = {
        .rise_time = STM32_I2C_RISE_TIME_DEFAULT,
        .fall_time = STM32_I2C_FALL_TIME_DEFAULT,
        .dnf = STM32_I2C_DNF_DEFAULT,
        .analog_filter = STM32_I2C_ANALOG_FILTER_ENABLE,
 };
 
-DECLARE_GLOBAL_DATA_PTR;
-
 static int stm32_i2c_check_device_busy(struct stm32_i2c_priv *i2c_priv)
 {
        struct stm32_i2c_regs *regs = i2c_priv->regs;
@@ -258,7 +255,7 @@ static int stm32_i2c_check_device_busy(struct stm32_i2c_priv *i2c_priv)
 }
 
 static void stm32_i2c_message_start(struct stm32_i2c_priv *i2c_priv,
-                                     struct i2c_msg *msg, bool stop)
+                                   struct i2c_msg *msg, bool stop)
 {
        struct stm32_i2c_regs *regs = i2c_priv->regs;
        u32 cr2 = readl(&regs->cr2);
@@ -302,7 +299,7 @@ static void stm32_i2c_message_start(struct stm32_i2c_priv *i2c_priv,
  */
 
 static void stm32_i2c_handle_reload(struct stm32_i2c_priv *i2c_priv,
-                                     struct i2c_msg *msg, bool stop)
+                                   struct i2c_msg *msg, bool stop)
 {
        struct stm32_i2c_regs *regs = i2c_priv->regs;
        u32 cr2 = readl(&regs->cr2);
@@ -320,7 +317,7 @@ static void stm32_i2c_handle_reload(struct stm32_i2c_priv *i2c_priv,
 }
 
 static int stm32_i2c_wait_flags(struct stm32_i2c_priv *i2c_priv,
-                                 u32 flags, u32 *status)
+                               u32 flags, u32 *status)
 {
        struct stm32_i2c_regs *regs = i2c_priv->regs;
        u32 time_start = get_timer(0);
@@ -395,7 +392,7 @@ static int stm32_i2c_check_end_of_message(struct stm32_i2c_priv *i2c_priv)
 }
 
 static int stm32_i2c_message_xfer(struct stm32_i2c_priv *i2c_priv,
-                                   struct i2c_msg *msg, bool stop)
+                                 struct i2c_msg *msg, bool stop)
 {
        struct stm32_i2c_regs *regs = i2c_priv->regs;
        u32 status;
@@ -468,7 +465,7 @@ static int stm32_i2c_message_xfer(struct stm32_i2c_priv *i2c_priv,
 }
 
 static int stm32_i2c_xfer(struct udevice *bus, struct i2c_msg *msg,
-                           int nmsgs)
+                         int nmsgs)
 {
        struct stm32_i2c_priv *i2c_priv = dev_get_priv(bus);
        int ret;
@@ -503,7 +500,7 @@ static int stm32_i2c_compute_solutions(struct stm32_i2c_setup *setup,
        af_delay_max = setup->analog_filter ?
                       STM32_I2C_ANALOG_FILTER_DELAY_MAX : 0;
 
-       sdadel_min = setup->fall_time - i2c_specs[setup->speed].hddat_min -
+       sdadel_min = i2c_specs[setup->speed].hddat_min + setup->fall_time -
                     af_delay_min - (setup->dnf + 3) * i2cclk;
 
        sdadel_max = i2c_specs[setup->speed].vddat_max - setup->rise_time -
@@ -533,7 +530,7 @@ static int stm32_i2c_compute_solutions(struct stm32_i2c_setup *setup,
                                if (((sdadel >= sdadel_min) &&
                                     (sdadel <= sdadel_max)) &&
                                    (p != p_prev)) {
-                                       v = kmalloc(sizeof(*v), GFP_KERNEL);
+                                       v = calloc(1, sizeof(*v));
                                        if (!v)
                                                return -ENOMEM;
 
@@ -543,13 +540,17 @@ static int stm32_i2c_compute_solutions(struct stm32_i2c_setup *setup,
                                        p_prev = p;
 
                                        list_add_tail(&v->node, solutions);
+                                       break;
                                }
                        }
+
+                       if (p_prev == p)
+                               break;
                }
        }
 
        if (list_empty(solutions)) {
-               error("%s: no Prescaler solution\n", __func__);
+               pr_err("%s: no Prescaler solution\n", __func__);
                ret = -EPERM;
        }
 
@@ -571,6 +572,7 @@ static int stm32_i2c_choose_solution(struct stm32_i2c_setup *setup,
        u32 dnf_delay;
        u32 tsync;
        u16 l, h;
+       bool sol_found = false;
        int ret = 0;
 
        af_delay_min = setup->analog_filter ?
@@ -596,6 +598,7 @@ static int stm32_i2c_choose_solution(struct stm32_i2c_setup *setup,
 
                for (l = 0; l < STM32_SCLL_MAX; l++) {
                        u32 tscl_l = (l + 1) * prescaler + tsync;
+
                        if ((tscl_l < i2c_specs[setup->speed].l_min) ||
                            (i2cclk >=
                             ((tscl_l - af_delay_min - dnf_delay) / 4))) {
@@ -619,15 +622,16 @@ static int stm32_i2c_choose_solution(struct stm32_i2c_setup *setup,
                                                clk_error_prev = clk_error;
                                                v->scll = l;
                                                v->sclh = h;
-                                               s = v;
+                                               sol_found = true;
+                                               memcpy(s, v, sizeof(*s));
                                        }
                                }
                        }
                }
        }
 
-       if (!s) {
-               error("%s: no solution at all\n", __func__);
+       if (!sol_found) {
+               pr_err("%s: no solution at all\n", __func__);
                ret = -EPERM;
        }
 
@@ -635,56 +639,49 @@ static int stm32_i2c_choose_solution(struct stm32_i2c_setup *setup,
 }
 
 static int stm32_i2c_compute_timing(struct stm32_i2c_priv *i2c_priv,
-                                     struct stm32_i2c_setup *setup,
-                                     struct stm32_i2c_timings *output)
+                                   struct stm32_i2c_setup *setup,
+                                   struct stm32_i2c_timings *output)
 {
-       struct stm32_i2c_timings *v, *_v, *s;
+       struct stm32_i2c_timings *v, *_v;
        struct list_head solutions;
        int ret;
 
        if (setup->speed >= STM32_I2C_SPEED_END) {
-               error("%s: speed out of bound {%d/%d}\n", __func__,
-                     setup->speed, STM32_I2C_SPEED_END - 1);
+               pr_err("%s: speed out of bound {%d/%d}\n", __func__,
+                      setup->speed, STM32_I2C_SPEED_END - 1);
                return -EINVAL;
        }
 
        if ((setup->rise_time > i2c_specs[setup->speed].rise_max) ||
            (setup->fall_time > i2c_specs[setup->speed].fall_max)) {
-               error("%s :timings out of bound Rise{%d>%d}/Fall{%d>%d}\n",
-                     __func__,
-                     setup->rise_time, i2c_specs[setup->speed].rise_max,
-                     setup->fall_time, i2c_specs[setup->speed].fall_max);
+               pr_err("%s :timings out of bound Rise{%d>%d}/Fall{%d>%d}\n",
+                      __func__,
+                      setup->rise_time, i2c_specs[setup->speed].rise_max,
+                      setup->fall_time, i2c_specs[setup->speed].fall_max);
                return -EINVAL;
        }
 
        if (setup->dnf > STM32_I2C_DNF_MAX) {
-               error("%s: DNF out of bound %d/%d\n", __func__,
-                     setup->dnf, STM32_I2C_DNF_MAX);
+               pr_err("%s: DNF out of bound %d/%d\n", __func__,
+                      setup->dnf, STM32_I2C_DNF_MAX);
                return -EINVAL;
        }
 
        if (setup->speed_freq > i2c_specs[setup->speed].rate) {
-               error("%s: Freq {%d/%d}\n", __func__,
-                     setup->speed_freq, i2c_specs[setup->speed].rate);
+               pr_err("%s: Freq {%d/%d}\n", __func__,
+                      setup->speed_freq, i2c_specs[setup->speed].rate);
                return -EINVAL;
        }
 
-       s = NULL;
        INIT_LIST_HEAD(&solutions);
        ret = stm32_i2c_compute_solutions(setup, &solutions);
        if (ret)
                goto exit;
 
-       ret = stm32_i2c_choose_solution(setup, &solutions, s);
+       ret = stm32_i2c_choose_solution(setup, &solutions, output);
        if (ret)
                goto exit;
 
-       output->presc = s->presc;
-       output->scldel = s->scldel;
-       output->sdadel = s->sdadel;
-       output->scll = s->scll;
-       output->sclh = s->sclh;
-
        debug("%s: Presc: %i, scldel: %i, sdadel: %i, scll: %i, sclh: %i\n",
              __func__, output->presc,
              output->scldel, output->sdadel,
@@ -694,14 +691,14 @@ exit:
        /* Release list and memory */
        list_for_each_entry_safe(v, _v, &solutions, node) {
                list_del(&v->node);
-               kfree(v);
+               free(v);
        }
 
        return ret;
 }
 
 static int stm32_i2c_setup_timing(struct stm32_i2c_priv *i2c_priv,
-                                   struct stm32_i2c_timings *timing)
+                                 struct stm32_i2c_timings *timing)
 {
        struct stm32_i2c_setup *setup = i2c_priv->setup;
        int ret = 0;
@@ -711,7 +708,7 @@ static int stm32_i2c_setup_timing(struct stm32_i2c_priv *i2c_priv,
        setup->clock_src = clk_get_rate(&i2c_priv->clk);
 
        if (!setup->clock_src) {
-               error("%s: clock rate is 0\n", __func__);
+               pr_err("%s: clock rate is 0\n", __func__);
                return -EINVAL;
        }
 
@@ -734,7 +731,7 @@ static int stm32_i2c_setup_timing(struct stm32_i2c_priv *i2c_priv,
        } while (ret);
 
        if (ret) {
-               error("%s: impossible to compute I2C timings.\n", __func__);
+               pr_err("%s: impossible to compute I2C timings.\n", __func__);
                return ret;
        }