summaryrefslogtreecommitdiffstats
path: root/drivers/tty
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/tty')
-rw-r--r--drivers/tty/serial/amba-pl011.c64
1 files changed, 38 insertions, 26 deletions
diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c
index b2e9e177a354..8ab70a620919 100644
--- a/drivers/tty/serial/amba-pl011.c
+++ b/drivers/tty/serial/amba-pl011.c
@@ -267,7 +267,7 @@ static void pl011_sgbuf_free(struct dma_chan *chan, struct pl011_sgbuf *sg,
267 } 267 }
268} 268}
269 269
270static void pl011_dma_probe_initcall(struct uart_amba_port *uap) 270static void pl011_dma_probe_initcall(struct device *dev, struct uart_amba_port *uap)
271{ 271{
272 /* DMA is the sole user of the platform data right now */ 272 /* DMA is the sole user of the platform data right now */
273 struct amba_pl011_data *plat = uap->port.dev->platform_data; 273 struct amba_pl011_data *plat = uap->port.dev->platform_data;
@@ -281,20 +281,25 @@ static void pl011_dma_probe_initcall(struct uart_amba_port *uap)
281 struct dma_chan *chan; 281 struct dma_chan *chan;
282 dma_cap_mask_t mask; 282 dma_cap_mask_t mask;
283 283
284 /* We need platform data */ 284 chan = dma_request_slave_channel(dev, "tx");
285 if (!plat || !plat->dma_filter) {
286 dev_info(uap->port.dev, "no DMA platform data\n");
287 return;
288 }
289 285
290 /* Try to acquire a generic DMA engine slave TX channel */
291 dma_cap_zero(mask);
292 dma_cap_set(DMA_SLAVE, mask);
293
294 chan = dma_request_channel(mask, plat->dma_filter, plat->dma_tx_param);
295 if (!chan) { 286 if (!chan) {
296 dev_err(uap->port.dev, "no TX DMA channel!\n"); 287 /* We need platform data */
297 return; 288 if (!plat || !plat->dma_filter) {
289 dev_info(uap->port.dev, "no DMA platform data\n");
290 return;
291 }
292
293 /* Try to acquire a generic DMA engine slave TX channel */
294 dma_cap_zero(mask);
295 dma_cap_set(DMA_SLAVE, mask);
296
297 chan = dma_request_channel(mask, plat->dma_filter,
298 plat->dma_tx_param);
299 if (!chan) {
300 dev_err(uap->port.dev, "no TX DMA channel!\n");
301 return;
302 }
298 } 303 }
299 304
300 dmaengine_slave_config(chan, &tx_conf); 305 dmaengine_slave_config(chan, &tx_conf);
@@ -304,7 +309,18 @@ static void pl011_dma_probe_initcall(struct uart_amba_port *uap)
304 dma_chan_name(uap->dmatx.chan)); 309 dma_chan_name(uap->dmatx.chan));
305 310
306 /* Optionally make use of an RX channel as well */ 311 /* Optionally make use of an RX channel as well */
307 if (plat->dma_rx_param) { 312 chan = dma_request_slave_channel(dev, "rx");
313
314 if (!chan && plat->dma_rx_param) {
315 chan = dma_request_channel(mask, plat->dma_filter, plat->dma_rx_param);
316
317 if (!chan) {
318 dev_err(uap->port.dev, "no RX DMA channel!\n");
319 return;
320 }
321 }
322
323 if (chan) {
308 struct dma_slave_config rx_conf = { 324 struct dma_slave_config rx_conf = {
309 .src_addr = uap->port.mapbase + UART01x_DR, 325 .src_addr = uap->port.mapbase + UART01x_DR,
310 .src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE, 326 .src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE,
@@ -313,12 +329,6 @@ static void pl011_dma_probe_initcall(struct uart_amba_port *uap)
313 .device_fc = false, 329 .device_fc = false,
314 }; 330 };
315 331
316 chan = dma_request_channel(mask, plat->dma_filter, plat->dma_rx_param);
317 if (!chan) {
318 dev_err(uap->port.dev, "no RX DMA channel!\n");
319 return;
320 }
321
322 dmaengine_slave_config(chan, &rx_conf); 332 dmaengine_slave_config(chan, &rx_conf);
323 uap->dmarx.chan = chan; 333 uap->dmarx.chan = chan;
324 334
@@ -360,6 +370,7 @@ static void pl011_dma_probe_initcall(struct uart_amba_port *uap)
360struct dma_uap { 370struct dma_uap {
361 struct list_head node; 371 struct list_head node;
362 struct uart_amba_port *uap; 372 struct uart_amba_port *uap;
373 struct device *dev;
363}; 374};
364 375
365static LIST_HEAD(pl011_dma_uarts); 376static LIST_HEAD(pl011_dma_uarts);
@@ -370,7 +381,7 @@ static int __init pl011_dma_initcall(void)
370 381
371 list_for_each_safe(node, tmp, &pl011_dma_uarts) { 382 list_for_each_safe(node, tmp, &pl011_dma_uarts) {
372 struct dma_uap *dmau = list_entry(node, struct dma_uap, node); 383 struct dma_uap *dmau = list_entry(node, struct dma_uap, node);
373 pl011_dma_probe_initcall(dmau->uap); 384 pl011_dma_probe_initcall(dmau->dev, dmau->uap);
374 list_del(node); 385 list_del(node);
375 kfree(dmau); 386 kfree(dmau);
376 } 387 }
@@ -379,18 +390,19 @@ static int __init pl011_dma_initcall(void)
379 390
380device_initcall(pl011_dma_initcall); 391device_initcall(pl011_dma_initcall);
381 392
382static void pl011_dma_probe(struct uart_amba_port *uap) 393static void pl011_dma_probe(struct device *dev, struct uart_amba_port *uap)
383{ 394{
384 struct dma_uap *dmau = kzalloc(sizeof(struct dma_uap), GFP_KERNEL); 395 struct dma_uap *dmau = kzalloc(sizeof(struct dma_uap), GFP_KERNEL);
385 if (dmau) { 396 if (dmau) {
386 dmau->uap = uap; 397 dmau->uap = uap;
398 dmau->dev = dev;
387 list_add_tail(&dmau->node, &pl011_dma_uarts); 399 list_add_tail(&dmau->node, &pl011_dma_uarts);
388 } 400 }
389} 401}
390#else 402#else
391static void pl011_dma_probe(struct uart_amba_port *uap) 403static void pl011_dma_probe(struct device *dev, struct uart_amba_port *uap)
392{ 404{
393 pl011_dma_probe_initcall(uap); 405 pl011_dma_probe_initcall(dev, uap);
394} 406}
395#endif 407#endif
396 408
@@ -1096,7 +1108,7 @@ static inline bool pl011_dma_rx_running(struct uart_amba_port *uap)
1096 1108
1097#else 1109#else
1098/* Blank functions if the DMA engine is not available */ 1110/* Blank functions if the DMA engine is not available */
1099static inline void pl011_dma_probe(struct uart_amba_port *uap) 1111static inline void pl011_dma_probe(struct device *dev, struct uart_amba_port *uap)
1100{ 1112{
1101} 1113}
1102 1114
@@ -2155,7 +2167,7 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id)
2155 uap->port.ops = &amba_pl011_pops; 2167 uap->port.ops = &amba_pl011_pops;
2156 uap->port.flags = UPF_BOOT_AUTOCONF; 2168 uap->port.flags = UPF_BOOT_AUTOCONF;
2157 uap->port.line = i; 2169 uap->port.line = i;
2158 pl011_dma_probe(uap); 2170 pl011_dma_probe(&dev->dev, uap);
2159 2171
2160 /* Ensure interrupts from this UART are masked and cleared */ 2172 /* Ensure interrupts from this UART are masked and cleared */
2161 writew(0, uap->port.membase + UART011_IMSC); 2173 writew(0, uap->port.membase + UART011_IMSC);