aboutsummaryrefslogtreecommitdiffstats
path: root/common/recipes-kernel/linux/linux-yocto-4.14.71/0851-Driver-reports-error-for-in-completed-I2C-transactio.patch
blob: b565ba2e435ab8765199ed4997fd3fa144f0fc31 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
From 3019de114b6a3214e89383f760b6ec7fe238aa77 Mon Sep 17 00:00:00 2001
From: Sudheesh Mavila <sudheesh.mavila@amd.com>
Date: Wed, 31 Jan 2018 11:01:15 +0530
Subject: [PATCH 0851/4131] Driver reports error for in-completed I2C
 transaction

Signed-off-by: Sudheesh Mavila <sudheesh.mavila@amd.com>
---
 drivers/i2c/busses/i2c-designware-common.c |  5 +++--
 drivers/i2c/busses/i2c-designware-core.h   |  2 +-
 drivers/i2c/busses/i2c-designware-master.c | 18 +++++++++++++-----
 drivers/i2c/busses/i2c-designware-slave.c  |  6 ++++--
 4 files changed, 21 insertions(+), 10 deletions(-)
 mode change 100644 => 100755 drivers/i2c/busses/i2c-designware-common.c
 mode change 100644 => 100755 drivers/i2c/busses/i2c-designware-core.h
 mode change 100644 => 100755 drivers/i2c/busses/i2c-designware-master.c
 mode change 100644 => 100755 drivers/i2c/busses/i2c-designware-slave.c

diff --git a/drivers/i2c/busses/i2c-designware-common.c b/drivers/i2c/busses/i2c-designware-common.c
old mode 100644
new mode 100755
index d1a6937..68707cd
--- a/drivers/i2c/busses/i2c-designware-common.c
+++ b/drivers/i2c/busses/i2c-designware-common.c
@@ -153,14 +153,14 @@ void __i2c_dw_enable(struct dw_i2c_dev *dev, bool enable)
 	dw_writel(dev, enable, DW_IC_ENABLE);
 }
 
-void __i2c_dw_enable_and_wait(struct dw_i2c_dev *dev, bool enable)
+int __i2c_dw_enable_and_wait(struct dw_i2c_dev *dev, bool enable)
 {
 	int timeout = 100;
 
 	do {
 		__i2c_dw_enable(dev, enable);
 		if ((dw_readl(dev, DW_IC_ENABLE_STATUS) & 1) == enable)
-			return;
+			return 0;
 
 		/*
 		 * Wait 10 times the signaling period of the highest I2C
@@ -172,6 +172,7 @@ void __i2c_dw_enable_and_wait(struct dw_i2c_dev *dev, bool enable)
 
 	dev_warn(dev->dev, "timeout in %sabling adapter\n",
 		 enable ? "en" : "dis");
+	return -ETIMEDOUT;
 }
 
 unsigned long i2c_dw_clk_rate(struct dw_i2c_dev *dev)
diff --git a/drivers/i2c/busses/i2c-designware-core.h b/drivers/i2c/busses/i2c-designware-core.h
old mode 100644
new mode 100755
index 9fee4c0..9652765
--- a/drivers/i2c/busses/i2c-designware-core.h
+++ b/drivers/i2c/busses/i2c-designware-core.h
@@ -297,7 +297,7 @@ void dw_writel(struct dw_i2c_dev *dev, u32 b, int offset);
 u32 i2c_dw_scl_hcnt(u32 ic_clk, u32 tSYMBOL, u32 tf, int cond, int offset);
 u32 i2c_dw_scl_lcnt(u32 ic_clk, u32 tLOW, u32 tf, int offset);
 void __i2c_dw_enable(struct dw_i2c_dev *dev, bool enable);
-void __i2c_dw_enable_and_wait(struct dw_i2c_dev *dev, bool enable);
+int __i2c_dw_enable_and_wait(struct dw_i2c_dev *dev, bool enable);
 unsigned long i2c_dw_clk_rate(struct dw_i2c_dev *dev);
 int i2c_dw_acquire_lock(struct dw_i2c_dev *dev);
 void i2c_dw_release_lock(struct dw_i2c_dev *dev);
diff --git a/drivers/i2c/busses/i2c-designware-master.c b/drivers/i2c/busses/i2c-designware-master.c
old mode 100644
new mode 100755
index 4915fa3..34dffd6
--- a/drivers/i2c/busses/i2c-designware-master.c
+++ b/drivers/i2c/busses/i2c-designware-master.c
@@ -79,7 +79,9 @@ static int i2c_dw_init_master(struct dw_i2c_dev *dev)
 	comp_param1 = dw_readl(dev, DW_IC_COMP_PARAM_1);
 
 	/* Disable the adapter */
-	__i2c_dw_enable_and_wait(dev, false);
+	ret = __i2c_dw_enable_and_wait(dev, false);
+	if (ret<0)
+		return ret;
 
 	/* Set standard and fast speed deviders for high/low periods */
 
@@ -172,13 +174,16 @@ static int i2c_dw_init_master(struct dw_i2c_dev *dev)
 	return 0;
 }
 
-static void i2c_dw_xfer_init(struct dw_i2c_dev *dev)
+static int i2c_dw_xfer_init(struct dw_i2c_dev *dev)
 {
 	struct i2c_msg *msgs = dev->msgs;
 	u32 ic_con, ic_tar = 0;
+	int ret = 0;
 
 	/* Disable the adapter */
-	__i2c_dw_enable_and_wait(dev, false);
+	ret = __i2c_dw_enable_and_wait(dev, false);
+	if (ret<0)
+		return ret;
 
 	/* If the slave address is ten bit address, enable 10BITADDR */
 	ic_con = dw_readl(dev, DW_IC_CON);
@@ -215,6 +220,7 @@ static void i2c_dw_xfer_init(struct dw_i2c_dev *dev)
 	/* Clear and enable interrupts */
 	dw_readl(dev, DW_IC_CLR_INTR);
 	dw_writel(dev, DW_IC_INTR_MASTER_MASK, DW_IC_INTR_MASK);
+	return ret;
 }
 
 /*
@@ -439,8 +445,10 @@ i2c_dw_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
 	if (ret < 0)
 		goto done;
 
-	/* Start the transfers */
-	i2c_dw_xfer_init(dev);
+	/* start the transfers */
+	ret = i2c_dw_xfer_init(dev);
+	if (ret < 0)
+		goto done;
 
 	/* Wait for tx to complete */
 	if (!wait_for_completion_timeout(&dev->cmd_complete, adap->timeout)) {
diff --git a/drivers/i2c/busses/i2c-designware-slave.c b/drivers/i2c/busses/i2c-designware-slave.c
old mode 100644
new mode 100755
index ea9578a..13154a3
--- a/drivers/i2c/busses/i2c-designware-slave.c
+++ b/drivers/i2c/busses/i2c-designware-slave.c
@@ -76,8 +76,10 @@ static int i2c_dw_init_slave(struct dw_i2c_dev *dev)
 
 	comp_param1 = dw_readl(dev, DW_IC_COMP_PARAM_1);
 
-	/* Disable the adapter. */
-	__i2c_dw_enable_and_wait(dev, false);
+	/* Disable the adapter */
+	ret = __i2c_dw_enable_and_wait(dev, false);
+	if (ret<0)
+		return ret;
 
 	/* Set standard and fast speed deviders for high/low periods. */
 	sda_falling_time = dev->sda_falling_time ?: 300; /* ns */
-- 
2.7.4