/** * sw_dma_request - request a dma channel * @name: dma channel name * @type: channel type, normal or dedicate * * Returns handle to the channel if success, NULL if failed. */ dma_hdl_t sw_dma_request(char * name, dma_chan_type_e type) { u32 i, num; u32 usign = 0; dma_channel_t *pchan = NULL; DMA_DBG("%s: name %s, chan type %d\n", __func__, name, (u32)type); if((name && strlen(name) >= MAX_NAME_LEN) || (type != CHAN_NORMAL && type != CHAN_DEDICATE)) { DMA_ERR("%s: para err, name %s, type %d\n", __func__, name, (u32)type); return NULL; } mutex_lock(&dma_mutex); /* check if already exist */ if(NULL != name && __dma_channel_already_exist(name)) { usign = __LINE__; goto end; } /* get a free channel */ if(CHAN_NORMAL == type) i = 0; else i = 8; num = i + 8; for(; i < num ; i++) { if(0 == g_dma_mgr.chnl[i].used) { WARN_ON(!__chan_is_free(&g_dma_mgr.chnl[i])); break; } } if(num == i) { usign = __LINE__; goto end; } /* init channel */ pchan = &g_dma_mgr.chnl[i]; pchan->used = 1; dma_request_init(pchan); if(NULL != name) strcpy(pchan->owner, name); end: mutex_unlock(&dma_mutex); if(0 != usign) DMA_ERR("%s err, line %d\n", __func__, usign); else DMA_DBG("%s: success, channel id %d\n", __func__, i); return (dma_hdl_t)pchan; }
/** * sw_dma_request - request a dma channel * @name: dma channel name * * Returns handle to the channel if success, NULL if failed. */ dm_hdl_t sw_dma_request(char *name, enum dma_work_mode_e work_mode) { u32 i = 0; u32 usign = 0; dma_channel_t *pchan = NULL; DMA_DBG("%s: name %s, work_mode %d\n", __func__, name, (u32)work_mode); if(strlen(name) >= MAX_OWNER_NAME_LEN || (work_mode != DMA_WORK_MODE_CHAIN && work_mode != DMA_WORK_MODE_SINGLE)) { DMA_ERR("%s: para err, name %s, work mode %d\n", __func__, name, (u32)work_mode); return NULL; } mutex_lock(&dma_mutex); /* check if already exist */ if(NULL != name && __dma_channel_already_exist(name)) { usign = __LINE__; goto end; } /* get a free channel */ for(i = 0; i < DMA_CHAN_TOTAL; i++) { pchan = &dma_chnl[i]; if(0 == pchan->used) { #ifdef DBG_DMA if(true != __dma_check_channel_free(pchan)) DMA_ERR("%s(%d) err, channel is not free\n", __func__, __LINE__); #endif /* DBG_DMA */ break; } } /* cannot get a free channel */ if(DMA_CHAN_TOTAL == i) { usign = __LINE__; goto end; } /* init channel */ if(DMA_WORK_MODE_CHAIN == work_mode) { dma_request_init_chain(pchan); } else if(DMA_WORK_MODE_SINGLE == work_mode) { dma_request_init_single(pchan); #ifdef NOT_ALLOC_DES_TEMP v_addr = (u32)dma_alloc_coherent(NULL, TEMP_DES_CNT * sizeof(des_item), (dma_addr_t *)&p_addr, GFP_KERNEL); if(0 == v_addr) printk("%s err, dma_alloc_coherent failed, line %d\n", __func__, __LINE__); else printk("%s: dma_alloc_coherent return v_addr 0x%08x, p_addr 0x%08x\n", __func__, v_addr, p_addr); index_get = 0; index_put = 0; #endif /* NOT_ALLOC_DES_TEMP */ } pchan->used = 1; if(NULL != name) strcpy(pchan->owner, name); pchan->work_mode = work_mode; end: mutex_unlock(&dma_mutex); if(0 != usign) { DMA_ERR("%s err, line %d\n", __func__, usign); return (dm_hdl_t)NULL; } else { DMA_DBG("%s: success, channel id %d\n", __func__, i); return (dm_hdl_t)pchan; } }