static int bcm63xx_spi_probe()

in spi-bcm63xx.c [486:617]


static int bcm63xx_spi_probe(struct platform_device *pdev)
{
	struct resource *r;
	const unsigned long *bcm63xx_spireg;
	struct device *dev = &pdev->dev;
	int irq, bus_num;
	struct spi_master *master;
	struct clk *clk;
	struct bcm63xx_spi *bs;
	int ret;
	u32 num_cs = BCM63XX_SPI_MAX_CS;
	struct reset_control *reset;

	if (dev->of_node) {
		const struct of_device_id *match;

		match = of_match_node(bcm63xx_spi_of_match, dev->of_node);
		if (!match)
			return -EINVAL;
		bcm63xx_spireg = match->data;

		of_property_read_u32(dev->of_node, "num-cs", &num_cs);
		if (num_cs > BCM63XX_SPI_MAX_CS) {
			dev_warn(dev, "unsupported number of cs (%i), reducing to 8\n",
				 num_cs);
			num_cs = BCM63XX_SPI_MAX_CS;
		}

		bus_num = -1;
	} else if (pdev->id_entry->driver_data) {
		const struct platform_device_id *match = pdev->id_entry;

		bcm63xx_spireg = (const unsigned long *)match->driver_data;
		bus_num = BCM63XX_SPI_BUS_NUM;
	} else {
		return -EINVAL;
	}

	irq = platform_get_irq(pdev, 0);
	if (irq < 0)
		return irq;

	clk = devm_clk_get(dev, "spi");
	if (IS_ERR(clk)) {
		dev_err(dev, "no clock for device\n");
		return PTR_ERR(clk);
	}

	reset = devm_reset_control_get_optional_exclusive(dev, NULL);
	if (IS_ERR(reset))
		return PTR_ERR(reset);

	master = spi_alloc_master(dev, sizeof(*bs));
	if (!master) {
		dev_err(dev, "out of memory\n");
		return -ENOMEM;
	}

	bs = spi_master_get_devdata(master);
	init_completion(&bs->done);

	platform_set_drvdata(pdev, master);
	bs->pdev = pdev;

	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	bs->regs = devm_ioremap_resource(&pdev->dev, r);
	if (IS_ERR(bs->regs)) {
		ret = PTR_ERR(bs->regs);
		goto out_err;
	}

	bs->irq = irq;
	bs->clk = clk;
	bs->reg_offsets = bcm63xx_spireg;
	bs->fifo_size = bs->reg_offsets[SPI_MSG_DATA_SIZE];

	ret = devm_request_irq(&pdev->dev, irq, bcm63xx_spi_interrupt, 0,
							pdev->name, master);
	if (ret) {
		dev_err(dev, "unable to request irq\n");
		goto out_err;
	}

	master->dev.of_node = dev->of_node;
	master->bus_num = bus_num;
	master->num_chipselect = num_cs;
	master->transfer_one_message = bcm63xx_spi_transfer_one;
	master->mode_bits = MODEBITS;
	master->bits_per_word_mask = SPI_BPW_MASK(8);
	master->max_transfer_size = bcm63xx_spi_max_length;
	master->max_message_size = bcm63xx_spi_max_length;
	master->auto_runtime_pm = true;
	bs->msg_type_shift = bs->reg_offsets[SPI_MSG_TYPE_SHIFT];
	bs->msg_ctl_width = bs->reg_offsets[SPI_MSG_CTL_WIDTH];
	bs->tx_io = (u8 *)(bs->regs + bs->reg_offsets[SPI_MSG_DATA]);
	bs->rx_io = (const u8 *)(bs->regs + bs->reg_offsets[SPI_RX_DATA]);

	/* Initialize hardware */
	ret = clk_prepare_enable(bs->clk);
	if (ret)
		goto out_err;

	ret = reset_control_reset(reset);
	if (ret) {
		dev_err(dev, "unable to reset device: %d\n", ret);
		goto out_clk_disable;
	}

	bcm_spi_writeb(bs, SPI_INTR_CLEAR_ALL, SPI_INT_STATUS);

	pm_runtime_enable(&pdev->dev);

	/* register and we are done */
	ret = devm_spi_register_master(dev, master);
	if (ret) {
		dev_err(dev, "spi register failed\n");
		goto out_pm_disable;
	}

	dev_info(dev, "at %pr (irq %d, FIFOs size %d)\n",
		 r, irq, bs->fifo_size);

	return 0;

out_pm_disable:
	pm_runtime_disable(&pdev->dev);
out_clk_disable:
	clk_disable_unprepare(clk);
out_err:
	spi_master_put(master);
	return ret;
}