diff options
author | Ashish Singh <assingh@nvidia.com> | 2017-09-13 19:14:54 -0400 |
---|---|---|
committer | mobile promotions <svcmobile_promotions@nvidia.com> | 2017-10-26 01:47:51 -0400 |
commit | cbeb10dabdd7c033842a8a0b899c35ead6084d2a (patch) | |
tree | 93c9d73a6c068d665eeb4f6ec12d7cab15343c64 /drivers/i2c | |
parent | 9e07f53e44dddbddab3ba0837a4f67c85efd73bc (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.c | 44 |
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 | ||
123 | static int tegra_ivc_i2c_add_single(struct tegra_ivc_channel *chan); | 123 | static int tegra_ivc_i2c_add_single(struct tegra_ivc_channel *chan); |
124 | 124 | ||
125 | static 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 | |||
125 | int tegra_ivc_i2c_single_xfer(struct tegra_i2c_ivc_dev *i2c_ivc_dev, | 146 | int 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; |