diff options
-rw-r--r-- | drivers/i2c/busses/i2c-bpmp-tegra.c | 39 |
1 files changed, 27 insertions, 12 deletions
diff --git a/drivers/i2c/busses/i2c-bpmp-tegra.c b/drivers/i2c/busses/i2c-bpmp-tegra.c index 3f23cb006..a2d84a398 100644 --- a/drivers/i2c/busses/i2c-bpmp-tegra.c +++ b/drivers/i2c/busses/i2c-bpmp-tegra.c | |||
@@ -190,27 +190,49 @@ static int deserialize_i2c(char *buf, size_t bufsize, | |||
190 | return 0; | 190 | return 0; |
191 | } | 191 | } |
192 | 192 | ||
193 | /** | ||
194 | * struct tegra_i2c_dev - per device i2c context | ||
195 | * @adapter: core i2c layer adapter information | ||
196 | */ | ||
197 | struct tegra_bpmp_i2c_dev { | ||
198 | struct i2c_adapter adapter; | ||
199 | u32 bpmp_adapter_id; | ||
200 | }; | ||
201 | |||
193 | 202 | ||
194 | static int tegra_bpmp_i2c(struct mrq_i2c_data_in *in, | 203 | static int tegra_bpmp_i2c(struct mrq_i2c_data_in *in, |
195 | struct mrq_i2c_data_out *out) | 204 | struct mrq_i2c_data_out *out, |
205 | struct tegra_bpmp_i2c_dev *i2c_dev) | ||
196 | { | 206 | { |
207 | unsigned long flags; | ||
208 | int ret; | ||
209 | |||
197 | if (irqs_disabled()) | 210 | if (irqs_disabled()) |
198 | return tegra_bpmp_send_receive_atomic(MRQ_I2C, | 211 | return tegra_bpmp_send_receive_atomic(MRQ_I2C, |
199 | in, sizeof(*in), out, sizeof(*out)); | 212 | in, sizeof(*in), out, sizeof(*out)); |
200 | 213 | ||
214 | if (i2c_dev->adapter.atomic_xfer_only) { | ||
215 | local_irq_save(flags); | ||
216 | ret = tegra_bpmp_send_receive_atomic(MRQ_I2C, | ||
217 | in, sizeof(*in), out, sizeof(*out)); | ||
218 | local_irq_restore(flags); | ||
219 | return ret; | ||
220 | } | ||
221 | |||
201 | return tegra_bpmp_send_receive(MRQ_I2C, | 222 | return tegra_bpmp_send_receive(MRQ_I2C, |
202 | in, sizeof(*in), out, sizeof(*out)); | 223 | in, sizeof(*in), out, sizeof(*out)); |
203 | } | 224 | } |
204 | 225 | ||
205 | static int tegra_bpmp_i2c_req(u32 adapter, struct mrq_i2c_data_in *in, | 226 | static int tegra_bpmp_i2c_req(u32 adapter, struct mrq_i2c_data_in *in, |
206 | int data_in_size, struct mrq_i2c_data_out *out) | 227 | int data_in_size, struct mrq_i2c_data_out *out, |
228 | struct tegra_bpmp_i2c_dev *i2c_dev) | ||
207 | { | 229 | { |
208 | int r; | 230 | int r; |
209 | 231 | ||
210 | in->req = MRQ_I2C_DATA_IN_REQ_I2C_REQ; | 232 | in->req = MRQ_I2C_DATA_IN_REQ_I2C_REQ; |
211 | in->data.i2c_req.adapter = adapter; | 233 | in->data.i2c_req.adapter = adapter; |
212 | in->data.i2c_req.data_in_size = data_in_size; | 234 | in->data.i2c_req.data_in_size = data_in_size; |
213 | r = tegra_bpmp_i2c(in, out); | 235 | r = tegra_bpmp_i2c(in, out, i2c_dev); |
214 | if (r) { | 236 | if (r) { |
215 | WARN_ON(r > 0); | 237 | WARN_ON(r > 0); |
216 | return r; | 238 | return r; |
@@ -222,14 +244,6 @@ static int tegra_bpmp_i2c_req(u32 adapter, struct mrq_i2c_data_in *in, | |||
222 | struct tegra_bpmp_i2c_chipdata { | 244 | struct tegra_bpmp_i2c_chipdata { |
223 | }; | 245 | }; |
224 | 246 | ||
225 | /** | ||
226 | * struct tegra_i2c_dev - per device i2c context | ||
227 | * @adapter: core i2c layer adapter information | ||
228 | */ | ||
229 | struct tegra_bpmp_i2c_dev { | ||
230 | struct i2c_adapter adapter; | ||
231 | u32 bpmp_adapter_id; | ||
232 | }; | ||
233 | 247 | ||
234 | static int tegra_bpmp_i2c_init(struct tegra_bpmp_i2c_dev *i2c_dev) | 248 | static int tegra_bpmp_i2c_init(struct tegra_bpmp_i2c_dev *i2c_dev) |
235 | { | 249 | { |
@@ -303,7 +317,8 @@ static int tegra_bpmp_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], | |||
303 | return size; | 317 | return size; |
304 | } | 318 | } |
305 | 319 | ||
306 | ret = tegra_bpmp_i2c_req(i2c_dev->bpmp_adapter_id, &in, size, &out); | 320 | ret = tegra_bpmp_i2c_req(i2c_dev->bpmp_adapter_id, &in, size, &out, |
321 | i2c_dev); | ||
307 | if (ret < 0) { | 322 | if (ret < 0) { |
308 | dev_err(&i2c_dev->adapter.dev, "tegra_bpmp_i2c_req ret %d\n", | 323 | dev_err(&i2c_dev->adapter.dev, "tegra_bpmp_i2c_req ret %d\n", |
309 | ret); | 324 | ret); |