static int rspi_probe()

in spi-rspi.c [1288:1410]


static int rspi_probe(struct platform_device *pdev)
{
	struct resource *res;
	struct spi_controller *ctlr;
	struct rspi_data *rspi;
	int ret;
	const struct rspi_plat_data *rspi_pd;
	const struct spi_ops *ops;
	unsigned long clksrc;

	ctlr = spi_alloc_master(&pdev->dev, sizeof(struct rspi_data));
	if (ctlr == NULL)
		return -ENOMEM;

	ops = of_device_get_match_data(&pdev->dev);
	if (ops) {
		ret = rspi_parse_dt(&pdev->dev, ctlr);
		if (ret)
			goto error1;
	} else {
		ops = (struct spi_ops *)pdev->id_entry->driver_data;
		rspi_pd = dev_get_platdata(&pdev->dev);
		if (rspi_pd && rspi_pd->num_chipselect)
			ctlr->num_chipselect = rspi_pd->num_chipselect;
		else
			ctlr->num_chipselect = 2; /* default */
	}

	rspi = spi_controller_get_devdata(ctlr);
	platform_set_drvdata(pdev, rspi);
	rspi->ops = ops;
	rspi->ctlr = ctlr;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	rspi->addr = devm_ioremap_resource(&pdev->dev, res);
	if (IS_ERR(rspi->addr)) {
		ret = PTR_ERR(rspi->addr);
		goto error1;
	}

	rspi->clk = devm_clk_get(&pdev->dev, NULL);
	if (IS_ERR(rspi->clk)) {
		dev_err(&pdev->dev, "cannot get clock\n");
		ret = PTR_ERR(rspi->clk);
		goto error1;
	}

	rspi->pdev = pdev;
	pm_runtime_enable(&pdev->dev);

	init_waitqueue_head(&rspi->wait);
	spin_lock_init(&rspi->lock);

	ctlr->bus_num = pdev->id;
	ctlr->setup = rspi_setup;
	ctlr->auto_runtime_pm = true;
	ctlr->transfer_one = ops->transfer_one;
	ctlr->prepare_message = rspi_prepare_message;
	ctlr->unprepare_message = rspi_unprepare_message;
	ctlr->mode_bits = SPI_CPHA | SPI_CPOL | SPI_CS_HIGH | SPI_LSB_FIRST |
			  SPI_LOOP | ops->extra_mode_bits;
	clksrc = clk_get_rate(rspi->clk);
	ctlr->min_speed_hz = DIV_ROUND_UP(clksrc, ops->max_div);
	ctlr->max_speed_hz = DIV_ROUND_UP(clksrc, ops->min_div);
	ctlr->flags = ops->flags;
	ctlr->dev.of_node = pdev->dev.of_node;
	ctlr->use_gpio_descriptors = true;
	ctlr->max_native_cs = rspi->ops->num_hw_ss;

	ret = platform_get_irq_byname_optional(pdev, "rx");
	if (ret < 0) {
		ret = platform_get_irq_byname_optional(pdev, "mux");
		if (ret < 0)
			ret = platform_get_irq(pdev, 0);
		if (ret >= 0)
			rspi->rx_irq = rspi->tx_irq = ret;
	} else {
		rspi->rx_irq = ret;
		ret = platform_get_irq_byname(pdev, "tx");
		if (ret >= 0)
			rspi->tx_irq = ret;
	}

	if (rspi->rx_irq == rspi->tx_irq) {
		/* Single multiplexed interrupt */
		ret = rspi_request_irq(&pdev->dev, rspi->rx_irq, rspi_irq_mux,
				       "mux", rspi);
	} else {
		/* Multi-interrupt mode, only SPRI and SPTI are used */
		ret = rspi_request_irq(&pdev->dev, rspi->rx_irq, rspi_irq_rx,
				       "rx", rspi);
		if (!ret)
			ret = rspi_request_irq(&pdev->dev, rspi->tx_irq,
					       rspi_irq_tx, "tx", rspi);
	}
	if (ret < 0) {
		dev_err(&pdev->dev, "request_irq error\n");
		goto error2;
	}

	ret = rspi_request_dma(&pdev->dev, ctlr, res);
	if (ret < 0)
		dev_warn(&pdev->dev, "DMA not available, using PIO\n");

	ret = devm_spi_register_controller(&pdev->dev, ctlr);
	if (ret < 0) {
		dev_err(&pdev->dev, "devm_spi_register_controller error.\n");
		goto error3;
	}

	dev_info(&pdev->dev, "probed\n");

	return 0;

error3:
	rspi_release_dma(ctlr);
error2:
	pm_runtime_disable(&pdev->dev);
error1:
	spi_controller_put(ctlr);

	return ret;
}