예제 #1
0
파일: dma.c 프로젝트: AppEngine/linux-2.6
static int s3c64xx_dma_init1(int chno, enum dma_ch chbase,
			     int irq, unsigned int base)
{
	struct s3c2410_dma_chan *chptr = &s3c2410_chans[chno];
	struct s3c64xx_dmac *dmac;
	char clkname[16];
	void __iomem *regs;
	void __iomem *regptr;
	int err, ch;

	dmac = kzalloc(sizeof(struct s3c64xx_dmac), GFP_KERNEL);
	if (!dmac) {
		printk(KERN_ERR "%s: failed to alloc mem\n", __func__);
		return -ENOMEM;
	}

	dmac->sysdev.id = chno / 8;
	dmac->sysdev.cls = &dma_sysclass;

	err = sysdev_register(&dmac->sysdev);
	if (err) {
		printk(KERN_ERR "%s: failed to register sysdevice\n", __func__);
		goto err_alloc;
	}

	regs = ioremap(base, 0x200);
	if (!regs) {
		printk(KERN_ERR "%s: failed to ioremap()\n", __func__);
		err = -ENXIO;
		goto err_dev;
	}

	snprintf(clkname, sizeof(clkname), "dma%d", dmac->sysdev.id);

	dmac->clk = clk_get(NULL, clkname);
	if (IS_ERR(dmac->clk)) {
		printk(KERN_ERR "%s: failed to get clock %s\n", __func__, clkname);
		err = PTR_ERR(dmac->clk);
		goto err_map;
	}

	clk_enable(dmac->clk);

	dmac->regs = regs;
	dmac->chanbase = chbase;
	dmac->channels = chptr;

	err = request_irq(irq, s3c64xx_dma_irq, 0, "DMA", dmac);
	if (err < 0) {
		printk(KERN_ERR "%s: failed to get irq\n", __func__);
		goto err_clk;
	}

	regptr = regs + PL080_Cx_BASE(0);

	for (ch = 0; ch < 8; ch++, chno++, chptr++) {
		printk(KERN_INFO "%s: registering DMA %d (%p)\n",
		       __func__, chno, regptr);

		chptr->bit = 1 << ch;
		chptr->number = chno;
		chptr->dmac = dmac;
		chptr->regs = regptr;
		regptr += PL008_Cx_STRIDE;
	}

	/* for the moment, permanently enable the controller */
	writel(PL080_CONFIG_ENABLE, regs + PL080_CONFIG);

	printk(KERN_INFO "PL080: IRQ %d, at %p\n", irq, regs);

	return 0;

err_clk:
	clk_disable(dmac->clk);
	clk_put(dmac->clk);
err_map:
	iounmap(regs);
err_dev:
	sysdev_unregister(&dmac->sysdev);
err_alloc:
	kfree(dmac);
	return err;
}
예제 #2
0
파일: dma.c 프로젝트: qnhoang81/spica-3.0
static int __init s3c64xx_dma_probe(struct platform_device *pdev)
{
	struct s3c2410_dma_chan *chptr = &s3c2410_chans[8*pdev->id];
	struct s3c64xx_dmac *dmac;
	char clkname[16];
	void __iomem *regs;
	void __iomem *regptr;
	int err, ch, irq;
	struct resource *res_mem, *res_chbase;

	dmac = kzalloc(sizeof(struct s3c64xx_dmac), GFP_KERNEL);
	if (!dmac) {
		printk(KERN_ERR "%s: failed to alloc mem\n", __func__);
		return -ENOMEM;
	}

	res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	res_chbase = platform_get_resource(pdev, IORESOURCE_DMA, 0);

	dmac->sysdev.id = pdev->id;
	dmac->sysdev.cls = &dma_sysclass;

	err = sysdev_register(&dmac->sysdev);
	if (err) {
		printk(KERN_ERR "%s: failed to register sysdevice\n", __func__);
		goto err_alloc;
	}

	regs = ioremap(res_mem->start, resource_size(res_mem));
	if (!regs) {
		printk(KERN_ERR "%s: failed to ioremap()\n", __func__);
		err = -ENXIO;
		goto err_dev;
	}

	snprintf(clkname, sizeof(clkname), "dma%d", dmac->sysdev.id);

	dmac->clk = clk_get(&pdev->dev, clkname);
	if (IS_ERR(dmac->clk)) {
		printk(KERN_ERR "%s: failed to get clock %s\n", __func__, clkname);
		err = PTR_ERR(dmac->clk);
		goto err_map;
	}
	clk_enable(dmac->clk);

	dmac->regs = regs;
	dmac->chanbase = res_chbase->start;
	dmac->channels = chptr;
	dmac->dev = &pdev->dev;

	irq = platform_get_irq(pdev, 0);
	err = request_irq(irq, s3c64xx_dma_irq, 0, "DMA", dmac);
	if (err < 0) {
		printk(KERN_ERR "%s: failed to get irq\n", __func__);
		goto err_clk;
	}

	regptr = regs + PL080_Cx_BASE(0);

	for (ch = 0; ch < 8; ch++, chptr++) {
		pr_debug("%s: registering DMA %d (%p)\n",
			 __func__, 8*pdev->id + ch, regptr);

		chptr->bit = 1 << ch;
		chptr->number = 8*pdev->id + ch;
		chptr->dmac = dmac;
		chptr->regs = regptr;
		atomic_set(&chptr->started, 0);
		regptr += PL080_Cx_STRIDE;
	}

	platform_set_drvdata(pdev, dmac);

	/* for the moment, permanently enable the controller */
	writel(PL080_CONFIG_ENABLE, regs + PL080_CONFIG);

	printk(KERN_INFO "PL080: IRQ %d, at %p, channels %d..%d\n",
	       irq, regs, 8*pdev->id, 8*pdev->id+8);

	return 0;

err_clk:
	clk_disable(dmac->clk);
	clk_put(dmac->clk);
err_map:
	iounmap(regs);
err_dev:
	sysdev_unregister(&dmac->sysdev);
err_alloc:
	kfree(dmac);
	return err;
}