@@ -1860,20 +1860,24 @@ static void sci_shutdown(struct uart_port *port)
sci_free_irq(s);
}
-static unsigned int sci_scbrr_calc(struct sci_port *s, unsigned int bps,
- unsigned long freq)
+/* calculate sample rate, BRR, and clock select */
+static void sci_scbrr_calc(struct sci_port *s, unsigned int bps,
+ unsigned long freq, int *brr, unsigned int *srr,
+ unsigned int *cks)
{
- return DIV_ROUND_CLOSEST(freq, s->sampling_rate * bps) - 1;
-}
-
-/* calculate sample rate, BRR, and clock select for HSCIF */
-static void sci_baud_calc_hscif(struct sci_port *s, unsigned int bps,
- unsigned long freq, int *brr,
- unsigned int *srr, unsigned int *cks)
-{
- unsigned int sr, br, prediv, scrate, c;
+ unsigned int min_sr, max_sr, shift, sr, br, prediv, scrate, c;
int err, min_err = INT_MAX;
+ if (s->sampling_rate) {
+ min_sr = max_sr = s->sampling_rate;
+ shift = 0;
+ } else {
+ /* HSCIF has a variable sample rate */
+ min_sr = 8;
+ max_sr = 32;
+ shift = 1;
+ }
+
/*
* Find the combination of sample rate and clock select with the
* smallest deviation from the desired baud rate.
@@ -1889,10 +1893,10 @@ static void sci_baud_calc_hscif(struct sci_port *s, unsigned int bps,
* (|D - 0.5| / N * (1 + F))|
* NOTE: Usually, treat D for 0.5, F is 0 by this calculation.
*/
- for (sr = 32; sr >= 8; sr--) {
+ for (sr = max_sr; sr >= min_sr; sr--) {
for (c = 0; c <= 3; c++) {
/* integerized formulas from HSCIF documentation */
- prediv = sr * (1 << (2 * c + 1));
+ prediv = sr * (1 << (2 * c + shift));
/*
* We need to calculate:
@@ -1974,16 +1978,8 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios,
max_baud = port->uartclk ? port->uartclk / 16 : 115200;
baud = uart_get_baud_rate(port, termios, old, 0, max_baud);
- if (likely(baud && port->uartclk)) {
- if (s->cfg->type == PORT_HSCIF) {
- sci_baud_calc_hscif(s, baud, port->uartclk, &t, &srr,
- &cks);
- } else {
- t = sci_scbrr_calc(s, baud, port->uartclk);
- for (cks = 0; t >= 256 && cks <= 3; cks++)
- t >>= 2;
- }
- }
+ if (likely(baud && port->uartclk))
+ sci_scbrr_calc(s, baud, port->uartclk, &t, &srr, &cks);
sci_port_enable(s);