| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Pinctrl based I2C DeMultiplexer |
|---|
| 3 | 4 | * |
|---|
| 4 | 5 | * Copyright (C) 2015-16 by Wolfram Sang, Sang Engineering <wsa@sang-engineering.com> |
|---|
| 5 | 6 | * Copyright (C) 2015-16 by Renesas Electronics Corporation |
|---|
| 6 | | - * |
|---|
| 7 | | - * This program is free software; you can redistribute it and/or modify it |
|---|
| 8 | | - * under the terms of the GNU General Public License as published by the |
|---|
| 9 | | - * Free Software Foundation; version 2 of the License. |
|---|
| 10 | 7 | * |
|---|
| 11 | 8 | * See the bindings doc for DTS setup and the sysfs doc for usage information. |
|---|
| 12 | 9 | * (look for filenames containing 'i2c-demux-pinctrl' in Documentation/) |
|---|
| .. | .. |
|---|
| 99 | 96 | |
|---|
| 100 | 97 | /* Now fill out current adapter structure. cur_chan must be up to date */ |
|---|
| 101 | 98 | priv->algo.master_xfer = i2c_demux_master_xfer; |
|---|
| 99 | + if (adap->algo->master_xfer_atomic) |
|---|
| 100 | + priv->algo.master_xfer_atomic = i2c_demux_master_xfer; |
|---|
| 102 | 101 | priv->algo.functionality = i2c_demux_functionality; |
|---|
| 103 | 102 | |
|---|
| 104 | 103 | snprintf(priv->cur_adap.name, sizeof(priv->cur_adap.name), |
|---|
| .. | .. |
|---|
| 219 | 218 | return -EINVAL; |
|---|
| 220 | 219 | } |
|---|
| 221 | 220 | |
|---|
| 222 | | - priv = devm_kzalloc(&pdev->dev, sizeof(*priv) |
|---|
| 223 | | - + num_chan * sizeof(struct i2c_demux_pinctrl_chan), GFP_KERNEL); |
|---|
| 221 | + priv = devm_kzalloc(&pdev->dev, struct_size(priv, chan, num_chan), |
|---|
| 222 | + GFP_KERNEL); |
|---|
| 224 | 223 | |
|---|
| 225 | 224 | props = devm_kcalloc(&pdev->dev, num_chan, sizeof(*props), GFP_KERNEL); |
|---|
| 226 | 225 | |
|---|
| .. | .. |
|---|
| 262 | 261 | |
|---|
| 263 | 262 | err = device_create_file(&pdev->dev, &dev_attr_available_masters); |
|---|
| 264 | 263 | if (err) |
|---|
| 265 | | - goto err_rollback; |
|---|
| 264 | + goto err_rollback_activation; |
|---|
| 266 | 265 | |
|---|
| 267 | 266 | err = device_create_file(&pdev->dev, &dev_attr_current_master); |
|---|
| 268 | 267 | if (err) |
|---|
| .. | .. |
|---|
| 272 | 271 | |
|---|
| 273 | 272 | err_rollback_available: |
|---|
| 274 | 273 | device_remove_file(&pdev->dev, &dev_attr_available_masters); |
|---|
| 275 | | -err_rollback: |
|---|
| 274 | +err_rollback_activation: |
|---|
| 276 | 275 | i2c_demux_deactivate_master(priv); |
|---|
| 276 | +err_rollback: |
|---|
| 277 | 277 | for (j = 0; j < i; j++) { |
|---|
| 278 | 278 | of_node_put(priv->chan[j].parent_np); |
|---|
| 279 | 279 | of_changeset_destroy(&priv->chan[j].chgset); |
|---|