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