common: bouncebuf: Permit passing custom alignment check function

Add extended version of the bounce_buffer_start(), which permits passing in
a custom alignment checker function for the buffer. This is useful e.g. on
systems with various DMA restrictions and where the checker function might
be more complex than a simple CPU cache alignment check.

Signed-off-by: Marek Vasut <marek.vasut+renesas@gmail.com>
Cc: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
Cc: Masahiro Yamada <yamada.masahiro@socionext.com>
Cc: Peng Fan <peng.fan@nxp.com>
Cc: Simon Glass <sjg@chromium.org>
Cc: Tom Rini <trini@konsulko.com>
This commit is contained in:
Marek Vasut 2020-04-04 12:45:02 +02:00 committed by Peng Fan
parent 453d21381b
commit 8074ffe335
2 changed files with 30 additions and 5 deletions

View file

@ -31,17 +31,19 @@ static int addr_aligned(struct bounce_buffer *state)
return 1; return 1;
} }
int bounce_buffer_start(struct bounce_buffer *state, void *data, int bounce_buffer_start_extalign(struct bounce_buffer *state, void *data,
size_t len, unsigned int flags) size_t len, unsigned int flags,
size_t alignment,
int (*addr_is_aligned)(struct bounce_buffer *state))
{ {
state->user_buffer = data; state->user_buffer = data;
state->bounce_buffer = data; state->bounce_buffer = data;
state->len = len; state->len = len;
state->len_aligned = roundup(len, ARCH_DMA_MINALIGN); state->len_aligned = roundup(len, alignment);
state->flags = flags; state->flags = flags;
if (!addr_aligned(state)) { if (!addr_is_aligned(state)) {
state->bounce_buffer = memalign(ARCH_DMA_MINALIGN, state->bounce_buffer = memalign(alignment,
state->len_aligned); state->len_aligned);
if (!state->bounce_buffer) if (!state->bounce_buffer)
return -ENOMEM; return -ENOMEM;
@ -62,6 +64,14 @@ int bounce_buffer_start(struct bounce_buffer *state, void *data,
return 0; return 0;
} }
int bounce_buffer_start(struct bounce_buffer *state, void *data,
size_t len, unsigned int flags)
{
return bounce_buffer_start_extalign(state, data, len, flags,
ARCH_DMA_MINALIGN,
addr_aligned);
}
int bounce_buffer_stop(struct bounce_buffer *state) int bounce_buffer_stop(struct bounce_buffer *state)
{ {
if (state->flags & GEN_BB_WRITE) { if (state->flags & GEN_BB_WRITE) {

View file

@ -62,6 +62,21 @@ struct bounce_buffer {
*/ */
int bounce_buffer_start(struct bounce_buffer *state, void *data, int bounce_buffer_start(struct bounce_buffer *state, void *data,
size_t len, unsigned int flags); size_t len, unsigned int flags);
/**
* bounce_buffer_start() -- Start the bounce buffer session with external align check function
* state: stores state passed between bounce_buffer_{start,stop}
* data: pointer to buffer to be aligned
* len: length of the buffer
* flags: flags describing the transaction, see above.
* alignment: alignment of the newly allocated bounce buffer
* addr_is_aligned: function for checking the alignment instead of the default one
*/
int bounce_buffer_start_extalign(struct bounce_buffer *state, void *data,
size_t len, unsigned int flags,
size_t alignment,
int (*addr_is_aligned)(struct bounce_buffer *state));
/** /**
* bounce_buffer_stop() -- Finish the bounce buffer session * bounce_buffer_stop() -- Finish the bounce buffer session
* state: stores state passed between bounce_buffer_{start,stop} * state: stores state passed between bounce_buffer_{start,stop}