in spi-au1550.c [723:924]
static int au1550_spi_probe(struct platform_device *pdev)
{
struct au1550_spi *hw;
struct spi_master *master;
struct resource *r;
int err = 0;
master = spi_alloc_master(&pdev->dev, sizeof(struct au1550_spi));
if (master == NULL) {
dev_err(&pdev->dev, "No memory for spi_master\n");
err = -ENOMEM;
goto err_nomem;
}
/* the spi->mode bits understood by this driver: */
master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LSB_FIRST;
master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 24);
hw = spi_master_get_devdata(master);
hw->master = master;
hw->pdata = dev_get_platdata(&pdev->dev);
hw->dev = &pdev->dev;
if (hw->pdata == NULL) {
dev_err(&pdev->dev, "No platform data supplied\n");
err = -ENOENT;
goto err_no_pdata;
}
r = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
if (!r) {
dev_err(&pdev->dev, "no IRQ\n");
err = -ENODEV;
goto err_no_iores;
}
hw->irq = r->start;
hw->usedma = 0;
r = platform_get_resource(pdev, IORESOURCE_DMA, 0);
if (r) {
hw->dma_tx_id = r->start;
r = platform_get_resource(pdev, IORESOURCE_DMA, 1);
if (r) {
hw->dma_rx_id = r->start;
if (usedma && ddma_memid) {
if (pdev->dev.dma_mask == NULL)
dev_warn(&pdev->dev, "no dma mask\n");
else
hw->usedma = 1;
}
}
}
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!r) {
dev_err(&pdev->dev, "no mmio resource\n");
err = -ENODEV;
goto err_no_iores;
}
hw->ioarea = request_mem_region(r->start, sizeof(psc_spi_t),
pdev->name);
if (!hw->ioarea) {
dev_err(&pdev->dev, "Cannot reserve iomem region\n");
err = -ENXIO;
goto err_no_iores;
}
hw->regs = (psc_spi_t __iomem *)ioremap(r->start, sizeof(psc_spi_t));
if (!hw->regs) {
dev_err(&pdev->dev, "cannot ioremap\n");
err = -ENXIO;
goto err_ioremap;
}
platform_set_drvdata(pdev, hw);
init_completion(&hw->master_done);
hw->bitbang.master = hw->master;
hw->bitbang.setup_transfer = au1550_spi_setupxfer;
hw->bitbang.chipselect = au1550_spi_chipsel;
hw->bitbang.txrx_bufs = au1550_spi_txrx_bufs;
if (hw->usedma) {
hw->dma_tx_ch = au1xxx_dbdma_chan_alloc(ddma_memid,
hw->dma_tx_id, NULL, (void *)hw);
if (hw->dma_tx_ch == 0) {
dev_err(&pdev->dev,
"Cannot allocate tx dma channel\n");
err = -ENXIO;
goto err_no_txdma;
}
au1xxx_dbdma_set_devwidth(hw->dma_tx_ch, 8);
if (au1xxx_dbdma_ring_alloc(hw->dma_tx_ch,
AU1550_SPI_DBDMA_DESCRIPTORS) == 0) {
dev_err(&pdev->dev,
"Cannot allocate tx dma descriptors\n");
err = -ENXIO;
goto err_no_txdma_descr;
}
hw->dma_rx_ch = au1xxx_dbdma_chan_alloc(hw->dma_rx_id,
ddma_memid, NULL, (void *)hw);
if (hw->dma_rx_ch == 0) {
dev_err(&pdev->dev,
"Cannot allocate rx dma channel\n");
err = -ENXIO;
goto err_no_rxdma;
}
au1xxx_dbdma_set_devwidth(hw->dma_rx_ch, 8);
if (au1xxx_dbdma_ring_alloc(hw->dma_rx_ch,
AU1550_SPI_DBDMA_DESCRIPTORS) == 0) {
dev_err(&pdev->dev,
"Cannot allocate rx dma descriptors\n");
err = -ENXIO;
goto err_no_rxdma_descr;
}
err = au1550_spi_dma_rxtmp_alloc(hw,
AU1550_SPI_DMA_RXTMP_MINSIZE);
if (err < 0) {
dev_err(&pdev->dev,
"Cannot allocate initial rx dma tmp buffer\n");
goto err_dma_rxtmp_alloc;
}
}
au1550_spi_bits_handlers_set(hw, 8);
err = request_irq(hw->irq, au1550_spi_irq, 0, pdev->name, hw);
if (err) {
dev_err(&pdev->dev, "Cannot claim IRQ\n");
goto err_no_irq;
}
master->bus_num = pdev->id;
master->num_chipselect = hw->pdata->num_chipselect;
/*
* precompute valid range for spi freq - from au1550 datasheet:
* psc_tempclk = psc_mainclk / (2 << DIV)
* spiclk = psc_tempclk / (2 * (BRG + 1))
* BRG valid range is 4..63
* DIV valid range is 0..3
* round the min and max frequencies to values that would still
* produce valid brg and div
*/
{
int min_div = (2 << 0) * (2 * (4 + 1));
int max_div = (2 << 3) * (2 * (63 + 1));
master->max_speed_hz = hw->pdata->mainclk_hz / min_div;
master->min_speed_hz =
hw->pdata->mainclk_hz / (max_div + 1) + 1;
}
au1550_spi_setup_psc_as_spi(hw);
err = spi_bitbang_start(&hw->bitbang);
if (err) {
dev_err(&pdev->dev, "Failed to register SPI master\n");
goto err_register;
}
dev_info(&pdev->dev,
"spi master registered: bus_num=%d num_chipselect=%d\n",
master->bus_num, master->num_chipselect);
return 0;
err_register:
free_irq(hw->irq, hw);
err_no_irq:
au1550_spi_dma_rxtmp_free(hw);
err_dma_rxtmp_alloc:
err_no_rxdma_descr:
if (hw->usedma)
au1xxx_dbdma_chan_free(hw->dma_rx_ch);
err_no_rxdma:
err_no_txdma_descr:
if (hw->usedma)
au1xxx_dbdma_chan_free(hw->dma_tx_ch);
err_no_txdma:
iounmap((void __iomem *)hw->regs);
err_ioremap:
release_mem_region(r->start, sizeof(psc_spi_t));
err_no_iores:
err_no_pdata:
spi_master_put(hw->master);
err_nomem:
return err;
}