static int stm32_mdma_probe()

in stm32-mdma.c [1506:1660]


static int stm32_mdma_probe(struct platform_device *pdev)
{
	struct stm32_mdma_chan *chan;
	struct stm32_mdma_device *dmadev;
	struct dma_device *dd;
	struct device_node *of_node;
	struct resource *res;
	struct reset_control *rst;
	u32 nr_channels, nr_requests;
	int i, count, ret;

	of_node = pdev->dev.of_node;
	if (!of_node)
		return -ENODEV;

	ret = device_property_read_u32(&pdev->dev, "dma-channels",
				       &nr_channels);
	if (ret) {
		nr_channels = STM32_MDMA_MAX_CHANNELS;
		dev_warn(&pdev->dev, "MDMA defaulting on %i channels\n",
			 nr_channels);
	}

	ret = device_property_read_u32(&pdev->dev, "dma-requests",
				       &nr_requests);
	if (ret) {
		nr_requests = STM32_MDMA_MAX_REQUESTS;
		dev_warn(&pdev->dev, "MDMA defaulting on %i request lines\n",
			 nr_requests);
	}

	count = device_property_count_u32(&pdev->dev, "st,ahb-addr-masks");
	if (count < 0)
		count = 0;

	dmadev = devm_kzalloc(&pdev->dev,
			      struct_size(dmadev, ahb_addr_masks, count),
			      GFP_KERNEL);
	if (!dmadev)
		return -ENOMEM;

	dmadev->nr_channels = nr_channels;
	dmadev->nr_requests = nr_requests;
	device_property_read_u32_array(&pdev->dev, "st,ahb-addr-masks",
				       dmadev->ahb_addr_masks,
				       count);
	dmadev->nr_ahb_addr_masks = count;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	dmadev->base = devm_ioremap_resource(&pdev->dev, res);
	if (IS_ERR(dmadev->base))
		return PTR_ERR(dmadev->base);

	dmadev->clk = devm_clk_get(&pdev->dev, NULL);
	if (IS_ERR(dmadev->clk))
		return dev_err_probe(&pdev->dev, PTR_ERR(dmadev->clk),
				     "Missing clock controller\n");

	ret = clk_prepare_enable(dmadev->clk);
	if (ret < 0) {
		dev_err(&pdev->dev, "clk_prep_enable error: %d\n", ret);
		return ret;
	}

	rst = devm_reset_control_get(&pdev->dev, NULL);
	if (IS_ERR(rst)) {
		ret = PTR_ERR(rst);
		if (ret == -EPROBE_DEFER)
			goto err_clk;
	} else {
		reset_control_assert(rst);
		udelay(2);
		reset_control_deassert(rst);
	}

	dd = &dmadev->ddev;
	dma_cap_set(DMA_SLAVE, dd->cap_mask);
	dma_cap_set(DMA_PRIVATE, dd->cap_mask);
	dma_cap_set(DMA_CYCLIC, dd->cap_mask);
	dma_cap_set(DMA_MEMCPY, dd->cap_mask);
	dd->device_alloc_chan_resources = stm32_mdma_alloc_chan_resources;
	dd->device_free_chan_resources = stm32_mdma_free_chan_resources;
	dd->device_tx_status = stm32_mdma_tx_status;
	dd->device_issue_pending = stm32_mdma_issue_pending;
	dd->device_prep_slave_sg = stm32_mdma_prep_slave_sg;
	dd->device_prep_dma_cyclic = stm32_mdma_prep_dma_cyclic;
	dd->device_prep_dma_memcpy = stm32_mdma_prep_dma_memcpy;
	dd->device_config = stm32_mdma_slave_config;
	dd->device_pause = stm32_mdma_pause;
	dd->device_resume = stm32_mdma_resume;
	dd->device_terminate_all = stm32_mdma_terminate_all;
	dd->device_synchronize = stm32_mdma_synchronize;
	dd->descriptor_reuse = true;

	dd->src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) |
		BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) |
		BIT(DMA_SLAVE_BUSWIDTH_4_BYTES) |
		BIT(DMA_SLAVE_BUSWIDTH_8_BYTES);
	dd->dst_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) |
		BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) |
		BIT(DMA_SLAVE_BUSWIDTH_4_BYTES) |
		BIT(DMA_SLAVE_BUSWIDTH_8_BYTES);
	dd->directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV) |
		BIT(DMA_MEM_TO_MEM);
	dd->residue_granularity = DMA_RESIDUE_GRANULARITY_BURST;
	dd->max_burst = STM32_MDMA_MAX_BURST;
	dd->dev = &pdev->dev;
	INIT_LIST_HEAD(&dd->channels);

	for (i = 0; i < dmadev->nr_channels; i++) {
		chan = &dmadev->chan[i];
		chan->id = i;
		chan->vchan.desc_free = stm32_mdma_desc_free;
		vchan_init(&chan->vchan, dd);
	}

	dmadev->irq = platform_get_irq(pdev, 0);
	if (dmadev->irq < 0) {
		ret = dmadev->irq;
		goto err_clk;
	}

	ret = devm_request_irq(&pdev->dev, dmadev->irq, stm32_mdma_irq_handler,
			       0, dev_name(&pdev->dev), dmadev);
	if (ret) {
		dev_err(&pdev->dev, "failed to request IRQ\n");
		goto err_clk;
	}

	ret = dmaenginem_async_device_register(dd);
	if (ret)
		goto err_clk;

	ret = of_dma_controller_register(of_node, stm32_mdma_of_xlate, dmadev);
	if (ret < 0) {
		dev_err(&pdev->dev,
			"STM32 MDMA DMA OF registration failed %d\n", ret);
		goto err_clk;
	}

	platform_set_drvdata(pdev, dmadev);
	pm_runtime_set_active(&pdev->dev);
	pm_runtime_enable(&pdev->dev);
	pm_runtime_get_noresume(&pdev->dev);
	pm_runtime_put(&pdev->dev);

	dev_info(&pdev->dev, "STM32 MDMA driver registered\n");

	return 0;

err_clk:
	clk_disable_unprepare(dmadev->clk);

	return ret;
}