static int __exit mx1_camera_remove(struct platform_device *pdev) { struct soc_camera_host *soc_host = to_soc_camera_host(&pdev->dev); struct mx1_camera_dev *pcdev = container_of(soc_host, struct mx1_camera_dev, soc_host); struct resource *res; imx_dma_free(pcdev->dma_chan); disable_fiq(pcdev->irq); mxc_set_irq_fiq(pcdev->irq, 0); release_fiq(&fh); clk_put(pcdev->clk); soc_camera_host_unregister(soc_host); iounmap(pcdev->base); res = pcdev->res; release_mem_region(res->start, resource_size(res)); kfree(pcdev); dev_info(&pdev->dev, "MX1 Camera driver unloaded\n"); return 0; }
static int imxmci_remove(struct platform_device *pdev) { struct mmc_host *mmc = platform_get_drvdata(pdev); platform_set_drvdata(pdev, NULL); if (mmc) { struct imxmci_host *host = mmc_priv(mmc); tasklet_disable(&host->tasklet); del_timer_sync(&host->timer); mmc_remove_host(mmc); free_irq(host->irq, host); if(host->dma_allocated){ imx_dma_free(host->dma); host->dma_allocated=0; } tasklet_kill(&host->tasklet); release_resource(host->res); mmc_free_host(mmc); } return 0; }
static int snd_imx_pcm_hw_free(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; struct imx_pcm_runtime_data *iprtd = runtime->private_data; if (iprtd->dma >= 0) { imx_dma_free(iprtd->dma); iprtd->dma = -EINVAL; } kfree(iprtd->sg_list); iprtd->sg_list = NULL; return 0; }
static int imx_ssi_dma_alloc(struct snd_pcm_substream *substream) { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct imx_pcm_dma_params *dma_params; struct snd_pcm_runtime *runtime = substream->runtime; struct imx_pcm_runtime_data *iprtd = runtime->private_data; int ret; dma_params = snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream); iprtd->dma = imx_dma_request_by_prio(DRV_NAME, DMA_PRIO_HIGH); if (iprtd->dma < 0) { pr_err("Failed to claim the audio DMA\n"); return -ENODEV; } ret = imx_dma_setup_handlers(iprtd->dma, imx_ssi_dma_callback, snd_imx_dma_err_callback, substream); if (ret) goto out; ret = imx_dma_setup_progression_handler(iprtd->dma, imx_ssi_dma_progression); if (ret) { pr_err("Failed to setup the DMA handler\n"); goto out; } ret = imx_dma_config_channel(iprtd->dma, IMX_DMA_MEMSIZE_16 | IMX_DMA_TYPE_FIFO, IMX_DMA_MEMSIZE_32 | IMX_DMA_TYPE_LINEAR, dma_params->dma, 1); if (ret < 0) { pr_err("Cannot configure DMA channel: %d\n", ret); goto out; } imx_dma_config_burstlen(iprtd->dma, dma_params->burstsize * 2); return 0; out: imx_dma_free(iprtd->dma); return ret; }
static int __devinit mx27_camera_dma_init(struct platform_device *pdev, struct mx2_camera_dev *pcdev) { int err; pcdev->dma = imx_dma_request_by_prio("CSI RX DMA", DMA_PRIO_HIGH); if (pcdev->dma < 0) { dev_err(&pdev->dev, "%s failed to request DMA channel\n", __func__); return pcdev->dma; } err = imx_dma_setup_handlers(pcdev->dma, mx27_camera_dma_callback, mx27_camera_dma_err_callback, pcdev); if (err) { dev_err(&pdev->dev, "%s failed to set DMA callback\n", __func__); goto err_out; } err = imx_dma_config_channel(pcdev->dma, IMX_DMA_MEMSIZE_32 | IMX_DMA_TYPE_FIFO, IMX_DMA_MEMSIZE_32 | IMX_DMA_TYPE_LINEAR, DMA_REQ_CSI_RX, 1); if (err) { dev_err(&pdev->dev, "%s failed to config DMA channel\n", __func__); goto err_out; } imx_dma_config_burstlen(pcdev->dma, 64); return 0; err_out: imx_dma_free(pcdev->dma); return err; }
/* 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; }
static int __init mx1_camera_probe(struct platform_device *pdev) { struct mx1_camera_dev *pcdev; struct resource *res; struct pt_regs regs; struct clk *clk; void __iomem *base; unsigned int irq; int err = 0; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); irq = platform_get_irq(pdev, 0); if (!res || (int)irq <= 0) { err = -ENODEV; goto exit; } clk = clk_get(&pdev->dev, "csi_clk"); if (IS_ERR(clk)) { err = PTR_ERR(clk); goto exit; } pcdev = kzalloc(sizeof(*pcdev), GFP_KERNEL); if (!pcdev) { dev_err(&pdev->dev, "Could not allocate pcdev\n"); err = -ENOMEM; goto exit_put_clk; } pcdev->res = res; pcdev->clk = clk; pcdev->pdata = pdev->dev.platform_data; if (pcdev->pdata) pcdev->mclk = pcdev->pdata->mclk_10khz * 10000; if (!pcdev->mclk) { dev_warn(&pdev->dev, "mclk_10khz == 0! Please, fix your platform data. " "Using default 20MHz\n"); pcdev->mclk = 20000000; } INIT_LIST_HEAD(&pcdev->capture); spin_lock_init(&pcdev->lock); /* * Request the regions. */ if (!request_mem_region(res->start, resource_size(res), DRIVER_NAME)) { err = -EBUSY; goto exit_kfree; } base = ioremap(res->start, resource_size(res)); if (!base) { err = -ENOMEM; goto exit_release; } pcdev->irq = irq; pcdev->base = base; /* request dma */ pcdev->dma_chan = imx_dma_request_by_prio(DRIVER_NAME, DMA_PRIO_HIGH); if (pcdev->dma_chan < 0) { dev_err(&pdev->dev, "Can't request DMA for MX1 CSI\n"); err = -EBUSY; goto exit_iounmap; } dev_dbg(&pdev->dev, "got DMA channel %d\n", pcdev->dma_chan); imx_dma_setup_handlers(pcdev->dma_chan, mx1_camera_dma_irq, NULL, pcdev); imx_dma_config_channel(pcdev->dma_chan, IMX_DMA_TYPE_FIFO, IMX_DMA_MEMSIZE_32, MX1_DMA_REQ_CSI_R, 0); /* burst length : 16 words = 64 bytes */ imx_dma_config_burstlen(pcdev->dma_chan, 0); /* request irq */ err = claim_fiq(&fh); if (err) { dev_err(&pdev->dev, "Camera interrupt register failed\n"); goto exit_free_dma; } set_fiq_handler(&mx1_camera_sof_fiq_start, &mx1_camera_sof_fiq_end - &mx1_camera_sof_fiq_start); regs.ARM_r8 = (long)MX1_DMA_DIMR; regs.ARM_r9 = (long)MX1_DMA_CCR(pcdev->dma_chan); regs.ARM_r10 = (long)pcdev->base + CSICR1; regs.ARM_fp = (long)pcdev->base + CSISR; regs.ARM_sp = 1 << pcdev->dma_chan; set_fiq_regs(®s); mxc_set_irq_fiq(irq, 1); enable_fiq(irq); pcdev->soc_host.drv_name = DRIVER_NAME; pcdev->soc_host.ops = &mx1_soc_camera_host_ops; pcdev->soc_host.priv = pcdev; pcdev->soc_host.v4l2_dev.dev = &pdev->dev; pcdev->soc_host.nr = pdev->id; err = soc_camera_host_register(&pcdev->soc_host); if (err) goto exit_free_irq; dev_info(&pdev->dev, "MX1 Camera driver loaded\n"); return 0; exit_free_irq: disable_fiq(irq); mxc_set_irq_fiq(irq, 0); release_fiq(&fh); exit_free_dma: imx_dma_free(pcdev->dma_chan); exit_iounmap: iounmap(base); exit_release: release_mem_region(res->start, resource_size(res)); exit_kfree: kfree(pcdev); exit_put_clk: clk_put(clk); exit: return err; }
static int imxmci_probe(struct platform_device *pdev) { struct mmc_host *mmc; struct imxmci_host *host = NULL; struct resource *r; int ret = 0, irq; printk(KERN_INFO "i.MX mmc driver\n"); r = platform_device_resource(pdev, IORESOURCE_MEM, 0); irq = platform_device_irq(pdev, 0); if (!r || irq == NO_IRQ) return -ENXIO; r = request_mem_region(r->start, 0x100, "IMXMCI"); if (!r) return -EBUSY; mmc = mmc_alloc_host(sizeof(struct imxmci_host), &pdev->dev); if (!mmc) { ret = -ENOMEM; goto out; } mmc->ops = &imxmci_ops; mmc->f_min = 150000; mmc->f_max = CLK_RATE/2; mmc->ocr_avail = MMC_VDD_32_33; mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_BYTEBLOCK; /* MMC core transfer sizes tunable parameters */ mmc->max_hw_segs = 64; mmc->max_phys_segs = 64; mmc->max_sectors = 64; /* default 1 << (PAGE_CACHE_SHIFT - 9) */ mmc->max_seg_size = 64*512; /* default PAGE_CACHE_SIZE */ host = mmc_priv(mmc); host->mmc = mmc; host->dma_allocated = 0; host->pdata = pdev->dev.platform_data; spin_lock_init(&host->lock); host->res = r; host->irq = irq; imx_gpio_mode(PB8_PF_SD_DAT0); imx_gpio_mode(PB9_PF_SD_DAT1); imx_gpio_mode(PB10_PF_SD_DAT2); /* Configured as GPIO with pull-up to ensure right MCC card mode */ /* Switched to PB11_PF_SD_DAT3 if 4 bit bus is configured */ imx_gpio_mode(GPIO_PORTB | GPIO_IN | GPIO_PUEN | 11); /* imx_gpio_mode(PB11_PF_SD_DAT3); */ imx_gpio_mode(PB12_PF_SD_CLK); imx_gpio_mode(PB13_PF_SD_CMD); imxmci_softreset(); if ( MMC_REV_NO != 0x390 ) { dev_err(mmc_dev(host->mmc), "wrong rev.no. 0x%08x. aborting.\n", MMC_REV_NO); goto out; } MMC_READ_TO = 0x2db4; /* recommended in data sheet */ host->imask = IMXMCI_INT_MASK_DEFAULT; MMC_INT_MASK = host->imask; if(imx_dma_request_by_prio(&host->dma, DRIVER_NAME, DMA_PRIO_LOW)<0){ dev_err(mmc_dev(host->mmc), "imx_dma_request_by_prio failed\n"); ret = -EBUSY; goto out; } host->dma_allocated=1; imx_dma_setup_handlers(host->dma, imxmci_dma_irq, NULL, host); tasklet_init(&host->tasklet, imxmci_tasklet_fnc, (unsigned long)host); host->status_reg=0; host->pending_events=0; ret = request_irq(host->irq, imxmci_irq, 0, DRIVER_NAME, host); if (ret) goto out; host->present = host->pdata->card_present(); init_timer(&host->timer); host->timer.data = (unsigned long)host; host->timer.function = imxmci_check_status; add_timer(&host->timer); mod_timer(&host->timer, jiffies + (HZ>>1)); platform_set_drvdata(pdev, mmc); mmc_add_host(mmc); return 0; out: if (host) { if(host->dma_allocated){ imx_dma_free(host->dma); host->dma_allocated=0; } } if (mmc) mmc_free_host(mmc); release_resource(r); return ret; }