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; }
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; }