Replace opmode shiftbit calculations with stored value per port (mxser_port.opmode_shift) . Preload value in mxser_probe routine. Signed-off-by: Michal Kadlic <michal.kadlic@xxxxxxxxx> --- Mxser driver uses a packed opmode register ( 2bits per port) to switch between RS232,RS485 and RS422 mode. Shiftbit variable is calculated in several places to determine correct bits per port. Reasons for change: 1. Code cleanup - remove calculations scattered in code 2. ARCH_MOXART could use mxser.c in the future but it uses different bit offsets, so each calculation would need an #ifdef. --- diff -purN old/drivers/tty/mxser.c new/drivers/tty/mxser.c --- old/drivers/tty/mxser.c 2016-06-15 13:22:50.000000000 +0200 +++ new/drivers/tty/mxser.c 2016-06-15 13:33:23.000000000 +0200 @@ -256,6 +256,8 @@ struct mxser_port { int xmit_cnt; int closing; + unsigned char opmode_shift; /* Position of opmode bits in opmode register */ + struct ktermios normal_termios; struct mxser_mon mon_data; @@ -1622,7 +1624,7 @@ static int mxser_ioctl_special(unsigned me->fifo[p] = 1; if (ip->board->chip_flag == MOXA_MUST_MU860_HWID) { - opmode = inb(ip->opmode_ioaddr)>>((p % 4) * 2); + opmode = inb(ip->opmode_ioaddr) >> ip->opmode_shift; opmode &= OP_MODE_MASK; } else { opmode = RS232_MODE; @@ -1677,16 +1679,12 @@ static int mxser_ioctl(struct tty_struct return mxser_ioctl_special(cmd, argp); if (cmd == MOXA_SET_OP_MODE || cmd == MOXA_GET_OP_MODE) { - int p; unsigned long opmode; - static unsigned char ModeMask[] = { 0xfc, 0xf3, 0xcf, 0x3f }; - int shiftbit; unsigned char val, mask; if (info->board->chip_flag != MOXA_MUST_MU860_HWID) return -EFAULT; - p = tty->index % 4; if (cmd == MOXA_SET_OP_MODE) { if (get_user(opmode, (int __user *) argp)) return -EFAULT; @@ -1695,19 +1693,17 @@ static int mxser_ioctl(struct tty_struct opmode != RS422_MODE && opmode != RS485_4WIRE_MODE) return -EFAULT; - mask = ModeMask[p]; - shiftbit = p * 2; + mask = ~ ( OP_MODE_MASK << info->opmode_shift ); + spin_lock_irq(&info->slock); val = inb(info->opmode_ioaddr); val &= mask; - val |= (opmode << shiftbit); + val |= (opmode << info->opmode_shift); outb(val, info->opmode_ioaddr); + spin_unlock_irq(&info->slock); } else { - shiftbit = p * 2; - spin_lock_irq(&info->slock); - opmode = inb(info->opmode_ioaddr) >> shiftbit; - spin_unlock_irq(&info->slock); + opmode = inb(info->opmode_ioaddr) >> info->opmode_shift; opmode &= OP_MODE_MASK; if (put_user(opmode, (int __user *)argp)) return -EFAULT; @@ -2633,9 +2629,12 @@ static int mxser_probe(struct pci_dev *p brd->ports[i].opmode_ioaddr = ioaddress + 4; else brd->ports[i].opmode_ioaddr = ioaddress + 0x0c; + /* opmode is packed , 2 bits per port, 4 ports per register */ + brd->ports[i].opmode_shift = (i % 4) * 2; } outb(0, ioaddress + 4); /* default set to RS232 mode */ - outb(0, ioaddress + 0x0c); /* default set to RS232 mode */ + if (brd->info->nports > 4) + outb(0, ioaddress + 0x0c); /* default set to RS232 mode */ } for (i = 0; i < brd->info->nports; i++) { -- To unsubscribe from this list: send the line "unsubscribe linux-serial" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html