in spi-lantiq-ssc.c [903:1024]
static int lantiq_ssc_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct spi_master *master;
struct lantiq_ssc_spi *spi;
const struct lantiq_ssc_hwcfg *hwcfg;
const struct of_device_id *match;
u32 id, supports_dma, revision;
unsigned int num_cs;
int err;
match = of_match_device(lantiq_ssc_match, dev);
if (!match) {
dev_err(dev, "no device match\n");
return -EINVAL;
}
hwcfg = match->data;
master = spi_alloc_master(dev, sizeof(struct lantiq_ssc_spi));
if (!master)
return -ENOMEM;
spi = spi_master_get_devdata(master);
spi->master = master;
spi->dev = dev;
spi->hwcfg = hwcfg;
platform_set_drvdata(pdev, spi);
spi->regbase = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(spi->regbase)) {
err = PTR_ERR(spi->regbase);
goto err_master_put;
}
err = hwcfg->cfg_irq(pdev, spi);
if (err)
goto err_master_put;
spi->spi_clk = devm_clk_get(dev, "gate");
if (IS_ERR(spi->spi_clk)) {
err = PTR_ERR(spi->spi_clk);
goto err_master_put;
}
err = clk_prepare_enable(spi->spi_clk);
if (err)
goto err_master_put;
/*
* Use the old clk_get_fpi() function on Lantiq platform, till it
* supports common clk.
*/
#if defined(CONFIG_LANTIQ) && !defined(CONFIG_COMMON_CLK)
spi->fpi_clk = clk_get_fpi();
#else
spi->fpi_clk = clk_get(dev, "freq");
#endif
if (IS_ERR(spi->fpi_clk)) {
err = PTR_ERR(spi->fpi_clk);
goto err_clk_disable;
}
num_cs = 8;
of_property_read_u32(pdev->dev.of_node, "num-cs", &num_cs);
spi->base_cs = 1;
of_property_read_u32(pdev->dev.of_node, "base-cs", &spi->base_cs);
spin_lock_init(&spi->lock);
spi->bits_per_word = 8;
spi->speed_hz = 0;
master->dev.of_node = pdev->dev.of_node;
master->num_chipselect = num_cs;
master->use_gpio_descriptors = true;
master->setup = lantiq_ssc_setup;
master->set_cs = lantiq_ssc_set_cs;
master->handle_err = lantiq_ssc_handle_err;
master->prepare_message = lantiq_ssc_prepare_message;
master->unprepare_message = lantiq_ssc_unprepare_message;
master->transfer_one = lantiq_ssc_transfer_one;
master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST | SPI_CS_HIGH |
SPI_LOOP;
master->bits_per_word_mask = SPI_BPW_RANGE_MASK(2, 8) |
SPI_BPW_MASK(16) | SPI_BPW_MASK(32);
spi->wq = alloc_ordered_workqueue(dev_name(dev), WQ_MEM_RECLAIM);
if (!spi->wq) {
err = -ENOMEM;
goto err_clk_put;
}
INIT_WORK(&spi->work, lantiq_ssc_bussy_work);
id = lantiq_ssc_readl(spi, LTQ_SPI_ID);
spi->tx_fifo_size = (id >> LTQ_SPI_ID_TXFS_S) & hwcfg->fifo_size_mask;
spi->rx_fifo_size = (id >> LTQ_SPI_ID_RXFS_S) & hwcfg->fifo_size_mask;
supports_dma = (id & LTQ_SPI_ID_CFG_M) >> LTQ_SPI_ID_CFG_S;
revision = id & LTQ_SPI_ID_REV_M;
lantiq_ssc_hw_init(spi);
dev_info(dev,
"Lantiq SSC SPI controller (Rev %i, TXFS %u, RXFS %u, DMA %u)\n",
revision, spi->tx_fifo_size, spi->rx_fifo_size, supports_dma);
err = devm_spi_register_master(dev, master);
if (err) {
dev_err(dev, "failed to register spi_master\n");
goto err_wq_destroy;
}
return 0;
err_wq_destroy:
destroy_workqueue(spi->wq);
err_clk_put:
clk_put(spi->fpi_clk);
err_clk_disable:
clk_disable_unprepare(spi->spi_clk);
err_master_put:
spi_master_put(master);
return err;
}