.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * drivers/i2c/busses/i2c-tegra-bpmp.c |
---|
3 | 4 | * |
---|
4 | 5 | * Copyright (c) 2016 NVIDIA Corporation. All rights reserved. |
---|
5 | 6 | * |
---|
6 | 7 | * Author: Shardar Shariff Md <smohammed@nvidia.com> |
---|
7 | | - * |
---|
8 | | - * This program is free software; you can redistribute it and/or modify it |
---|
9 | | - * under the terms and conditions of the GNU General Public License, |
---|
10 | | - * version 2, as published by the Free Software Foundation. |
---|
11 | | - * |
---|
12 | | - * This program is distributed in the hope it will be useful, but WITHOUT |
---|
13 | | - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
---|
14 | | - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
---|
15 | | - * more details. |
---|
16 | | - * |
---|
17 | | - * You should have received a copy of the GNU General Public License |
---|
18 | | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
---|
19 | 8 | */ |
---|
20 | 9 | |
---|
21 | 10 | #include <linux/err.h> |
---|
.. | .. |
---|
207 | 196 | |
---|
208 | 197 | static int tegra_bpmp_i2c_msg_xfer(struct tegra_bpmp_i2c *i2c, |
---|
209 | 198 | struct mrq_i2c_request *request, |
---|
210 | | - struct mrq_i2c_response *response) |
---|
| 199 | + struct mrq_i2c_response *response, |
---|
| 200 | + bool atomic) |
---|
211 | 201 | { |
---|
212 | 202 | struct tegra_bpmp_message msg; |
---|
213 | 203 | int err; |
---|
.. | .. |
---|
222 | 212 | msg.rx.data = response; |
---|
223 | 213 | msg.rx.size = sizeof(*response); |
---|
224 | 214 | |
---|
225 | | - if (irqs_disabled()) |
---|
| 215 | + if (atomic) |
---|
226 | 216 | err = tegra_bpmp_transfer_atomic(i2c->bpmp, &msg); |
---|
227 | 217 | else |
---|
228 | 218 | err = tegra_bpmp_transfer(i2c->bpmp, &msg); |
---|
.. | .. |
---|
230 | 220 | return err; |
---|
231 | 221 | } |
---|
232 | 222 | |
---|
233 | | -static int tegra_bpmp_i2c_xfer(struct i2c_adapter *adapter, |
---|
234 | | - struct i2c_msg *msgs, int num) |
---|
| 223 | +static int tegra_bpmp_i2c_xfer_common(struct i2c_adapter *adapter, |
---|
| 224 | + struct i2c_msg *msgs, int num, |
---|
| 225 | + bool atomic) |
---|
235 | 226 | { |
---|
236 | 227 | struct tegra_bpmp_i2c *i2c = i2c_get_adapdata(adapter); |
---|
237 | 228 | struct mrq_i2c_response response; |
---|
.. | .. |
---|
253 | 244 | return err; |
---|
254 | 245 | } |
---|
255 | 246 | |
---|
256 | | - err = tegra_bpmp_i2c_msg_xfer(i2c, &request, &response); |
---|
| 247 | + err = tegra_bpmp_i2c_msg_xfer(i2c, &request, &response, atomic); |
---|
257 | 248 | if (err < 0) { |
---|
258 | 249 | dev_err(i2c->dev, "failed to transfer message: %d\n", err); |
---|
259 | 250 | return err; |
---|
.. | .. |
---|
268 | 259 | return num; |
---|
269 | 260 | } |
---|
270 | 261 | |
---|
| 262 | +static int tegra_bpmp_i2c_xfer(struct i2c_adapter *adapter, |
---|
| 263 | + struct i2c_msg *msgs, int num) |
---|
| 264 | +{ |
---|
| 265 | + return tegra_bpmp_i2c_xfer_common(adapter, msgs, num, false); |
---|
| 266 | +} |
---|
| 267 | + |
---|
| 268 | +static int tegra_bpmp_i2c_xfer_atomic(struct i2c_adapter *adapter, |
---|
| 269 | + struct i2c_msg *msgs, int num) |
---|
| 270 | +{ |
---|
| 271 | + return tegra_bpmp_i2c_xfer_common(adapter, msgs, num, true); |
---|
| 272 | +} |
---|
| 273 | + |
---|
271 | 274 | static u32 tegra_bpmp_i2c_func(struct i2c_adapter *adapter) |
---|
272 | 275 | { |
---|
273 | 276 | return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR | |
---|
.. | .. |
---|
276 | 279 | |
---|
277 | 280 | static const struct i2c_algorithm tegra_bpmp_i2c_algo = { |
---|
278 | 281 | .master_xfer = tegra_bpmp_i2c_xfer, |
---|
| 282 | + .master_xfer_atomic = tegra_bpmp_i2c_xfer_atomic, |
---|
279 | 283 | .functionality = tegra_bpmp_i2c_func, |
---|
280 | 284 | }; |
---|
281 | 285 | |
---|