static int tdm_fsl_remove(struct platform_device *ofdev) { struct tdm_priv *priv; int buf_size; struct tdm_adapter *adap; if (!ofdev) { pr_err("%s: Invalid handle\n", __func__); return -EINVAL; } priv = dev_get_drvdata(&ofdev->dev); adap = priv->adap; tdm_fsl_disable(priv->adap); tdm_fsl_stop(priv); tdm_del_adapter(priv->adap); dev_set_drvdata(&ofdev->dev, NULL); /* free the irqs and dispose their mapping */ free_irq(priv->tdm_err_intr, priv); free_irq(priv->dmac_done_intr, priv); irq_dispose_mapping(priv->tdm_err_intr); irq_dispose_mapping(priv->dmac_done_intr); iounmap(priv->tdm_regs); iounmap(priv->dmac_regs); /* free the buffers */ buf_size = TDM_BUF_SIZE(adap->adapt_cfg.num_ch, adap->adapt_cfg.slot_width, adap->adapt_cfg.num_frames); dma_free_coherent(priv->device, buf_size, priv->dma_input_vaddr, priv->dma_input_paddr); dma_free_coherent(priv->device, buf_size, priv->dma_output_vaddr, priv->dma_output_paddr); /* free the TCDs */ dma_free_coherent(priv->device, NUM_OF_TDM_BUF * TCD_BUFFER_SIZE, priv->dma_rx_tcd_vaddr, priv->dma_rx_tcd_paddr); dma_free_coherent(priv->device, NUM_OF_TDM_BUF * TCD_BUFFER_SIZE, priv->dma_tx_tcd_vaddr, priv->dma_tx_tcd_paddr); dev_set_drvdata(&ofdev->dev, NULL); kfree(priv); return 0; }
static int __devexit tdm_fsl_starlite_remove(struct of_device *ofdev) { struct tdm_priv *priv = dev_get_drvdata(&ofdev->dev); int buf_size; tdm_fsl_starlite_disable(priv->adap); tdm_fsl_starlite_stop(priv); tdm_del_adapter(priv->adap); dev_set_drvdata(&ofdev->dev, NULL); /* free the irqs and dispose their mapping */ free_irq(priv->tdm_err_intr, priv); free_irq(priv->dmac_done_intr, priv); irq_dispose_mapping(priv->tdm_err_intr); irq_dispose_mapping(priv->dmac_done_intr); iounmap(priv->tdm_regs); iounmap(priv->dmac_regs); /* free the buffers */ buf_size = TDM_BUF_SIZE(priv->cfg.num_ch, priv->cfg.ch_width, priv->cfg.num_frames); dma_free_coherent(priv->device, buf_size, priv->dma_input_vaddr, priv->dma_input_paddr); dma_free_coherent(priv->device, buf_size, priv->dma_output_vaddr, priv->dma_output_paddr); /* free the TCDs */ dma_free_coherent(priv->device, NUM_OF_TDM_BUF * TCD_BUFFER_SIZE, priv->dma_rx_tcd_vaddr, priv->dma_rx_tcd_paddr); dma_free_coherent(priv->device, NUM_OF_TDM_BUF * TCD_BUFFER_SIZE, priv->dma_tx_tcd_vaddr, priv->dma_tx_tcd_paddr); dev_set_drvdata(&ofdev->dev, NULL); kfree(priv); return 0; }
static int init_tdm(struct tdm_priv *priv) { u8 *buf; int i; int buf_size; dma_addr_t physaddr = 0; int ret = 0; /* Allocate memory for Rx/Tx buffer according to active time slots BufferSize = NUM_OF_TDM_BUF*NUM_OF_FRAMES*Active_CH */ buf_size = TDM_BUF_SIZE(priv->cfg.num_ch, priv->cfg.ch_width, priv->cfg.num_frames); buf = dma_alloc_coherent(priv->device, buf_size, &physaddr, GFP_KERNEL); if (!buf) { ret = -ENOMEM; goto err_alloc_ip; } priv->dma_input_paddr = physaddr; priv->dma_input_vaddr = buf; priv->tdm_input_data = ALIGN_ADDRESS(buf, ALIGNED_8_BYTES); buf = dma_alloc_coherent(priv->device, buf_size, &physaddr, GFP_KERNEL); if (!buf) { ret = -ENOMEM; goto err_alloc_op; } priv->dma_output_paddr = physaddr; priv->dma_output_vaddr = buf; priv->tdm_output_data = ALIGN_ADDRESS(buf, ALIGNED_8_BYTES); /* allocate memory for TCD buffer discriptors */ buf = dma_alloc_coherent(priv->device, NUM_OF_TDM_BUF * TCD_BUFFER_SIZE, &physaddr, GFP_KERNEL); if (!buf) { ret = -ENOMEM; goto err_alloc_rx; } memset(buf, 0, NUM_OF_TDM_BUF * TCD_BUFFER_SIZE); priv->dma_rx_tcd_paddr = physaddr; priv->dma_rx_tcd_vaddr = buf; for (i = 0; i < NUM_OF_TDM_BUF; i++) { priv->dma_rx_tcd[i] = ALIGN_ADDRESS(buf, ALIGNED_32_BYTES); buf += TCD_BUFFER_SIZE; } buf = dma_alloc_coherent(priv->device, 3 * TCD_BUFFER_SIZE, &physaddr, GFP_KERNEL); if (!buf) { ret = -ENOMEM; goto err_alloc_tx; } memset(buf, 0, NUM_OF_TDM_BUF * TCD_BUFFER_SIZE); priv->dma_tx_tcd_paddr = physaddr; priv->dma_tx_tcd_vaddr = buf; for (i = 0; i < NUM_OF_TDM_BUF; i++) { priv->dma_tx_tcd[i] = ALIGN_ADDRESS(buf, ALIGNED_32_BYTES); buf += TCD_BUFFER_SIZE; } priv->phase_rx = 0; priv->phase_tx = 0; return 0; err_alloc_tx: dma_free_coherent(priv->device, NUM_OF_TDM_BUF * TCD_BUFFER_SIZE, priv->dma_rx_tcd_vaddr, priv->dma_rx_tcd_paddr); err_alloc_rx: dma_free_coherent(priv->device, buf_size, priv->dma_output_vaddr, priv->dma_output_paddr); err_alloc_op: dma_free_coherent(priv->device, buf_size, priv->dma_input_vaddr, priv->dma_input_paddr); err_alloc_ip: return ret; }
static int init_tdm(struct tdm_priv *priv) { u8 *buf; int i; int buf_size; dma_addr_t physaddr = 0; int ret = 0; struct tdm_adapter *adap; if (!priv) { pr_err("%s: Invalid handle\n", __func__); return -EINVAL; } adap = priv->adap; /* Allocate memory for Rx/Tx buffer according to active time slots BufferSize = NUM_OF_TDM_BUF * NUM_SAMPLES_PER_FRAME * slot_width * num_ch */ /*Allocating Rx Buffer*/ buf_size = TDM_BUF_SIZE(adap->adapt_cfg.num_ch, adap->adapt_cfg.slot_width, adap->adapt_cfg.num_frames); buf = dma_alloc_coherent(priv->device, buf_size, &physaddr, GFP_KERNEL); if (!buf) { ret = -ENOMEM; goto err_alloc_ip; } priv->dma_input_paddr = physaddr; priv->dma_input_vaddr = buf; priv->tdm_input_data = ALIGN_ADDRESS(buf, ALIGNED_8_BYTES); /*Allocating Tx Buffer*/ buf = dma_alloc_coherent(priv->device, buf_size, &physaddr, GFP_KERNEL); if (!buf) { ret = -ENOMEM; goto err_alloc_op; } priv->dma_output_paddr = physaddr; priv->dma_output_vaddr = buf; priv->tdm_output_data = ALIGN_ADDRESS(buf, ALIGNED_8_BYTES); /* allocate memory for TCD buffer discriptors */ buf = dma_alloc_coherent(priv->device, NUM_OF_TDM_BUF * TCD_BUFFER_SIZE, &physaddr, GFP_KERNEL); if (!buf) { ret = -ENOMEM; goto err_alloc_rx; } memset(buf, 0, NUM_OF_TDM_BUF * TCD_BUFFER_SIZE); priv->dma_rx_tcd_paddr = physaddr; priv->dma_rx_tcd_vaddr = buf; for (i = 0; i < NUM_OF_TDM_BUF; i++) { priv->dma_rx_tcd[i] = ALIGN_ADDRESS(buf, ALIGNED_32_BYTES); buf += TCD_BUFFER_SIZE; } buf = dma_alloc_coherent(priv->device, 3 * TCD_BUFFER_SIZE, &physaddr, GFP_KERNEL); if (!buf) { ret = -ENOMEM; goto err_alloc_tx; } memset(buf, 0, NUM_OF_TDM_BUF * TCD_BUFFER_SIZE); priv->dma_tx_tcd_paddr = physaddr; priv->dma_tx_tcd_vaddr = buf; for (i = 0; i < NUM_OF_TDM_BUF; i++) { priv->dma_tx_tcd[i] = ALIGN_ADDRESS(buf, ALIGNED_32_BYTES); buf += TCD_BUFFER_SIZE; } priv->phase_rx = 0; priv->phase_tx = 0; return 0; err_alloc_tx: dma_free_coherent(priv->device, NUM_OF_TDM_BUF * TCD_BUFFER_SIZE, priv->dma_rx_tcd_vaddr, priv->dma_rx_tcd_paddr); err_alloc_rx: dma_free_coherent(priv->device, buf_size, priv->dma_output_vaddr, priv->dma_output_paddr); err_alloc_op: dma_free_coherent(priv->device, buf_size, priv->dma_input_vaddr, priv->dma_input_paddr); err_alloc_ip: return ret; }