Patch "i2c: mv64xxx: The n clockdiv factor is 0 based on sunxi SoCs" has been added to the 4.3-stable tree
This is a note to let you know that I've just added the patch titled
i2c: mv64xxx: The n clockdiv factor is 0 based on sunxi SoCs
to the 4.3-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
i2c-mv64xxx-the-n-clockdiv-factor-is-0-based-on-sunxi-socs.patch
and it can be found in the queue-4.3 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
bba61f50f76574ca5b84b310925be7c2e8e64275Mon Sep 17 00:00:00 2001
From: Hans de Goede <[email protected]>
Date: Sun, 27 Sep 2015 16:57:08 +0200
Subject: i2c: mv64xxx: The n clockdiv factor is 0 based on sunxi SoCs
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
From: Hans de Goede <[email protected]>
commit bba61f50f76574ca5b84b310925be7c2e8e64275 upstream.
According to the datasheets the n factor for dividing the tclk is 2 to the power n on Allwinner SoCs, not 2 to the power n + 1 as it is on other mv64xxx implementations.
I've contacted Allwinner about this and they have confirmed that the datasheet is correct.
This commit fixes the clk-divider calculations for Allwinner SoCs accordingly.
--- drivers/i2c/busses/i2c-mv64xxx.c | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-)
drivers/i2c/busses/i2c-mv64xxx.c +18 -9
@@ -146,6 +146,8 @@ struct mv64xxx_i2c_data {bool errata_delay;struct reset_control *rstc;bool irq_clear_inverted; +/* Clk div is 2 to the power n, not 2 to the power n + 1 */ +bool clk_n_base_0; };static struct mv64xxx_i2c_regs mv64xxx_i2c_regs_mv64xxx = {
@@ -757,25 +759,29 @@ MODULE_DEVICE_TABLE(of, mv64xxx_i2c_of_m #ifdef CONFIG_OF #ifdef CONFIG_HAVE_CLK static int -mv64xxx_calc_freq(const int tclk, const int n, const int m) +mv64xxx_calc_freq(struct mv64xxx_i2c_data *drv_data, + const int tclk, const int n, const int m) { - return tclk / (10 * (m + 1) * (2 << n)); + if (drv_data->clk_n_base_0) + return tclk / (10 * (m + 1) * (1 << n)); + else + return tclk / (10 * (m + 1) * (2 << n)); } static bool -mv64xxx_find_baud_factors(const u32 req_freq, const u32 tclk, u32 *best_n, - u32 *best_m) +mv64xxx_find_baud_factors(struct mv64xxx_i2c_data *drv_data, + const u32 req_freq, const u32 tclk) { int freq, delta, best_delta = INT_MAX; int m, n; for (n = 0; n <= 7; n++) for (m = 0; m <= 15; m++) { - freq = mv64xxx_calc_freq(tclk, n, m); + freq = mv64xxx_calc_freq(drv_data, tclk, n, m); delta = req_freq - freq; if (delta >= 0 && delta < best_delta) { - *best_m = m; - *best_n = n; + drv_data->freq_m = m; + drv_data->freq_n = n; best_delta = delta; } if (best_delta == 0)
@@ -813,8 +819,11 @@ mv64xxx_of_config(struct mv64xxx_i2c_datif (of_property_read_u32 (np,"clock-frequency" , &bus_freq)) bus_freq =100000 ;/* 100kHz by default */ -if (!mv64xxx_find_baud_factors (bus_freq, tclk, - &drv_data->freq_n, &drv_data->freq_m)) { +if (of_device_is_compatible (np,"allwinner,sun4i-a10-i2c" ) || +of_device_is_compatible (np,"allwinner,sun6i-a31-i2c" )) + drv_data->clk_n_base_0 = true; + +if (!mv64xxx_find_baud_factors (drv_data, bus_freq, tclk)) { rc = -EINVAL ; goto out; }
Patches currently in stable-queue which might be from [email protected] are
queue-4.3/i2c-mv64xxx-the-n-clockdiv-factor-is-0-based-on-sunxi-socs.patch