diff options
Diffstat (limited to 'drivers/tty')
-rw-r--r-- | drivers/tty/serial/amba-pl011.c | 64 |
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 | ||
270 | static void pl011_dma_probe_initcall(struct uart_amba_port *uap) | 270 | static 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) | |||
360 | struct dma_uap { | 370 | struct 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 | ||
365 | static LIST_HEAD(pl011_dma_uarts); | 376 | static 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 | ||
380 | device_initcall(pl011_dma_initcall); | 391 | device_initcall(pl011_dma_initcall); |
381 | 392 | ||
382 | static void pl011_dma_probe(struct uart_amba_port *uap) | 393 | static 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 |
391 | static void pl011_dma_probe(struct uart_amba_port *uap) | 403 | static 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 */ |
1099 | static inline void pl011_dma_probe(struct uart_amba_port *uap) | 1111 | static 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); |