unsigned int baud, quot;
        unsigned int old_csize = old ? old->c_cflag & CSIZE : CS8;
        unsigned long div;
-       unsigned long num, denom;
+       unsigned long num, denom, old_ubir, old_ubmr;
        uint64_t tdiv64;
 
        /*
        ufcr = (ufcr & (~UFCR_RFDIV)) | UFCR_RFDIV_REG(div);
        imx_uart_writel(sport, ufcr, UFCR);
 
-       imx_uart_writel(sport, num, UBIR);
-       imx_uart_writel(sport, denom, UBMR);
+       /*
+        *  Two registers below should always be written both and in this
+        *  particular order. One consequence is that we need to check if any of
+        *  them changes and then update both. We do need the check for change
+        *  as even writing the same values seem to "restart"
+        *  transmission/receiving logic in the hardware, that leads to data
+        *  breakage even when rate doesn't in fact change. E.g., user switches
+        *  RTS/CTS handshake and suddenly gets broken bytes.
+        */
+       old_ubir = imx_uart_readl(sport, UBIR);
+       old_ubmr = imx_uart_readl(sport, UBMR);
+       if (old_ubir != num || old_ubmr != denom) {
+               imx_uart_writel(sport, num, UBIR);
+               imx_uart_writel(sport, denom, UBMR);
+       }
 
        if (!imx_uart_is_imx1(sport))
                imx_uart_writel(sport, sport->port.uartclk / div / 1000,