diff options
author | Rabin Vincent <rabin.vincent@axis.com> | 2015-11-23 02:13:45 -0500 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2015-11-23 06:31:44 -0500 |
commit | f3d4bb3342630cd3d89882586851498d8dc7c0f2 (patch) | |
tree | cfa8e53506ecc427d1ab043fffee145fe55c0922 /drivers/spi/spi-pl022.c | |
parent | 8005c49d9aea74d382f474ce11afbbc7d7130bec (diff) |
spi: pl022: handle EPROBE_DEFER for dma
Handle EPROBE_DEFER explicitly so that we ensure that we get the DMA
channel specified in the device tree, instead of depending on the DMA
controller getting probed before us.
Signed-off-by: Rabin Vincent <rabin.vincent@axis.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'drivers/spi/spi-pl022.c')
-rw-r--r-- | drivers/spi/spi-pl022.c | 28 |
1 files changed, 22 insertions, 6 deletions
diff --git a/drivers/spi/spi-pl022.c b/drivers/spi/spi-pl022.c index 94af80676684..5e5fd77e2711 100644 --- a/drivers/spi/spi-pl022.c +++ b/drivers/spi/spi-pl022.c | |||
@@ -1171,19 +1171,31 @@ err_no_rxchan: | |||
1171 | static int pl022_dma_autoprobe(struct pl022 *pl022) | 1171 | static int pl022_dma_autoprobe(struct pl022 *pl022) |
1172 | { | 1172 | { |
1173 | struct device *dev = &pl022->adev->dev; | 1173 | struct device *dev = &pl022->adev->dev; |
1174 | struct dma_chan *chan; | ||
1175 | int err; | ||
1174 | 1176 | ||
1175 | /* automatically configure DMA channels from platform, normally using DT */ | 1177 | /* automatically configure DMA channels from platform, normally using DT */ |
1176 | pl022->dma_rx_channel = dma_request_slave_channel(dev, "rx"); | 1178 | chan = dma_request_slave_channel_reason(dev, "rx"); |
1177 | if (!pl022->dma_rx_channel) | 1179 | if (IS_ERR(chan)) { |
1180 | err = PTR_ERR(chan); | ||
1178 | goto err_no_rxchan; | 1181 | goto err_no_rxchan; |
1182 | } | ||
1183 | |||
1184 | pl022->dma_rx_channel = chan; | ||
1179 | 1185 | ||
1180 | pl022->dma_tx_channel = dma_request_slave_channel(dev, "tx"); | 1186 | chan = dma_request_slave_channel_reason(dev, "tx"); |
1181 | if (!pl022->dma_tx_channel) | 1187 | if (IS_ERR(chan)) { |
1188 | err = PTR_ERR(chan); | ||
1182 | goto err_no_txchan; | 1189 | goto err_no_txchan; |
1190 | } | ||
1191 | |||
1192 | pl022->dma_tx_channel = chan; | ||
1183 | 1193 | ||
1184 | pl022->dummypage = kmalloc(PAGE_SIZE, GFP_KERNEL); | 1194 | pl022->dummypage = kmalloc(PAGE_SIZE, GFP_KERNEL); |
1185 | if (!pl022->dummypage) | 1195 | if (!pl022->dummypage) { |
1196 | err = -ENOMEM; | ||
1186 | goto err_no_dummypage; | 1197 | goto err_no_dummypage; |
1198 | } | ||
1187 | 1199 | ||
1188 | return 0; | 1200 | return 0; |
1189 | 1201 | ||
@@ -1194,7 +1206,7 @@ err_no_txchan: | |||
1194 | dma_release_channel(pl022->dma_rx_channel); | 1206 | dma_release_channel(pl022->dma_rx_channel); |
1195 | pl022->dma_rx_channel = NULL; | 1207 | pl022->dma_rx_channel = NULL; |
1196 | err_no_rxchan: | 1208 | err_no_rxchan: |
1197 | return -ENODEV; | 1209 | return err; |
1198 | } | 1210 | } |
1199 | 1211 | ||
1200 | static void terminate_dma(struct pl022 *pl022) | 1212 | static void terminate_dma(struct pl022 *pl022) |
@@ -2236,6 +2248,10 @@ static int pl022_probe(struct amba_device *adev, const struct amba_id *id) | |||
2236 | 2248 | ||
2237 | /* Get DMA channels, try autoconfiguration first */ | 2249 | /* Get DMA channels, try autoconfiguration first */ |
2238 | status = pl022_dma_autoprobe(pl022); | 2250 | status = pl022_dma_autoprobe(pl022); |
2251 | if (status == -EPROBE_DEFER) { | ||
2252 | dev_dbg(dev, "deferring probe to get DMA channel\n"); | ||
2253 | goto err_no_irq; | ||
2254 | } | ||
2239 | 2255 | ||
2240 | /* If that failed, use channels from platform_info */ | 2256 | /* If that failed, use channels from platform_info */ |
2241 | if (status == 0) | 2257 | if (status == 0) |