summaryrefslogtreecommitdiffstats
path: root/drivers/i2c
diff options
context:
space:
mode:
authorAshish Singh <assingh@nvidia.com>2017-09-13 19:14:54 -0400
committermobile promotions <svcmobile_promotions@nvidia.com>2017-10-26 01:47:51 -0400
commitcbeb10dabdd7c033842a8a0b899c35ead6084d2a (patch)
tree93c9d73a6c068d665eeb4f6ec12d7cab15343c64 /drivers/i2c
parent9e07f53e44dddbddab3ba0837a4f67c85efd73bc (diff)
i2c: camrtc: Fix ivc rpc callback
Following additions and fixes done in this patch 1. Add support for callback for i2c writes, that is non-blocking calls. This currently disabled though. 2. Fix a bug for starting timer for callbacks in rpc. 3. Add tracing support in rpc for debugging. Bug 1853141 Change-Id: I91511828e3be21fc9dd878af4bcb07d4d14d50a1 Signed-off-by: Ashish Singh <assingh@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/1559498 GVS: Gerrit_Virtual_Submit Reviewed-by: Bhanu Murthy V <bmurthyv@nvidia.com> Reviewed-by: Jihoon Bang <jbang@nvidia.com>
Diffstat (limited to 'drivers/i2c')
-rw-r--r--drivers/i2c/busses/i2c-ivc-single.c44
1 files changed, 42 insertions, 2 deletions
diff --git a/drivers/i2c/busses/i2c-ivc-single.c b/drivers/i2c/busses/i2c-ivc-single.c
index 6e66fe97a..0522fb8e7 100644
--- a/drivers/i2c/busses/i2c-ivc-single.c
+++ b/drivers/i2c/busses/i2c-ivc-single.c
@@ -122,6 +122,27 @@ EXPORT_SYMBOL(tegra_ivc_i2c_get_dev);
122 122
123static int tegra_ivc_i2c_add_single(struct tegra_ivc_channel *chan); 123static int tegra_ivc_i2c_add_single(struct tegra_ivc_channel *chan);
124 124
125static void tegra_ivc_i2c_single_call_callback(
126 int ret,
127 const struct tegra_ivc_rpc_response_frame *rep,
128 void *param)
129{
130 struct device *dev = param;
131 struct camrtc_rpc_i2c_response *rpc_rsp;
132
133 if (ret != 0) {
134 dev_err(dev, "I2C transaction callback failure: %d\n", ret);
135 return;
136 }
137
138 rpc_rsp = (struct camrtc_rpc_i2c_response *)rep->payload32;
139 if (rpc_rsp->result != 0) {
140 dev_err(dev,
141 "I2C transaction callback response failure: %d\n",
142 (int)rpc_rsp->result);
143 }
144}
145
125int tegra_ivc_i2c_single_xfer(struct tegra_i2c_ivc_dev *i2c_ivc_dev, 146int tegra_ivc_i2c_single_xfer(struct tegra_i2c_ivc_dev *i2c_ivc_dev,
126 const struct i2c_msg *reqs, int num) 147 const struct i2c_msg *reqs, int num)
127{ 148{
@@ -130,6 +151,11 @@ int tegra_ivc_i2c_single_xfer(struct tegra_i2c_ivc_dev *i2c_ivc_dev,
130 int ret = 0, len = 0; 151 int ret = 0, len = 0;
131 u8 *read_ptr = NULL; 152 u8 *read_ptr = NULL;
132 int read_len = 0; 153 int read_len = 0;
154 /*
155 * blocking call always enabled, make false to enable
156 * non-blocking calls
157 */
158 bool is_blocking = true;
133 159
134 if (i2c_ivc_dev == NULL || i2c_ivc_dev->chan == NULL) 160 if (i2c_ivc_dev == NULL || i2c_ivc_dev->chan == NULL)
135 return -EIO; 161 return -EIO;
@@ -174,6 +200,10 @@ int tegra_ivc_i2c_single_xfer(struct tegra_i2c_ivc_dev *i2c_ivc_dev,
174 struct camrtc_rpc_i2c_response *rpc_rsp; 200 struct camrtc_rpc_i2c_response *rpc_rsp;
175 201
176 i2c_ivc_dev->rpc_i2c_req.request_len = len; 202 i2c_ivc_dev->rpc_i2c_req.request_len = len;
203 i2c_ivc_dev->rpc_i2c_req.callback = is_blocking ?
204 NULL : tegra_ivc_i2c_single_call_callback;
205 i2c_ivc_dev->rpc_i2c_req.callback_param =
206 &i2c_ivc_dev->chan->dev;
177 ret = tegra_ivc_rpc_call(i2c_ivc_dev->chan, 207 ret = tegra_ivc_rpc_call(i2c_ivc_dev->chan,
178 &i2c_ivc_dev->rpc_i2c_req); 208 &i2c_ivc_dev->rpc_i2c_req);
179 209
@@ -187,7 +217,13 @@ int tegra_ivc_i2c_single_xfer(struct tegra_i2c_ivc_dev *i2c_ivc_dev,
187 } 217 }
188 218
189 rpc_rsp = &i2c_ivc_dev->rpc_i2c_rsp; 219 rpc_rsp = &i2c_ivc_dev->rpc_i2c_rsp;
190 if (rpc_rsp->result) { 220 /* response results only matter if the call is blocking,
221 * else ignore
222 */
223 if (rpc_rsp->result && is_blocking) {
224 dev_err(&i2c_ivc_dev->chan->dev,
225 "I2C transaction response at addr 0x%x failed: %d\n",
226 reqs[0].addr, rpc_rsp->result);
191 ret = -EIO; 227 ret = -EIO;
192 goto error; 228 goto error;
193 } 229 }
@@ -215,6 +251,10 @@ int tegra_ivc_i2c_single_xfer(struct tegra_i2c_ivc_dev *i2c_ivc_dev,
215 pbuf[0] = CAMRTC_I2C_REQUEST_FLAG_READ; 251 pbuf[0] = CAMRTC_I2C_REQUEST_FLAG_READ;
216 ++i2c_ivc_dev->stat.reads; 252 ++i2c_ivc_dev->stat.reads;
217 i2c_ivc_dev->stat.read_bytes += preq->len; 253 i2c_ivc_dev->stat.read_bytes += preq->len;
254 /* a single read request among all requests makes the
255 * whole request to rtcpu blocking
256 */
257 is_blocking = true;
218 } 258 }
219 259
220 if ((preq->flags & I2C_M_NOSTART) == 0) { 260 if ((preq->flags & I2C_M_NOSTART) == 0) {
@@ -409,7 +449,7 @@ static int tegra_ivc_i2c_add_single(struct tegra_ivc_channel *chan)
409 sizeof(i2c_ivc_dev->rpc_i2c_rsp); 449 sizeof(i2c_ivc_dev->rpc_i2c_rsp);
410 i2c_ivc_dev->rpc_i2c_req.response = &i2c_ivc_dev->rpc_i2c_rsp; 450 i2c_ivc_dev->rpc_i2c_req.response = &i2c_ivc_dev->rpc_i2c_rsp;
411 i2c_ivc_dev->rpc_i2c_req.callback = NULL; 451 i2c_ivc_dev->rpc_i2c_req.callback = NULL;
412 i2c_ivc_dev->rpc_i2c_req.callback_param = NULL; 452 i2c_ivc_dev->rpc_i2c_req.callback_param = &i2c_ivc_dev->chan->dev;
413 i2c_ivc_dev->rpc_i2c_req.timeout_ms = 453 i2c_ivc_dev->rpc_i2c_req.timeout_ms =
414 I2C_CAMRTC_RPC_IVC_SINGLE_TIMEOUT_MS; 454 I2C_CAMRTC_RPC_IVC_SINGLE_TIMEOUT_MS;
415 i2c_ivc_dev->is_added = true; 455 i2c_ivc_dev->is_added = true;