static int max310x_set_baud(struct uart_port *port, int baud)
 {
-       unsigned int mode = 0, clk = port->uartclk, div = clk / baud;
+       unsigned int mode = 0, div = 0, frac = 0, c = 0, F = 0;
 
-       /* Check for minimal value for divider */
-       if (div < 16)
-               div = 16;
-
-       if (clk % baud && (div / 16) < 0x8000) {
+       /*
+        * Calculate the integer divisor first. Select a proper mode
+        * in case if the requested baud is too high for the pre-defined
+        * clocks frequency.
+        */
+       div = port->uartclk / baud;
+       if (div < 8) {
+               /* Mode x4 */
+               c = 4;
+               mode = MAX310X_BRGCFG_4XMODE_BIT;
+       } else if (div < 16) {
                /* Mode x2 */
+               c = 8;
                mode = MAX310X_BRGCFG_2XMODE_BIT;
-               clk = port->uartclk * 2;
-               div = clk / baud;
-
-               if (clk % baud && (div / 16) < 0x8000) {
-                       /* Mode x4 */
-                       mode = MAX310X_BRGCFG_4XMODE_BIT;
-                       clk = port->uartclk * 4;
-                       div = clk / baud;
-               }
+       } else {
+               c = 16;
        }
 
-       max310x_port_write(port, MAX310X_BRGDIVMSB_REG, (div / 16) >> 8);
-       max310x_port_write(port, MAX310X_BRGDIVLSB_REG, div / 16);
-       max310x_port_write(port, MAX310X_BRGCFG_REG, (div % 16) | mode);
+       /* Calculate the divisor in accordance with the fraction coefficient */
+       div /= c;
+       F = c*baud;
+
+       /* Calculate the baud rate fraction */
+       if (div > 0)
+               frac = (16*(port->uartclk % F)) / F;
+       else
+               div = 1;
+
+       max310x_port_write(port, MAX310X_BRGDIVMSB_REG, div >> 8);
+       max310x_port_write(port, MAX310X_BRGDIVLSB_REG, div);
+       max310x_port_write(port, MAX310X_BRGCFG_REG, frac | mode);
 
-       return DIV_ROUND_CLOSEST(clk, div);
+       /* Return the actual baud rate we just programmed */
+       return (16*port->uartclk) / (c*(16*div + frac));
 }
 
 static int max310x_update_best_err(unsigned long f, long *besterr)
 {
        /* Use baudrate 115200 for calculate error */
-       long err = f % (115200 * 16);
+       long err = f % (460800 * 16);
 
        if ((*besterr < 0) || (*besterr > err)) {
                *besterr = err;