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 __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; }
void __init ams_delta_init_fiq(void) { void *fiqhandler_start; unsigned int fiqhandler_length; struct pt_regs FIQ_regs; unsigned long val, offset; int i, retval; fiqhandler_start = &qwerty_fiqin_start; fiqhandler_length = &qwerty_fiqin_end - &qwerty_fiqin_start; pr_info("Installing fiq handler from %p, length 0x%x\n", fiqhandler_start, fiqhandler_length); retval = claim_fiq(&fh); if (retval) { pr_err("ams_delta_init_fiq(): couldn't claim FIQ, ret=%d\n", retval); return; } retval = request_irq(INT_DEFERRED_FIQ, deferred_fiq, IRQ_TYPE_EDGE_RISING, "deferred_fiq", NULL); if (retval < 0) { pr_err("Failed to get deferred_fiq IRQ, ret=%d\n", retval); release_fiq(&fh); return; } /* * Since no set_type() method is provided by OMAP irq chip, * switch to edge triggered interrupt type manually. */ offset = IRQ_ILR0_REG_OFFSET + ((INT_DEFERRED_FIQ - NR_IRQS_LEGACY) & 0x1f) * 0x4; val = omap_readl(DEFERRED_FIQ_IH_BASE + offset) & ~(1 << 1); omap_writel(val, DEFERRED_FIQ_IH_BASE + offset); set_fiq_handler(fiqhandler_start, fiqhandler_length); /* * Initialise the buffer which is shared * between FIQ mode and IRQ mode */ fiq_buffer[FIQ_GPIO_INT_MASK] = 0; fiq_buffer[FIQ_MASK] = 0; fiq_buffer[FIQ_STATE] = 0; fiq_buffer[FIQ_KEY] = 0; fiq_buffer[FIQ_KEYS_CNT] = 0; fiq_buffer[FIQ_KEYS_HICNT] = 0; fiq_buffer[FIQ_TAIL_OFFSET] = 0; fiq_buffer[FIQ_HEAD_OFFSET] = 0; fiq_buffer[FIQ_BUF_LEN] = 256; fiq_buffer[FIQ_MISSED_KEYS] = 0; fiq_buffer[FIQ_BUFFER_START] = (unsigned int) &fiq_buffer[FIQ_CIRC_BUFF]; for (i = FIQ_CNT_INT_00; i <= FIQ_CNT_INT_15; i++) fiq_buffer[i] = 0; /* * FIQ mode r9 always points to the fiq_buffer, because the FIQ isr * will run in an unpredictable context. The fiq_buffer is the FIQ isr's * only means of communication with the IRQ level and other kernel * context code. */ FIQ_regs.ARM_r9 = (unsigned int)fiq_buffer; set_fiq_regs(&FIQ_regs); pr_info("request_fiq(): fiq_buffer = %p\n", fiq_buffer); /* * Redirect GPIO interrupts to FIQ */ offset = IRQ_ILR0_REG_OFFSET + (INT_GPIO_BANK1 - NR_IRQS_LEGACY) * 0x4; val = omap_readl(OMAP_IH1_BASE + offset) | 1; omap_writel(val, OMAP_IH1_BASE + offset); }
static void floppy_disable_dma(dmach_t channel, dma_t *dma) { disable_fiq(dma->dma_irq); release_fiq(&fh); }
void imx_ssi_fiq_exit(struct platform_device *pdev, struct imx_ssi *ssi) { mxc_set_irq_fiq(ssi->irq, 0); release_fiq(&fh); }