Skip to content

Commit

Permalink
drivers: dma_cavs: separate callbacks per channel
Browse files Browse the repository at this point in the history
Allow the application using DMA driver to register a callback for
a specific channel within the DMA device instead of one callback
per device.

Signed-off-by: Sathish Kuttan <[email protected]>
  • Loading branch information
Sathish Kuttan authored and nashif committed May 31, 2018
1 parent 29b7cdc commit 9a7538b
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 21 deletions.
36 changes: 19 additions & 17 deletions drivers/dma/dma_cavs.c
Original file line number Diff line number Diff line change
Expand Up @@ -86,27 +86,29 @@ static void dw_dma_isr(void *arg)
dw_write(dev_cfg->base, DW_CLEAR_TFR, status_tfr);

/* Dispatch ISRs for channels depending upon the bit set */
if (dev_data->dma_blkcallback) {
while (status_block) {
channel = find_lsb_set(status_block) - 1;
status_block &= ~(1 << channel);
while (status_block) {
channel = find_lsb_set(status_block) - 1;
status_block &= ~(1 << channel);
chan_data = &dev_data->chan[channel];

if (chan_data->dma_blkcallback) {

/* Ensure the linked list (chan_data->lli) is
* freed in the user callback function once
* all the blocks are transferred.
*/
dev_data->dma_blkcallback(dev, channel, 0);
chan_data->dma_blkcallback(dev, channel, 0);
}
}

if (dev_data->dma_tfrcallback) {
while (status_tfr) {
channel = find_lsb_set(status_tfr) - 1;
status_tfr &= ~(1 << channel);
chan_data = &dev_data->chan[channel];
k_free(chan_data->lli);
chan_data->lli = NULL;
dev_data->dma_tfrcallback(dev, channel, 0);
while (status_tfr) {
channel = find_lsb_set(status_tfr) - 1;
status_tfr &= ~(1 << channel);
chan_data = &dev_data->chan[channel];
k_free(chan_data->lli);
chan_data->lli = NULL;
if (chan_data->dma_tfrcallback) {
chan_data->dma_tfrcallback(dev, channel, 0);
}
}
}
Expand Down Expand Up @@ -250,9 +252,9 @@ static int dw_dma_config(struct device *dev, u32_t channel,
* at the end of each block.
*/
if (cfg->complete_callback_en) {
dev_data->dma_blkcallback = cfg->dma_callback;
chan_data->dma_blkcallback = cfg->dma_callback;
} else {
dev_data->dma_tfrcallback = cfg->dma_callback;
chan_data->dma_tfrcallback = cfg->dma_callback;
}

return 0;
Expand All @@ -270,11 +272,11 @@ static int dw_dma_transfer_start(struct device *dev, u32_t channel)

chan_data = &dev_data->chan[channel];

if (dev_data->dma_tfrcallback) {
if (chan_data->dma_tfrcallback) {
dw_write(dev_cfg->base, DW_MASK_TFR, INT_UNMASK(channel));
}

if (dev_data->dma_blkcallback) {
if (chan_data->dma_blkcallback) {
dw_write(dev_cfg->base, DW_MASK_BLOCK, INT_UNMASK(channel));
}

Expand Down
8 changes: 4 additions & 4 deletions drivers/dma/dma_cavs.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ struct dma_chan_data {
struct dw_lli2 *lli;
u32_t cfg_lo;
u32_t cfg_hi;
void (*dma_blkcallback)(struct device *dev, u32_t channel,
int error_code);
void (*dma_tfrcallback)(struct device *dev, u32_t channel,
int error_code);
};

#define DW_MAX_CHAN 8
Expand Down Expand Up @@ -111,10 +115,6 @@ struct dw_drv_plat_data {

/* Device run time data */
struct dw_dma_dev_data {
void (*dma_blkcallback)(struct device *dev, u32_t channel,
int error_code);
void (*dma_tfrcallback)(struct device *dev, u32_t channel,
int error_code);
struct dw_drv_plat_data *channel_data;
struct dma_chan_data chan[DW_MAX_CHAN];
};
Expand Down

0 comments on commit 9a7538b

Please sign in to comment.