bcm2835: dma: strangeness of of_dma_request_slave_channel

Martin Sperl kernel at martin.sperl.org
Mon Apr 27 11:37:22 PDT 2015


Hi!

While implementing DMA mode fro the spi-bcm2835 driver I have run 
into some strangeness:

When loading unloading and reloading the module the call to 
of_dma_request_slave_channel fails on the second load and there
only for the second dma channel requested.

Here the basics:
void bcm2835_dma_release(struct spi_master *master)
{
        if (master->dma_tx) {
                dma_release_channel(master->dma_tx);
                master->dma_tx = NULL;
        }
        if (master->dma_rx) {
                dma_release_channel(master->dma_rx);
                master->dma_rx = NULL;
        }
}

void bcm2835_dma_init(struct spi_master *master, struct device *dev)
{
        struct bcm2835_spi *bs = spi_master_get_devdata(master);
        struct dma_slave_config slave_config;
        int ret;

        /* get tx/rx dma */
        master->dma_tx = dma_request_slave_channel(dev, "tx");
        if (!master->dma_tx) {
                dev_err(dev, "no tx-dma found - not using dma mode\n");
                goto err;
        }
        master->dma_rx = dma_request_slave_channel(dev, "rx");
        if (!master->dma_rx) {
                dev_err(dev, "only tx-dma was found - not using dma mode\n");
                goto err_release;
        }
       	...
	ret = dmaengine_slave_config(master->dma_tx, &slave_config); 
       	...
	ret = dmaengine_slave_config(master->dma_rx, &slave_config);

}

here the portion in the device-tree:
        dmas = <&dma 6>, <&dma 7>;
        dma-names = "tx", "rx";

So after a reboot I run:
modprobe spi-bcm2835
rmmod spi-bcm2835
modprobe spi-bcm2835

dmesg shows: "only tx-dma was found - not using dma mode"
for the second modprobe - the first one is fine and the channels are
found - the only way arround it is reboot!

So it can get a channel for TX (typically channel 4) and for rx it
fails for any module load besides the first (which returns channel 5
on the first load)

Tracing it further I see (inside bcm2835_dma_xlate) that
	chan = dma_get_any_slave_channel(&d->ddev);

returns NULL the second (or any subsequent) times the module gets
loaded.

Has someone any insight why this could be the case and how to avoid it?
I am tired of rebooting every time i apply a change!

Thanks,
	Martin

P.s: I have applied V2 of the patch to enable normal DMA operation.



More information about the linux-rpi-kernel mailing list