Commit dc715452 authored by Arnd Bergmann's avatar Arnd Bergmann

spi: pl022: use generic DMA slave configuration if possible

With the new OF DMA binding, it is possible to completely avoid the
need for platform_data for configuring a DMA channel. In cases where the
platform has already been converted, calling dma_request_slave_channel
should get all the necessary information from the device tree.

Like the patch that converts the dw_dma controller, this is completely
untested and is looking for someone to try it out.
Signed-off-by: default avatarArnd Bergmann <arnd@arndb.de>
Acked-by: default avatarGrant Likely <grant.likely@secretlab.ca>
Acked-by: default avatarMark Brown <broonie@opensource.wolfsonmicro.com>
Acked-by: default avatarLinus Walleij <linus.walleij@linaro.org>
Cc: spi-devel-general@lists.sourceforge.net
Cc: Viresh Kumar <viresh.kumar@linaro.org>
Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Cc: Vinod Koul <vinod.koul@linux.intel.com>
Cc: devicetree-discuss@lists.ozlabs.org
Cc: linux-arm-kernel@lists.infradead.org
parent f6161aa1
...@@ -16,6 +16,11 @@ Optional properties: ...@@ -16,6 +16,11 @@ Optional properties:
device will be suspended immediately device will be suspended immediately
- pl022,rt : indicates the controller should run the message pump with realtime - pl022,rt : indicates the controller should run the message pump with realtime
priority to minimise the transfer latency on the bus (boolean) priority to minimise the transfer latency on the bus (boolean)
- dmas : Two or more DMA channel specifiers following the convention outlined
in bindings/dma/dma.txt
- dma-names: Names for the dma channels, if present. There must be at
least one channel named "tx" for transmit and named "rx" for
receive.
SPI slave nodes must be children of the SPI master node and can SPI slave nodes must be children of the SPI master node and can
...@@ -32,3 +37,34 @@ contain the following properties. ...@@ -32,3 +37,34 @@ contain the following properties.
- pl022,wait-state : Microwire interface: Wait state - pl022,wait-state : Microwire interface: Wait state
- pl022,duplex : Microwire interface: Full/Half duplex - pl022,duplex : Microwire interface: Full/Half duplex
Example:
spi@e0100000 {
compatible = "arm,pl022", "arm,primecell";
reg = <0xe0100000 0x1000>;
#address-cells = <1>;
#size-cells = <0>;
interrupts = <0 31 0x4>;
dmas = <&dma-controller 23 1>,
<&dma-controller 24 0>;
dma-names = "rx", "tx";
m25p80@1 {
compatible = "st,m25p80";
reg = <1>;
spi-max-frequency = <12000000>;
spi-cpol;
spi-cpha;
pl022,hierarchy = <0>;
pl022,interface = <0>;
pl022,slave-tx-disable;
pl022,com-mode = <0x2>;
pl022,rx-level-trig = <0>;
pl022,tx-level-trig = <0>;
pl022,ctrl-len = <0x11>;
pl022,wait-state = <0>;
pl022,duplex = <0>;
};
};
...@@ -1139,6 +1139,35 @@ static int pl022_dma_probe(struct pl022 *pl022) ...@@ -1139,6 +1139,35 @@ static int pl022_dma_probe(struct pl022 *pl022)
return -ENODEV; return -ENODEV;
} }
static int pl022_dma_autoprobe(struct pl022 *pl022)
{
struct device *dev = &pl022->adev->dev;
/* automatically configure DMA channels from platform, normally using DT */
pl022->dma_rx_channel = dma_request_slave_channel(dev, "rx");
if (!pl022->dma_rx_channel)
goto err_no_rxchan;
pl022->dma_tx_channel = dma_request_slave_channel(dev, "tx");
if (!pl022->dma_tx_channel)
goto err_no_txchan;
pl022->dummypage = kmalloc(PAGE_SIZE, GFP_KERNEL);
if (!pl022->dummypage)
goto err_no_dummypage;
return 0;
err_no_dummypage:
dma_release_channel(pl022->dma_tx_channel);
pl022->dma_tx_channel = NULL;
err_no_txchan:
dma_release_channel(pl022->dma_rx_channel);
pl022->dma_rx_channel = NULL;
err_no_rxchan:
return -ENODEV;
}
static void terminate_dma(struct pl022 *pl022) static void terminate_dma(struct pl022 *pl022)
{ {
struct dma_chan *rxchan = pl022->dma_rx_channel; struct dma_chan *rxchan = pl022->dma_rx_channel;
...@@ -1167,6 +1196,11 @@ static inline int configure_dma(struct pl022 *pl022) ...@@ -1167,6 +1196,11 @@ static inline int configure_dma(struct pl022 *pl022)
return -ENODEV; return -ENODEV;
} }
static inline int pl022_dma_autoprobe(struct pl022 *pl022)
{
return 0;
}
static inline int pl022_dma_probe(struct pl022 *pl022) static inline int pl022_dma_probe(struct pl022 *pl022)
{ {
return 0; return 0;
...@@ -2226,8 +2260,13 @@ static int pl022_probe(struct amba_device *adev, const struct amba_id *id) ...@@ -2226,8 +2260,13 @@ static int pl022_probe(struct amba_device *adev, const struct amba_id *id)
goto err_no_irq; goto err_no_irq;
} }
/* Get DMA channels */ /* Get DMA channels, try autoconfiguration first */
if (platform_info->enable_dma) { status = pl022_dma_autoprobe(pl022);
/* If that failed, use channels from platform_info */
if (status == 0)
platform_info->enable_dma = 1;
else if (platform_info->enable_dma) {
status = pl022_dma_probe(pl022); status = pl022_dma_probe(pl022);
if (status != 0) if (status != 0)
platform_info->enable_dma = 0; platform_info->enable_dma = 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment