aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty
diff options
context:
space:
mode:
authorGovindraj.R <govindraj.raja@ti.com>2011-11-09 07:11:21 -0500
committerKevin Hilman <khilman@ti.com>2011-12-14 19:05:26 -0500
commit2fd149645eb46d26130d7070c6de037dddf34880 (patch)
tree1b7030c0c6f65ebf7ae061ab082ea26f47453679 /drivers/tty
parent36fc2d15b120ef85be74c68b5ad74ac04fbefa8a (diff)
ARM: OMAP2+: UART: Remove omap_uart_can_sleep and add pm_qos
Omap_uart_can_sleep function blocks system wide low power state until uart is active remove this func and add qos requests to prevent MPU from transitioning. Keep qos request to default value which will allow MPU to transition and while uart baud rate is available calculate the latency value from the baudrate and use the same to hold constraint while uart clocks are enabled, and if uart is auto-idled the constraint is updated with default constraint value allowing MPU to transition. Qos requests are blocking notifier calls so put these requests to work queue, also the driver uses irq_safe version of runtime API's and callbacks can be called in interrupt disabled context. So to avoid warn on slow path warning while using qos update API's from runtime callbacks use the qos_work_queue. During bootup the runtime_resume call backs might not be called and runtime callback gets called only after uart is idled by setting the autosuspend timeout. So qos_request from runtime resume callback might not activated during boot if uart baudrate is calculated during bootup for console uart, so schedule the qos_work queue once we calc_latency while configuring the uart port. Flush and complete any pending qos jobs in work queue while suspending. Signed-off-by: Govindraj.R <govindraj.raja@ti.com> Acked-by: Greg Kroah-Hartman <gregkh@suse.de> (for drivers/tty changes) Signed-off-by: Kevin Hilman <khilman@ti.com>
Diffstat (limited to 'drivers/tty')
-rw-r--r--drivers/tty/serial/omap-serial.c36
1 files changed, 35 insertions, 1 deletions
diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c
index e1eaa66c047b..f3ff0ca377c5 100644
--- a/drivers/tty/serial/omap-serial.c
+++ b/drivers/tty/serial/omap-serial.c
@@ -51,6 +51,8 @@ static void serial_omap_rxdma_poll(unsigned long uart_no);
51static int serial_omap_start_rxdma(struct uart_omap_port *up); 51static int serial_omap_start_rxdma(struct uart_omap_port *up);
52static void serial_omap_mdr1_errataset(struct uart_omap_port *up, u8 mdr1); 52static void serial_omap_mdr1_errataset(struct uart_omap_port *up, u8 mdr1);
53 53
54static struct workqueue_struct *serial_omap_uart_wq;
55
54static inline unsigned int serial_in(struct uart_omap_port *up, int offset) 56static inline unsigned int serial_in(struct uart_omap_port *up, int offset)
55{ 57{
56 offset <<= up->port.regshift; 58 offset <<= up->port.regshift;
@@ -671,6 +673,14 @@ serial_omap_configure_xonxoff
671 serial_out(up, UART_LCR, up->lcr); 673 serial_out(up, UART_LCR, up->lcr);
672} 674}
673 675
676static void serial_omap_uart_qos_work(struct work_struct *work)
677{
678 struct uart_omap_port *up = container_of(work, struct uart_omap_port,
679 qos_work);
680
681 pm_qos_update_request(&up->pm_qos_request, up->latency);
682}
683
674static void 684static void
675serial_omap_set_termios(struct uart_port *port, struct ktermios *termios, 685serial_omap_set_termios(struct uart_port *port, struct ktermios *termios,
676 struct ktermios *old) 686 struct ktermios *old)
@@ -711,6 +721,12 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios,
711 baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/13); 721 baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/13);
712 quot = serial_omap_get_divisor(port, baud); 722 quot = serial_omap_get_divisor(port, baud);
713 723
724 /* calculate wakeup latency constraint */
725 up->calc_latency = (1000000 * up->port.fifosize) /
726 (1000 * baud / 8);
727 up->latency = up->calc_latency;
728 schedule_work(&up->qos_work);
729
714 up->dll = quot & 0xff; 730 up->dll = quot & 0xff;
715 up->dlh = quot >> 8; 731 up->dlh = quot >> 8;
716 up->mdr1 = UART_OMAP_MDR1_DISABLE; 732 up->mdr1 = UART_OMAP_MDR1_DISABLE;
@@ -1145,8 +1161,11 @@ static int serial_omap_suspend(struct device *dev)
1145{ 1161{
1146 struct uart_omap_port *up = dev_get_drvdata(dev); 1162 struct uart_omap_port *up = dev_get_drvdata(dev);
1147 1163
1148 if (up) 1164 if (up) {
1149 uart_suspend_port(&serial_omap_reg, &up->port); 1165 uart_suspend_port(&serial_omap_reg, &up->port);
1166 flush_work_sync(&up->qos_work);
1167 }
1168
1150 return 0; 1169 return 0;
1151} 1170}
1152 1171
@@ -1383,6 +1402,13 @@ static int serial_omap_probe(struct platform_device *pdev)
1383 up->uart_dma.rx_dma_channel = OMAP_UART_DMA_CH_FREE; 1402 up->uart_dma.rx_dma_channel = OMAP_UART_DMA_CH_FREE;
1384 } 1403 }
1385 1404
1405 up->latency = PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE;
1406 up->calc_latency = PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE;
1407 pm_qos_add_request(&up->pm_qos_request,
1408 PM_QOS_CPU_DMA_LATENCY, up->latency);
1409 serial_omap_uart_wq = create_singlethread_workqueue(up->name);
1410 INIT_WORK(&up->qos_work, serial_omap_uart_qos_work);
1411
1386 pm_runtime_use_autosuspend(&pdev->dev); 1412 pm_runtime_use_autosuspend(&pdev->dev);
1387 pm_runtime_set_autosuspend_delay(&pdev->dev, 1413 pm_runtime_set_autosuspend_delay(&pdev->dev,
1388 omap_up_info->autosuspend_timeout); 1414 omap_up_info->autosuspend_timeout);
@@ -1416,6 +1442,8 @@ static int serial_omap_remove(struct platform_device *dev)
1416 if (up) { 1442 if (up) {
1417 pm_runtime_disable(&up->pdev->dev); 1443 pm_runtime_disable(&up->pdev->dev);
1418 uart_remove_one_port(&serial_omap_reg, &up->port); 1444 uart_remove_one_port(&serial_omap_reg, &up->port);
1445 pm_qos_remove_request(&up->pm_qos_request);
1446
1419 kfree(up); 1447 kfree(up);
1420 } 1448 }
1421 1449
@@ -1518,6 +1546,9 @@ static int serial_omap_runtime_suspend(struct device *dev)
1518 (up->errata & UART_ERRATA_i291_DMA_FORCEIDLE)) 1546 (up->errata & UART_ERRATA_i291_DMA_FORCEIDLE))
1519 pdata->set_forceidle(up->pdev); 1547 pdata->set_forceidle(up->pdev);
1520 1548
1549 up->latency = PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE;
1550 schedule_work(&up->qos_work);
1551
1521 return 0; 1552 return 0;
1522} 1553}
1523 1554
@@ -1538,6 +1569,9 @@ static int serial_omap_runtime_resume(struct device *dev)
1538 if (up->use_dma && pdata->set_noidle && 1569 if (up->use_dma && pdata->set_noidle &&
1539 (up->errata & UART_ERRATA_i291_DMA_FORCEIDLE)) 1570 (up->errata & UART_ERRATA_i291_DMA_FORCEIDLE))
1540 pdata->set_noidle(up->pdev); 1571 pdata->set_noidle(up->pdev);
1572
1573 up->latency = up->calc_latency;
1574 schedule_work(&up->qos_work);
1541 } 1575 }
1542 1576
1543 return 0; 1577 return 0;