diff options
Diffstat (limited to 'drivers/serial/sh-sci.c')
-rw-r--r-- | drivers/serial/sh-sci.c | 27 |
1 files changed, 25 insertions, 2 deletions
diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c index 3a13e58e9c5d..386fb878680c 100644 --- a/drivers/serial/sh-sci.c +++ b/drivers/serial/sh-sci.c | |||
@@ -82,6 +82,9 @@ struct sci_port { | |||
82 | /* SCSCR initialization */ | 82 | /* SCSCR initialization */ |
83 | unsigned int scscr; | 83 | unsigned int scscr; |
84 | 84 | ||
85 | /* SCBRR calculation algo */ | ||
86 | unsigned int scbrr_algo_id; | ||
87 | |||
85 | #ifdef CONFIG_HAVE_CLK | 88 | #ifdef CONFIG_HAVE_CLK |
86 | /* Interface clock */ | 89 | /* Interface clock */ |
87 | struct clk *iclk; | 90 | struct clk *iclk; |
@@ -928,6 +931,27 @@ static void sci_shutdown(struct uart_port *port) | |||
928 | s->disable(port); | 931 | s->disable(port); |
929 | } | 932 | } |
930 | 933 | ||
934 | static unsigned int sci_scbrr_calc(unsigned int algo_id, unsigned int bps, | ||
935 | unsigned long freq) | ||
936 | { | ||
937 | switch (algo_id) { | ||
938 | case SCBRR_ALGO_1: | ||
939 | return ((freq + 16 * bps) / (16 * bps) - 1); | ||
940 | case SCBRR_ALGO_2: | ||
941 | return ((freq + 16 * bps) / (32 * bps) - 1); | ||
942 | case SCBRR_ALGO_3: | ||
943 | return (((freq * 2) + 16 * bps) / (16 * bps) - 1); | ||
944 | case SCBRR_ALGO_4: | ||
945 | return (((freq * 2) + 16 * bps) / (32 * bps) - 1); | ||
946 | case SCBRR_ALGO_5: | ||
947 | return (((freq * 1000 / 32) / bps) - 1); | ||
948 | } | ||
949 | |||
950 | /* Warn, but use a safe default */ | ||
951 | WARN_ON(1); | ||
952 | return ((freq + 16 * bps) / (32 * bps) - 1); | ||
953 | } | ||
954 | |||
931 | static void sci_set_termios(struct uart_port *port, struct ktermios *termios, | 955 | static void sci_set_termios(struct uart_port *port, struct ktermios *termios, |
932 | struct ktermios *old) | 956 | struct ktermios *old) |
933 | { | 957 | { |
@@ -937,7 +961,7 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, | |||
937 | 961 | ||
938 | baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16); | 962 | baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16); |
939 | if (likely(baud)) | 963 | if (likely(baud)) |
940 | t = SCBRR_VALUE(baud, port->uartclk); | 964 | t = sci_scbrr_calc(s->scbrr_algo_id, baud, port->uartclk); |
941 | 965 | ||
942 | do { | 966 | do { |
943 | status = sci_in(port, SCxSR); | 967 | status = sci_in(port, SCxSR); |
@@ -1108,7 +1132,6 @@ static void __devinit sci_init_single(struct platform_device *dev, | |||
1108 | sci_port->type = sci_port->port.type = p->type; | 1132 | sci_port->type = sci_port->port.type = p->type; |
1109 | 1133 | ||
1110 | memcpy(&sci_port->irqs, &p->irqs, sizeof(p->irqs)); | 1134 | memcpy(&sci_port->irqs, &p->irqs, sizeof(p->irqs)); |
1111 | |||
1112 | } | 1135 | } |
1113 | 1136 | ||
1114 | #ifdef CONFIG_SERIAL_SH_SCI_CONSOLE | 1137 | #ifdef CONFIG_SERIAL_SH_SCI_CONSOLE |