| .. | .. |
|---|
| 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 | |
|---|