if (sync)
sst->ops->post_message(sst, msg, true); else
sst_add_to_dispatch_list_and_post(sst, msg);
if (response) {
ret = sst_wait_timeout(sst, block); if (ret < 0) goto out;
if (data && block->data) {
*data = kmemdup(block->data, block->size, GFP_KERNEL); if (!*data) {
ret = -ENOMEM; goto out;
}
}
}
out: if (response)
sst_free_block(sst, block);
test_and_clear_bit(pvt_id, &sst->pvt_id); return ret;
}
int sst_pm_runtime_put(struct intel_sst_drv *sst_drv)
{ int ret;
ret = pm_runtime_put_autosuspend(sst_drv->dev); if (ret < 0) return ret; return0;
}
void sst_fill_header_mrfld(union ipc_header_mrfld *header, int msg, int task_id, int large, int drv_id)
{
header->full = 0;
header->p.header_high.part.msg_id = msg;
header->p.header_high.part.task_id = task_id;
header->p.header_high.part.large = large;
header->p.header_high.part.drv_id = drv_id;
header->p.header_high.part.done = 0;
header->p.header_high.part.busy = 1;
header->p.header_high.part.res_rqd = 1;
}
void sst_fill_header_dsp(struct ipc_dsp_hdr *dsp, int msg, int pipe_id, int len)
{
dsp->cmd_id = msg;
dsp->mod_index_id = 0xff;
dsp->pipe_id = pipe_id;
dsp->length = len;
dsp->mod_id = 0;
}
#define SST_MAX_BLOCKS 15 /* *sst_assign_pvt_id-assignapvtidforstream * *@sst_drv_ctx:drivercontext * *thisfunctionassignsaprivateidforcallsthatdonthavestream *contextyet,shouldbecalledwithlockheld *usesbitsfortheid,andfindsfirstfreebitsandassignsthat
*/ int sst_assign_pvt_id(struct intel_sst_drv *drv)
{ int local;
spin_lock(&drv->block_lock); /* find first zero index from lsb */
local = ffz(drv->pvt_id);
dev_dbg(drv->dev, "pvt_id assigned --> %d\n", local); if (local >= SST_MAX_BLOCKS){
spin_unlock(&drv->block_lock);
dev_err(drv->dev, "PVT _ID error: no free id blocks "); return -EINVAL;
} /* toggle the index */
change_bit(local, &drv->pvt_id);
spin_unlock(&drv->block_lock); return local;
}
int sst_validate_strid( struct intel_sst_drv *sst_drv_ctx, int str_id)
{ if (str_id <= 0 || str_id > sst_drv_ctx->info.max_streams) {
dev_err(sst_drv_ctx->dev, "SST ERR: invalid stream id : %d, max %d\n",
str_id, sst_drv_ctx->info.max_streams); return -EINVAL;
}
return0;
}
struct stream_info *get_stream_info( struct intel_sst_drv *sst_drv_ctx, int str_id)
{ if (sst_validate_strid(sst_drv_ctx, str_id)) return NULL; return &sst_drv_ctx->streams[str_id];
}
int get_stream_id_mrfld(struct intel_sst_drv *sst_drv_ctx,
u32 pipe_id)
{ int i;
for (i = 1; i <= sst_drv_ctx->info.max_streams; i++) if (pipe_id == sst_drv_ctx->streams[i].pipe_id) return i;
dev_dbg(sst_drv_ctx->dev, "no such pipe_id(%u)", pipe_id); return -1;
}
u32 relocate_imr_addr_mrfld(u32 base_addr)
{ /* Get the difference from 512MB aligned base addr */ /* relocate the base */
base_addr = MRFLD_FW_VIRTUAL_BASE + (base_addr % (512 * 1024 * 1024)); return base_addr;
}
EXPORT_SYMBOL_GPL(relocate_imr_addr_mrfld);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.