diff options
Diffstat (limited to 'drivers/tty/serial')
-rw-r--r-- | drivers/tty/serial/sirfsoc_uart.c | 28 | ||||
-rw-r--r-- | drivers/tty/serial/sirfsoc_uart.h | 1 |
2 files changed, 22 insertions, 7 deletions
diff --git a/drivers/tty/serial/sirfsoc_uart.c b/drivers/tty/serial/sirfsoc_uart.c index 8f3d6c091acc..6bbfe9934a4d 100644 --- a/drivers/tty/serial/sirfsoc_uart.c +++ b/drivers/tty/serial/sirfsoc_uart.c | |||
@@ -357,7 +357,6 @@ static void sirfsoc_uart_set_termios(struct uart_port *port, | |||
357 | struct ktermios *old) | 357 | struct ktermios *old) |
358 | { | 358 | { |
359 | struct sirfsoc_uart_port *sirfport = to_sirfport(port); | 359 | struct sirfsoc_uart_port *sirfport = to_sirfport(port); |
360 | unsigned long ioclk_rate; | ||
361 | unsigned long config_reg = 0; | 360 | unsigned long config_reg = 0; |
362 | unsigned long baud_rate; | 361 | unsigned long baud_rate; |
363 | unsigned long setted_baud; | 362 | unsigned long setted_baud; |
@@ -369,7 +368,6 @@ static void sirfsoc_uart_set_termios(struct uart_port *port, | |||
369 | int threshold_div; | 368 | int threshold_div; |
370 | int temp; | 369 | int temp; |
371 | 370 | ||
372 | ioclk_rate = 150000000; | ||
373 | switch (termios->c_cflag & CSIZE) { | 371 | switch (termios->c_cflag & CSIZE) { |
374 | default: | 372 | default: |
375 | case CS8: | 373 | case CS8: |
@@ -425,14 +423,17 @@ static void sirfsoc_uart_set_termios(struct uart_port *port, | |||
425 | sirfsoc_uart_disable_ms(port); | 423 | sirfsoc_uart_disable_ms(port); |
426 | } | 424 | } |
427 | 425 | ||
428 | /* common rate: fast calculation */ | 426 | if (port->uartclk == 150000000) { |
429 | for (ic = 0; ic < SIRF_BAUD_RATE_SUPPORT_NR; ic++) | 427 | /* common rate: fast calculation */ |
430 | if (baud_rate == baudrate_to_regv[ic].baud_rate) | 428 | for (ic = 0; ic < SIRF_BAUD_RATE_SUPPORT_NR; ic++) |
431 | clk_div_reg = baudrate_to_regv[ic].reg_val; | 429 | if (baud_rate == baudrate_to_regv[ic].baud_rate) |
430 | clk_div_reg = baudrate_to_regv[ic].reg_val; | ||
431 | } | ||
432 | |||
432 | setted_baud = baud_rate; | 433 | setted_baud = baud_rate; |
433 | /* arbitary rate setting */ | 434 | /* arbitary rate setting */ |
434 | if (unlikely(clk_div_reg == 0)) | 435 | if (unlikely(clk_div_reg == 0)) |
435 | clk_div_reg = sirfsoc_calc_sample_div(baud_rate, ioclk_rate, | 436 | clk_div_reg = sirfsoc_calc_sample_div(baud_rate, port->uartclk, |
436 | &setted_baud); | 437 | &setted_baud); |
437 | wr_regl(port, SIRFUART_DIVISOR, clk_div_reg); | 438 | wr_regl(port, SIRFUART_DIVISOR, clk_div_reg); |
438 | 439 | ||
@@ -691,6 +692,14 @@ int sirfsoc_uart_probe(struct platform_device *pdev) | |||
691 | goto err; | 692 | goto err; |
692 | } | 693 | } |
693 | 694 | ||
695 | sirfport->clk = clk_get(&pdev->dev, NULL); | ||
696 | if (IS_ERR(sirfport->clk)) { | ||
697 | ret = PTR_ERR(sirfport->clk); | ||
698 | goto clk_err; | ||
699 | } | ||
700 | clk_prepare_enable(sirfport->clk); | ||
701 | port->uartclk = clk_get_rate(sirfport->clk); | ||
702 | |||
694 | port->ops = &sirfsoc_uart_ops; | 703 | port->ops = &sirfsoc_uart_ops; |
695 | spin_lock_init(&port->lock); | 704 | spin_lock_init(&port->lock); |
696 | 705 | ||
@@ -704,6 +713,9 @@ int sirfsoc_uart_probe(struct platform_device *pdev) | |||
704 | return 0; | 713 | return 0; |
705 | 714 | ||
706 | port_err: | 715 | port_err: |
716 | clk_disable_unprepare(sirfport->clk); | ||
717 | clk_put(sirfport->clk); | ||
718 | clk_err: | ||
707 | platform_set_drvdata(pdev, NULL); | 719 | platform_set_drvdata(pdev, NULL); |
708 | if (sirfport->hw_flow_ctrl) | 720 | if (sirfport->hw_flow_ctrl) |
709 | pinctrl_put(sirfport->p); | 721 | pinctrl_put(sirfport->p); |
@@ -718,6 +730,8 @@ static int sirfsoc_uart_remove(struct platform_device *pdev) | |||
718 | platform_set_drvdata(pdev, NULL); | 730 | platform_set_drvdata(pdev, NULL); |
719 | if (sirfport->hw_flow_ctrl) | 731 | if (sirfport->hw_flow_ctrl) |
720 | pinctrl_put(sirfport->p); | 732 | pinctrl_put(sirfport->p); |
733 | clk_disable_unprepare(sirfport->clk); | ||
734 | clk_put(sirfport->clk); | ||
721 | uart_remove_one_port(&sirfsoc_uart_drv, port); | 735 | uart_remove_one_port(&sirfsoc_uart_drv, port); |
722 | return 0; | 736 | return 0; |
723 | } | 737 | } |
diff --git a/drivers/tty/serial/sirfsoc_uart.h b/drivers/tty/serial/sirfsoc_uart.h index 6431640c3163..85328ba0c4e3 100644 --- a/drivers/tty/serial/sirfsoc_uart.h +++ b/drivers/tty/serial/sirfsoc_uart.h | |||
@@ -163,6 +163,7 @@ struct sirfsoc_uart_port { | |||
163 | 163 | ||
164 | struct uart_port port; | 164 | struct uart_port port; |
165 | struct pinctrl *p; | 165 | struct pinctrl *p; |
166 | struct clk *clk; | ||
166 | }; | 167 | }; |
167 | 168 | ||
168 | /* Hardware Flow Control */ | 169 | /* Hardware Flow Control */ |