Переглянути джерело

efDataDiscreteRateMining temperatureVariance.c 邵敏 commit at 2021-03-11

邵敏 4 роки тому
батько
коміт
32b0e78930

+ 137 - 0
efDataDiscreteRateMining/varianceCalculation/temperatureVariance.c

@@ -614,3 +614,140 @@ static irqreturn_t s3c64xx_dma_irq(int irq, void *pw)
 		/* Free the node and update curr, if non-circular queue */
 		if (!(chan->flags & S3C2410_DMAF_CIRCULAR)) {
 			chan->curr = buff->next;
+			s3c64xx_dma_freebuff(buff);
+		}
+
+		/* Update 'next' */
+		buff = chan->next;
+		if (chan->next == chan->end) {
+			chan->next = chan->curr;
+			if (!(chan->flags & S3C2410_DMAF_CIRCULAR))
+				chan->end = NULL;
+		} else {
+			chan->next = buff->next;
+		}
+	}
+
+	return IRQ_HANDLED;
+}
+
+static struct bus_type dma_subsys = {
+	.name		= "s3c64xx-dma",
+	.dev_name	= "s3c64xx-dma",
+};
+
+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->dev.id = chno / 8;
+	dmac->dev.bus = &dma_subsys;
+
+	err = device_register(&dmac->dev);
+	if (err) {
+		printk(KERN_ERR "%s: failed to register device\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->dev.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++, chptr++) {
+		pr_debug("%s: registering DMA %d (%p)\n",
+			 __func__, chno + ch, regptr);
+
+		chptr->bit = 1 << ch;
+		chptr->number = chno + ch;
+		chptr->dmac = dmac;
+		chptr->regs = regptr;
+		regptr += PL080_Cx_STRIDE;
+	}
+
+	/* 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, chno, chno+8);
+
+	return 0;
+
+err_clk:
+	clk_disable(dmac->clk);
+	clk_put(dmac->clk);
+err_map:
+	iounmap(regs);
+err_dev:
+	device_unregister(&dmac->dev);
+err_alloc:
+	kfree(dmac);
+	return err;
+}
+
+static int __init s3c64xx_dma_init(void)
+{
+	int ret;
+
+	printk(KERN_INFO "%s: Registering DMA channels\n", __func__);
+
+	dma_pool = dma_pool_create("DMA-LLI", NULL, sizeof(struct pl080s_lli), 16, 0);
+	if (!dma_pool) {
+		printk(KERN_ERR "%s: failed to create pool\n", __func__);
+		return -ENOMEM;
+	}
+
+	ret = subsys_system_register(&dma_subsys, NULL);
+	if (ret) {
+		printk(KERN_ERR "%s: failed to create subsys\n", __func__);
+		return -ENOMEM;
+	}
+
+	/* Set all DMA configuration to be DMA, not SDMA */
+	writel(0xffffff, S3C64XX_SDMA_SEL);
+
+	/* Register standard DMA controllers */
+	s3c64xx_dma_init1(0, DMACH_UART0, IRQ_DMA0, 0x75000000);
+	s3c64xx_dma_init1(8, DMACH_PCM1_TX, IRQ_DMA1, 0x75100000);
+
+	return 0;
+}
+
+arch_initcall(s3c64xx_dma_init);