summaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial/pl2303.c
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2015-08-17 09:09:51 -0700
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2015-08-17 09:09:51 -0700
commit02dc2723f2b0b94bb3e47c08e1543b84b1836086 (patch)
tree189cb06a65d9e940ca92d4e0b94162a287263aba /drivers/usb/serial/pl2303.c
parent17248569499eae54b314fb05c4ff19fd47c9e99b (diff)
parent26c78daade0fbeef7f20bae3c5508a7c571078cd (diff)
downloadblackbird-op-linux-02dc2723f2b0b94bb3e47c08e1543b84b1836086.tar.gz
blackbird-op-linux-02dc2723f2b0b94bb3e47c08e1543b84b1836086.zip
Merge tag 'usb-serial-4.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/johan/usb-serial into usb-next
Johan writes: USB-serial updates for v4.3-rc1 Here's a fix for a long-standing issue with the pl2303 divisor calculations that affects some non-standard baudrates that were enabled in v3.18. Adding support for newer Edgeport devices and firmware required changes to the io_ti driver and also exposed some issues with the driver's current firmware handling. Included is also a URL comment-typo fix. Signed-off-by: Johan Hovold <johan@kernel.org>
Diffstat (limited to 'drivers/usb/serial/pl2303.c')
-rw-r--r--drivers/usb/serial/pl2303.c35
1 files changed, 26 insertions, 9 deletions
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c
index f5257af33ecf..ae682e4eeaef 100644
--- a/drivers/usb/serial/pl2303.c
+++ b/drivers/usb/serial/pl2303.c
@@ -362,21 +362,38 @@ static speed_t pl2303_encode_baud_rate_direct(unsigned char buf[4],
static speed_t pl2303_encode_baud_rate_divisor(unsigned char buf[4],
speed_t baud)
{
- unsigned int tmp;
+ unsigned int baseline, mantissa, exponent;
/*
* Apparently the formula is:
- * baudrate = 12M * 32 / (2^buf[1]) / buf[0]
+ * baudrate = 12M * 32 / (mantissa * 4^exponent)
+ * where
+ * mantissa = buf[8:0]
+ * exponent = buf[11:9]
*/
- tmp = 12000000 * 32 / baud;
+ baseline = 12000000 * 32;
+ mantissa = baseline / baud;
+ if (mantissa == 0)
+ mantissa = 1; /* Avoid dividing by zero if baud > 32*12M. */
+ exponent = 0;
+ while (mantissa >= 512) {
+ if (exponent < 7) {
+ mantissa >>= 2; /* divide by 4 */
+ exponent++;
+ } else {
+ /* Exponent is maxed. Trim mantissa and leave. */
+ mantissa = 511;
+ break;
+ }
+ }
+
buf[3] = 0x80;
buf[2] = 0;
- buf[1] = (tmp >= 256);
- while (tmp >= 256) {
- tmp >>= 2;
- buf[1] <<= 1;
- }
- buf[0] = tmp;
+ buf[1] = exponent << 1 | mantissa >> 8;
+ buf[0] = mantissa & 0xff;
+
+ /* Calculate and return the exact baud rate. */
+ baud = (baseline / mantissa) >> (exponent << 1);
return baud;
}
OpenPOWER on IntegriCloud