Skip to content

Commit

Permalink
i2c: refactor function to release a DMA safe buffer
Browse files Browse the repository at this point in the history
a) rename to 'put' instead of 'release' to match 'get' when obtaining
   the buffer
b) change the argument order to have the buffer as first argument
c) add a new argument telling the function if the message was
   transferred. This allows the function to be used also in cases
   where setting up DMA failed, so the buffer needs to be freed without
   syncing to the message buffer.

Also convert the only user.

Signed-off-by: Wolfram Sang <[email protected]>
Reviewed-by: Niklas Söderlund <[email protected]>
Signed-off-by: Wolfram Sang <[email protected]>
  • Loading branch information
Wolfram Sang authored and Wolfram Sang committed Aug 30, 2018
1 parent 1204d12 commit 82fe39a
Show file tree
Hide file tree
Showing 4 changed files with 15 additions and 10 deletions.
10 changes: 7 additions & 3 deletions Documentation/i2c/DMA-considerations
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,14 @@ bounce buffer. But you don't need to care about that detail, just use the
returned buffer. If NULL is returned, the threshold was not met or a bounce
buffer could not be allocated. Fall back to PIO in that case.

In any case, a buffer obtained from above needs to be released. It ensures data
is copied back to the message and a potentially used bounce buffer is freed::
In any case, a buffer obtained from above needs to be released. Another helper
function ensures a potentially used bounce buffer is freed::

i2c_release_dma_safe_msg_buf(msg, dma_buf);
i2c_put_dma_safe_msg_buf(dma_buf, msg, xferred);

The last argument 'xferred' controls if the buffer is synced back to the
message or not. No syncing is needed in cases setting up DMA had an error and
there was no data transferred.

The bounce buffer handling from the core is generic and simple. It will always
allocate a new bounce buffer. If you want a more sophisticated handling (e.g.
Expand Down
2 changes: 1 addition & 1 deletion drivers/i2c/busses/i2c-sh_mobile.c
Original file line number Diff line number Diff line change
Expand Up @@ -507,7 +507,7 @@ static void sh_mobile_i2c_dma_callback(void *data)
pd->pos = pd->msg->len;
pd->stop_after_dma = true;

i2c_release_dma_safe_msg_buf(pd->msg, pd->dma_buf);
i2c_put_dma_safe_msg_buf(pd->dma_buf, pd->msg, true);

iic_set_clr(pd, ICIC, 0, ICIC_TDMAE | ICIC_RDMAE);
}
Expand Down
11 changes: 6 additions & 5 deletions drivers/i2c/i2c-core-base.c
Original file line number Diff line number Diff line change
Expand Up @@ -2293,21 +2293,22 @@ u8 *i2c_get_dma_safe_msg_buf(struct i2c_msg *msg, unsigned int threshold)
EXPORT_SYMBOL_GPL(i2c_get_dma_safe_msg_buf);

/**
* i2c_release_dma_safe_msg_buf - release DMA safe buffer and sync with i2c_msg
* @msg: the message to be synced with
* i2c_put_dma_safe_msg_buf - release DMA safe buffer and sync with i2c_msg
* @buf: the buffer obtained from i2c_get_dma_safe_msg_buf(). May be NULL.
* @msg: the message which the buffer corresponds to
* @xferred: bool saying if the message was transferred
*/
void i2c_release_dma_safe_msg_buf(struct i2c_msg *msg, u8 *buf)
void i2c_put_dma_safe_msg_buf(u8 *buf, struct i2c_msg *msg, bool xferred)
{
if (!buf || buf == msg->buf)
return;

if (msg->flags & I2C_M_RD)
if (xferred && msg->flags & I2C_M_RD)
memcpy(msg->buf, buf, msg->len);

kfree(buf);
}
EXPORT_SYMBOL_GPL(i2c_release_dma_safe_msg_buf);
EXPORT_SYMBOL_GPL(i2c_put_dma_safe_msg_buf);

MODULE_AUTHOR("Simon G. Vogl <[email protected]>");
MODULE_DESCRIPTION("I2C-Bus main module");
Expand Down
2 changes: 1 addition & 1 deletion include/linux/i2c.h
Original file line number Diff line number Diff line change
Expand Up @@ -855,7 +855,7 @@ static inline u8 i2c_8bit_addr_from_msg(const struct i2c_msg *msg)
}

u8 *i2c_get_dma_safe_msg_buf(struct i2c_msg *msg, unsigned int threshold);
void i2c_release_dma_safe_msg_buf(struct i2c_msg *msg, u8 *buf);
void i2c_put_dma_safe_msg_buf(u8 *buf, struct i2c_msg *msg, bool xferred);

int i2c_handle_smbus_host_notify(struct i2c_adapter *adap, unsigned short addr);
/**
Expand Down

0 comments on commit 82fe39a

Please sign in to comment.