This patch adds the num_channels_busy member to the dma structure that stores the number of channels busy at any given time. This will be useful in providing basic and primitive QoS while allocating DMAC for various users.
Signed-off-by: Ranjani Sridharan ranjani.sridharan@linux.intel.com --- src/drivers/dw-dma.c | 9 +++++++++ src/drivers/hda-dma.c | 9 +++++++++ src/include/sof/dma.h | 1 + 3 files changed, 19 insertions(+)
diff --git a/src/drivers/dw-dma.c b/src/drivers/dw-dma.c index c064330..5c43656 100644 --- a/src/drivers/dw-dma.c +++ b/src/drivers/dw-dma.c @@ -307,6 +307,9 @@ static int dw_dma_channel_get(struct dma *dma, int req_chan) if (p->chan[i].status != COMP_STATE_INIT) continue;
+ /* atomically increment num channels in use */ + __sync_fetch_and_add(&dma->num_channels_busy, 1); + p->chan[i].status = COMP_STATE_READY;
/* unmask block, transfer and error interrupts for channel */ @@ -357,6 +360,9 @@ static void dw_dma_channel_put(struct dma *dma, int channel) spin_lock_irq(&dma->lock, flags); dw_dma_channel_put_unlocked(dma, channel); spin_unlock_irq(&dma->lock, flags); + + /* atomically decrement num channels in use */ + __sync_fetch_and_sub(&dma->num_channels_busy, 1); }
static int dw_dma_start(struct dma *dma, int channel) @@ -1033,6 +1039,9 @@ static int dw_dma_probe(struct dma *dma) interrupt_enable(dma_int[i]->irq); }
+ /* initialize number of busy channels */ + dma->num_channels_busy = 0; + return 0; }
diff --git a/src/drivers/hda-dma.c b/src/drivers/hda-dma.c index 97ea0ef..731d4a9 100644 --- a/src/drivers/hda-dma.c +++ b/src/drivers/hda-dma.c @@ -145,6 +145,9 @@ static int hda_dma_channel_get(struct dma *dma, int channel) if (p->chan[channel].status == COMP_STATE_INIT) { p->chan[channel].status = COMP_STATE_READY;
+ /* atomically increment num channels in use */ + __sync_fetch_and_add(&dma->num_channels_busy, 1); + /* return channel */ spin_unlock_irq(&dma->lock, flags); return channel; @@ -163,6 +166,9 @@ static void hda_dma_channel_put_unlocked(struct dma *dma, int channel)
/* set new state */ p->chan[channel].status = COMP_STATE_INIT; + + /* atomically decrement num channels in use */ + __sync_fetch_and_sub(&dma->num_channels_busy, 1); }
/* channel must not be running when this is called */ @@ -400,6 +406,9 @@ static int hda_dma_probe(struct dma *dma) for (i = 0; i < HDA_DMA_MAX_CHANS; i++) hda_pdata->chan[i].status = COMP_STATE_INIT;
+ /* init number of busy channels */ + dma->num_channels_busy = 0; + return 0; }
diff --git a/src/include/sof/dma.h b/src/include/sof/dma.h index 142aafc..2ae4225 100644 --- a/src/include/sof/dma.h +++ b/src/include/sof/dma.h @@ -137,6 +137,7 @@ struct dma { struct dma_plat_data plat_data; spinlock_t lock; const struct dma_ops *ops; + uint32_t num_channels_busy; /* number of channels in use */ void *private; };