static int imxmci_finish_data(struct imxmci_host *host, unsigned int stat) { struct mmc_data *data = host->data; int data_error; if(test_and_clear_bit(IMXMCI_PEND_DMA_DATA_b, &host->pending_events)){ imx_dma_disable(host->dma); dma_unmap_sg(mmc_dev(host->mmc), data->sg, host->dma_nents, host->dma_dir); } if ( stat & STATUS_ERR_MASK ) { dev_dbg(mmc_dev(host->mmc), "request failed. status: 0x%08x\n",stat); if(stat & (STATUS_CRC_READ_ERR | STATUS_CRC_WRITE_ERR)) data->error = MMC_ERR_BADCRC; else if(stat & STATUS_TIME_OUT_READ) data->error = MMC_ERR_TIMEOUT; else data->error = MMC_ERR_FAILED; } else { data->bytes_xfered = host->dma_size; } data_error = data->error; host->data = NULL; return data_error; }
static void mx1_camera_dma_irq(int channel, void *data) { struct mx1_camera_dev *pcdev = data; struct device *dev = pcdev->soc_host.icd->parent; struct mx1_buffer *buf; struct videobuf_buffer *vb; unsigned long flags; spin_lock_irqsave(&pcdev->lock, flags); imx_dma_disable(channel); if (unlikely(!pcdev->active)) { dev_err(dev, "DMA End IRQ with no active buffer\n"); goto out; } vb = &pcdev->active->vb; buf = container_of(vb, struct mx1_buffer, vb); WARN_ON(buf->inwork || list_empty(&vb->queue)); dev_dbg(dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__, vb, vb->baddr, vb->bsize); mx1_camera_wakeup(pcdev, vb, buf); out: spin_unlock_irqrestore(&pcdev->lock, flags); }
static void snd_imx_dma_err_callback(int channel, void *data, int err) { struct snd_pcm_substream *substream = data; struct snd_soc_pcm_runtime *rtd = substream->private_data; struct imx_pcm_dma_params *dma_params = snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream); struct snd_pcm_runtime *runtime = substream->runtime; struct imx_pcm_runtime_data *iprtd = runtime->private_data; int ret; pr_err("DMA timeout on channel %d -%s%s%s%s\n", channel, err & IMX_DMA_ERR_BURST ? " burst" : "", err & IMX_DMA_ERR_REQUEST ? " request" : "", err & IMX_DMA_ERR_TRANSFER ? " transfer" : "", err & IMX_DMA_ERR_BUFFER ? " buffer" : ""); imx_dma_disable(iprtd->dma); ret = imx_dma_setup_sg(iprtd->dma, iprtd->sg_list, iprtd->sg_count, IMX_DMA_LENGTH_LOOP, dma_params->dma_addr, substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? DMA_MODE_WRITE : DMA_MODE_READ); if (!ret) imx_dma_enable(iprtd->dma); }
static int snd_imx_pcm_trigger(struct snd_pcm_substream *substream, int cmd) { struct snd_pcm_runtime *runtime = substream->runtime; struct imx_pcm_runtime_data *iprtd = runtime->private_data; switch (cmd) { case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_RESUME: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: imx_dma_enable(iprtd->dma); break; case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_PAUSE_PUSH: imx_dma_disable(iprtd->dma); break; default: return -EINVAL; } return 0; }
static void mx1_camera_clock_stop(struct soc_camera_host *ici) { struct mx1_camera_dev *pcdev = ici->priv; unsigned int csicr1; /* disable interrupts */ csicr1 = __raw_readl(pcdev->base + CSICR1) & ~CSI_IRQ_MASK; __raw_writel(csicr1, pcdev->base + CSICR1); /* Stop DMA engine */ imx_dma_disable(pcdev->dma_chan); mx1_camera_deactivate(pcdev); }
/* Called by the DMA framework when an error has occured */ static void dma_test_err_handler(int channel, void *data, int err) { printk("%s %d %d\n", __func__, channel, err); printk("DMA timeout on channel %d -%s%s%s%s%s\n", channel, err & IMX_DMA_ERR_BURST ? " burst":"", err & IMX_DMA_ERR_REQUEST ? " request":"", err & IMX_DMA_ERR_TRANSFER ? " transfer":"", err & IMX_DMA_ERR_BUFFER ? " buffer":"", err & IMX_DMA_ERR_TIMEOUT ? " hw_chain_watchdog":""); imx_dma_disable(channel); }
static void mx1_camera_remove_device(struct soc_camera_device *icd) { struct soc_camera_host *ici = to_soc_camera_host(icd->parent); struct mx1_camera_dev *pcdev = ici->priv; unsigned int csicr1; /* disable interrupts */ csicr1 = __raw_readl(pcdev->base + CSICR1) & ~CSI_IRQ_MASK; __raw_writel(csicr1, pcdev->base + CSICR1); /* Stop DMA engine */ imx_dma_disable(pcdev->dma_chan); dev_info(icd->parent, "MX1 Camera driver detached from camera %d\n", icd->devnum); mx1_camera_deactivate(pcdev); }
/* configure DMA channel of a given substream */ static int dma_request(void) { int err=0, chan=0; chan = imx_dma_request_by_prio(DRIVER_NAME, DMA_PRIO_HIGH); if (chan < 0) { printk(KERN_ERR "Unable to grab a DMA channel\n"); err = chan; goto on_error_1; } err = imx_dma_setup_handlers(chan, dma_test_callback, dma_test_err_handler, NULL /* private data comes here */); if (err < 0) { printk(KERN_ERR "Unable to setup DMA handler for channel %d\n", chan); err = -EIO; goto on_error_2; } /* err = imx_dma_setup_progression_handler(chan, dma_test_progression); if (err != 0) { pr_err("Failed to setup the DMA progression handler\n"); err = -EIO; goto on_error_2; } */ printk("DMA channel %d setup\n", chan); imx_dma_disable(chan); return chan; on_error_2: imx_dma_free(chan); on_error_1: return err; }