From e09b41010ba33a20a87472ee821fa407a5b8da36 Mon Sep 17 00:00:00 2001 From: José Pekkarinen Date: Mon, 11 Apr 2016 10:41:07 +0300 Subject: These changes are the raw update to linux-4.4.6-rt14. Kernel sources are taken from kernel.org, and rt patch from the rt wiki download page. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit During the rebasing, the following patch collided: Force tick interrupt and get rid of softirq magic(I70131fb85). Collisions have been removed because its logic was found on the source already. Change-Id: I7f57a4081d9deaa0d9ccfc41a6c8daccdee3b769 Signed-off-by: José Pekkarinen --- kernel/drivers/i2c/busses/i2c-axxia.c | 41 +++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) (limited to 'kernel/drivers/i2c/busses/i2c-axxia.c') diff --git a/kernel/drivers/i2c/busses/i2c-axxia.c b/kernel/drivers/i2c/busses/i2c-axxia.c index 32d883490..c335cc785 100644 --- a/kernel/drivers/i2c/busses/i2c-axxia.c +++ b/kernel/drivers/i2c/busses/i2c-axxia.c @@ -42,6 +42,10 @@ #define IBML_LOW_SEXT 0x18 #define TIMER_CLOCK_DIV 0x1c #define I2C_BUS_MONITOR 0x20 +#define BM_SDAC BIT(3) +#define BM_SCLC BIT(2) +#define BM_SDAS BIT(1) +#define BM_SCLS BIT(0) #define SOFT_RESET 0x24 #define MST_COMMAND 0x28 #define CMD_BUSY (1<<3) @@ -394,6 +398,9 @@ static int axxia_i2c_xfer_msg(struct axxia_i2c_dev *idev, struct i2c_msg *msg) if (time_left == 0) idev->msg_err = -ETIMEDOUT; + if (idev->msg_err == -ETIMEDOUT) + i2c_recover_bus(&idev->adapter); + if (unlikely(idev->msg_err) && idev->msg_err != -ENXIO) axxia_i2c_init(idev); @@ -437,6 +444,39 @@ axxia_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) return ret ? : i; } +static int axxia_i2c_get_scl(struct i2c_adapter *adap) +{ + struct axxia_i2c_dev *idev = i2c_get_adapdata(adap); + + return !!(readl(idev->base + I2C_BUS_MONITOR) & BM_SCLS); +} + +static void axxia_i2c_set_scl(struct i2c_adapter *adap, int val) +{ + struct axxia_i2c_dev *idev = i2c_get_adapdata(adap); + u32 tmp; + + /* Preserve SDA Control */ + tmp = readl(idev->base + I2C_BUS_MONITOR) & BM_SDAC; + if (!val) + tmp |= BM_SCLC; + writel(tmp, idev->base + I2C_BUS_MONITOR); +} + +static int axxia_i2c_get_sda(struct i2c_adapter *adap) +{ + struct axxia_i2c_dev *idev = i2c_get_adapdata(adap); + + return !!(readl(idev->base + I2C_BUS_MONITOR) & BM_SDAS); +} + +static struct i2c_bus_recovery_info axxia_i2c_recovery_info = { + .recover_bus = i2c_generic_scl_recovery, + .get_scl = axxia_i2c_get_scl, + .set_scl = axxia_i2c_set_scl, + .get_sda = axxia_i2c_get_sda, +}; + static u32 axxia_i2c_func(struct i2c_adapter *adap) { u32 caps = (I2C_FUNC_I2C | I2C_FUNC_10BIT_ADDR | @@ -511,6 +551,7 @@ static int axxia_i2c_probe(struct platform_device *pdev) strlcpy(idev->adapter.name, pdev->name, sizeof(idev->adapter.name)); idev->adapter.owner = THIS_MODULE; idev->adapter.algo = &axxia_i2c_algo; + idev->adapter.bus_recovery_info = &axxia_i2c_recovery_info; idev->adapter.quirks = &axxia_i2c_quirks; idev->adapter.dev.parent = &pdev->dev; idev->adapter.dev.of_node = pdev->dev.of_node; -- cgit 1.2.3-korg