forked from mirrors/linux
		
	serial: 8250: Add support for higher baud rates to Pericom chips
The Pericom chips can achieve additional baud rates by programming the sample clock register. The baud rates can be described as 921600 * 16 / (16 - scr) for scr values 5 to 15. The divisor is set to 1 for these baud rates. Adds new quirk for Pericom chips other than the four port chips to use the Signed-off-by: Jay Dolan <jay.dolan@accesio.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
		
							parent
							
								
									4e828c3e09
								
							
						
					
					
						commit
						6bf4e42f1d
					
				
					 1 changed files with 78 additions and 17 deletions
				
			
		| 
						 | 
					@ -1326,13 +1326,66 @@ static int pci_default_setup(struct serial_private *priv,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return setup_port(priv, port, bar, offset, board->reg_shift);
 | 
						return setup_port(priv, port, bar, offset, board->reg_shift);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					pericom_do_set_divisor(struct uart_port *port, unsigned int baud,
 | 
				
			||||||
 | 
								       unsigned int quot, unsigned int quot_frac)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int scr;
 | 
				
			||||||
 | 
						int lcr;
 | 
				
			||||||
 | 
						int actual_baud;
 | 
				
			||||||
 | 
						int tolerance;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (scr = 5 ; scr <= 15 ; scr++) {
 | 
				
			||||||
 | 
							actual_baud = 921600 * 16 / scr;
 | 
				
			||||||
 | 
							tolerance = actual_baud / 50;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if ((baud < actual_baud + tolerance) &&
 | 
				
			||||||
 | 
								(baud > actual_baud - tolerance)) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								lcr = serial_port_in(port, UART_LCR);
 | 
				
			||||||
 | 
								serial_port_out(port, UART_LCR, lcr | 0x80);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								serial_port_out(port, UART_DLL, 1);
 | 
				
			||||||
 | 
								serial_port_out(port, UART_DLM, 0);
 | 
				
			||||||
 | 
								serial_port_out(port, 2, 16 - scr);
 | 
				
			||||||
 | 
								serial_port_out(port, UART_LCR, lcr);
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
 | 
							} else if (baud > actual_baud) {
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						serial8250_do_set_divisor(port, baud, quot, quot_frac);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
static int pci_pericom_setup(struct serial_private *priv,
 | 
					static int pci_pericom_setup(struct serial_private *priv,
 | 
				
			||||||
		  const struct pciserial_board *board,
 | 
							  const struct pciserial_board *board,
 | 
				
			||||||
		  struct uart_8250_port *port, int idx)
 | 
							  struct uart_8250_port *port, int idx)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	unsigned int bar, offset = board->first_offset, maxnr;
 | 
						unsigned int bar, offset = board->first_offset, maxnr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bar = FL_GET_BASE(board->flags);
 | 
				
			||||||
 | 
						if (board->flags & FL_BASE_BARS)
 | 
				
			||||||
 | 
							bar += idx;
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							offset += idx * board->uart_offset;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						maxnr = (pci_resource_len(priv->dev, bar) - board->first_offset) >>
 | 
				
			||||||
 | 
							(board->reg_shift + 3);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (board->flags & FL_REGION_SZ_CAP && idx >= maxnr)
 | 
				
			||||||
 | 
							return 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						port->port.set_divisor = pericom_do_set_divisor;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return setup_port(priv, port, bar, offset, board->reg_shift);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int pci_pericom_setup_four_at_eight(struct serial_private *priv,
 | 
				
			||||||
 | 
							  const struct pciserial_board *board,
 | 
				
			||||||
 | 
							  struct uart_8250_port *port, int idx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						unsigned int bar, offset = board->first_offset, maxnr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bar = FL_GET_BASE(board->flags);
 | 
						bar = FL_GET_BASE(board->flags);
 | 
				
			||||||
	if (board->flags & FL_BASE_BARS)
 | 
						if (board->flags & FL_BASE_BARS)
 | 
				
			||||||
		bar += idx;
 | 
							bar += idx;
 | 
				
			||||||
| 
						 | 
					@ -1348,6 +1401,8 @@ static int pci_pericom_setup(struct serial_private *priv,
 | 
				
			||||||
	if (board->flags & FL_REGION_SZ_CAP && idx >= maxnr)
 | 
						if (board->flags & FL_REGION_SZ_CAP && idx >= maxnr)
 | 
				
			||||||
		return 1;
 | 
							return 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						port->port.set_divisor = pericom_do_set_divisor;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return setup_port(priv, port, bar, offset, board->reg_shift);
 | 
						return setup_port(priv, port, bar, offset, board->reg_shift);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1995,7 +2050,7 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
 | 
				
			||||||
		.device		= PCI_DEVICE_ID_PERICOM_PI7C9X7954,
 | 
							.device		= PCI_DEVICE_ID_PERICOM_PI7C9X7954,
 | 
				
			||||||
		.subvendor	= PCI_ANY_ID,
 | 
							.subvendor	= PCI_ANY_ID,
 | 
				
			||||||
		.subdevice	= PCI_ANY_ID,
 | 
							.subdevice	= PCI_ANY_ID,
 | 
				
			||||||
		.setup		= pci_pericom_setup,
 | 
							.setup		= pci_pericom_setup_four_at_eight,
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * PLX
 | 
						 * PLX
 | 
				
			||||||
| 
						 | 
					@ -2032,107 +2087,113 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
 | 
				
			||||||
		.device     = PCI_DEVICE_ID_ACCESIO_PCIE_COM_4SDB,
 | 
							.device     = PCI_DEVICE_ID_ACCESIO_PCIE_COM_4SDB,
 | 
				
			||||||
		.subvendor  = PCI_ANY_ID,
 | 
							.subvendor  = PCI_ANY_ID,
 | 
				
			||||||
		.subdevice  = PCI_ANY_ID,
 | 
							.subdevice  = PCI_ANY_ID,
 | 
				
			||||||
		.setup      = pci_pericom_setup,
 | 
							.setup      = pci_pericom_setup_four_at_eight,
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		.vendor     = PCI_VENDOR_ID_ACCESIO,
 | 
							.vendor     = PCI_VENDOR_ID_ACCESIO,
 | 
				
			||||||
		.device     = PCI_DEVICE_ID_ACCESIO_MPCIE_COM_4S,
 | 
							.device     = PCI_DEVICE_ID_ACCESIO_MPCIE_COM_4S,
 | 
				
			||||||
		.subvendor  = PCI_ANY_ID,
 | 
							.subvendor  = PCI_ANY_ID,
 | 
				
			||||||
		.subdevice  = PCI_ANY_ID,
 | 
							.subdevice  = PCI_ANY_ID,
 | 
				
			||||||
		.setup      = pci_pericom_setup,
 | 
							.setup      = pci_pericom_setup_four_at_eight,
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		.vendor     = PCI_VENDOR_ID_ACCESIO,
 | 
							.vendor     = PCI_VENDOR_ID_ACCESIO,
 | 
				
			||||||
		.device     = PCI_DEVICE_ID_ACCESIO_PCIE_COM232_4DB,
 | 
							.device     = PCI_DEVICE_ID_ACCESIO_PCIE_COM232_4DB,
 | 
				
			||||||
		.subvendor  = PCI_ANY_ID,
 | 
							.subvendor  = PCI_ANY_ID,
 | 
				
			||||||
		.subdevice  = PCI_ANY_ID,
 | 
							.subdevice  = PCI_ANY_ID,
 | 
				
			||||||
		.setup      = pci_pericom_setup,
 | 
							.setup      = pci_pericom_setup_four_at_eight,
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		.vendor     = PCI_VENDOR_ID_ACCESIO,
 | 
							.vendor     = PCI_VENDOR_ID_ACCESIO,
 | 
				
			||||||
		.device     = PCI_DEVICE_ID_ACCESIO_MPCIE_COM232_4,
 | 
							.device     = PCI_DEVICE_ID_ACCESIO_MPCIE_COM232_4,
 | 
				
			||||||
		.subvendor  = PCI_ANY_ID,
 | 
							.subvendor  = PCI_ANY_ID,
 | 
				
			||||||
		.subdevice  = PCI_ANY_ID,
 | 
							.subdevice  = PCI_ANY_ID,
 | 
				
			||||||
		.setup      = pci_pericom_setup,
 | 
							.setup      = pci_pericom_setup_four_at_eight,
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		.vendor     = PCI_VENDOR_ID_ACCESIO,
 | 
							.vendor     = PCI_VENDOR_ID_ACCESIO,
 | 
				
			||||||
		.device     = PCI_DEVICE_ID_ACCESIO_PCIE_COM_4SMDB,
 | 
							.device     = PCI_DEVICE_ID_ACCESIO_PCIE_COM_4SMDB,
 | 
				
			||||||
		.subvendor  = PCI_ANY_ID,
 | 
							.subvendor  = PCI_ANY_ID,
 | 
				
			||||||
		.subdevice  = PCI_ANY_ID,
 | 
							.subdevice  = PCI_ANY_ID,
 | 
				
			||||||
		.setup      = pci_pericom_setup,
 | 
							.setup      = pci_pericom_setup_four_at_eight,
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		.vendor     = PCI_VENDOR_ID_ACCESIO,
 | 
							.vendor     = PCI_VENDOR_ID_ACCESIO,
 | 
				
			||||||
		.device     = PCI_DEVICE_ID_ACCESIO_MPCIE_COM_4SM,
 | 
							.device     = PCI_DEVICE_ID_ACCESIO_MPCIE_COM_4SM,
 | 
				
			||||||
		.subvendor  = PCI_ANY_ID,
 | 
							.subvendor  = PCI_ANY_ID,
 | 
				
			||||||
		.subdevice  = PCI_ANY_ID,
 | 
							.subdevice  = PCI_ANY_ID,
 | 
				
			||||||
		.setup      = pci_pericom_setup,
 | 
							.setup      = pci_pericom_setup_four_at_eight,
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		.vendor     = PCI_VENDOR_ID_ACCESIO,
 | 
							.vendor     = PCI_VENDOR_ID_ACCESIO,
 | 
				
			||||||
		.device     = PCI_DEVICE_ID_ACCESIO_MPCIE_ICM422_4,
 | 
							.device     = PCI_DEVICE_ID_ACCESIO_MPCIE_ICM422_4,
 | 
				
			||||||
		.subvendor  = PCI_ANY_ID,
 | 
							.subvendor  = PCI_ANY_ID,
 | 
				
			||||||
		.subdevice  = PCI_ANY_ID,
 | 
							.subdevice  = PCI_ANY_ID,
 | 
				
			||||||
		.setup      = pci_pericom_setup,
 | 
							.setup      = pci_pericom_setup_four_at_eight,
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		.vendor     = PCI_VENDOR_ID_ACCESIO,
 | 
							.vendor     = PCI_VENDOR_ID_ACCESIO,
 | 
				
			||||||
		.device     = PCI_DEVICE_ID_ACCESIO_MPCIE_ICM485_4,
 | 
							.device     = PCI_DEVICE_ID_ACCESIO_MPCIE_ICM485_4,
 | 
				
			||||||
		.subvendor  = PCI_ANY_ID,
 | 
							.subvendor  = PCI_ANY_ID,
 | 
				
			||||||
		.subdevice  = PCI_ANY_ID,
 | 
							.subdevice  = PCI_ANY_ID,
 | 
				
			||||||
		.setup      = pci_pericom_setup,
 | 
							.setup      = pci_pericom_setup_four_at_eight,
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		.vendor     = PCI_DEVICE_ID_ACCESIO_PCIE_ICM_4S,
 | 
							.vendor     = PCI_DEVICE_ID_ACCESIO_PCIE_ICM_4S,
 | 
				
			||||||
		.device     = PCI_DEVICE_ID_ACCESIO_PCIE_ICM232_4,
 | 
							.device     = PCI_DEVICE_ID_ACCESIO_PCIE_ICM232_4,
 | 
				
			||||||
		.subvendor  = PCI_ANY_ID,
 | 
							.subvendor  = PCI_ANY_ID,
 | 
				
			||||||
		.subdevice  = PCI_ANY_ID,
 | 
							.subdevice  = PCI_ANY_ID,
 | 
				
			||||||
		.setup      = pci_pericom_setup,
 | 
							.setup      = pci_pericom_setup_four_at_eight,
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		.vendor     = PCI_VENDOR_ID_ACCESIO,
 | 
							.vendor     = PCI_VENDOR_ID_ACCESIO,
 | 
				
			||||||
		.device     = PCI_DEVICE_ID_ACCESIO_MPCIE_ICM232_4,
 | 
							.device     = PCI_DEVICE_ID_ACCESIO_MPCIE_ICM232_4,
 | 
				
			||||||
		.subvendor  = PCI_ANY_ID,
 | 
							.subvendor  = PCI_ANY_ID,
 | 
				
			||||||
		.subdevice  = PCI_ANY_ID,
 | 
							.subdevice  = PCI_ANY_ID,
 | 
				
			||||||
		.setup      = pci_pericom_setup,
 | 
							.setup      = pci_pericom_setup_four_at_eight,
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		.vendor     = PCI_VENDOR_ID_ACCESIO,
 | 
							.vendor     = PCI_VENDOR_ID_ACCESIO,
 | 
				
			||||||
		.device     = PCI_DEVICE_ID_ACCESIO_PCIE_COM422_4,
 | 
							.device     = PCI_DEVICE_ID_ACCESIO_PCIE_COM422_4,
 | 
				
			||||||
		.subvendor  = PCI_ANY_ID,
 | 
							.subvendor  = PCI_ANY_ID,
 | 
				
			||||||
		.subdevice  = PCI_ANY_ID,
 | 
							.subdevice  = PCI_ANY_ID,
 | 
				
			||||||
		.setup      = pci_pericom_setup,
 | 
							.setup      = pci_pericom_setup_four_at_eight,
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		.vendor     = PCI_VENDOR_ID_ACCESIO,
 | 
							.vendor     = PCI_VENDOR_ID_ACCESIO,
 | 
				
			||||||
		.device     = PCI_DEVICE_ID_ACCESIO_PCIE_COM485_4,
 | 
							.device     = PCI_DEVICE_ID_ACCESIO_PCIE_COM485_4,
 | 
				
			||||||
		.subvendor  = PCI_ANY_ID,
 | 
							.subvendor  = PCI_ANY_ID,
 | 
				
			||||||
		.subdevice  = PCI_ANY_ID,
 | 
							.subdevice  = PCI_ANY_ID,
 | 
				
			||||||
		.setup      = pci_pericom_setup,
 | 
							.setup      = pci_pericom_setup_four_at_eight,
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		.vendor     = PCI_VENDOR_ID_ACCESIO,
 | 
							.vendor     = PCI_VENDOR_ID_ACCESIO,
 | 
				
			||||||
		.device     = PCI_DEVICE_ID_ACCESIO_PCIE_COM232_4,
 | 
							.device     = PCI_DEVICE_ID_ACCESIO_PCIE_COM232_4,
 | 
				
			||||||
		.subvendor  = PCI_ANY_ID,
 | 
							.subvendor  = PCI_ANY_ID,
 | 
				
			||||||
		.subdevice  = PCI_ANY_ID,
 | 
							.subdevice  = PCI_ANY_ID,
 | 
				
			||||||
		.setup      = pci_pericom_setup,
 | 
							.setup      = pci_pericom_setup_four_at_eight,
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		.vendor     = PCI_VENDOR_ID_ACCESIO,
 | 
							.vendor     = PCI_VENDOR_ID_ACCESIO,
 | 
				
			||||||
		.device     = PCI_DEVICE_ID_ACCESIO_PCIE_COM_4SM,
 | 
							.device     = PCI_DEVICE_ID_ACCESIO_PCIE_COM_4SM,
 | 
				
			||||||
		.subvendor  = PCI_ANY_ID,
 | 
							.subvendor  = PCI_ANY_ID,
 | 
				
			||||||
		.subdevice  = PCI_ANY_ID,
 | 
							.subdevice  = PCI_ANY_ID,
 | 
				
			||||||
		.setup      = pci_pericom_setup,
 | 
							.setup      = pci_pericom_setup_four_at_eight,
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		.vendor     = PCI_VENDOR_ID_ACCESIO,
 | 
							.vendor     = PCI_VENDOR_ID_ACCESIO,
 | 
				
			||||||
		.device     = PCI_DEVICE_ID_ACCESIO_PCIE_ICM_4SM,
 | 
							.device     = PCI_DEVICE_ID_ACCESIO_PCIE_ICM_4SM,
 | 
				
			||||||
		.subvendor  = PCI_ANY_ID,
 | 
							.subvendor  = PCI_ANY_ID,
 | 
				
			||||||
		.subdevice  = PCI_ANY_ID,
 | 
							.subdevice  = PCI_ANY_ID,
 | 
				
			||||||
		.setup      = pci_pericom_setup,
 | 
							.setup      = pci_pericom_setup_four_at_eight,
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	/*
 | 
						{
 | 
				
			||||||
 | 
							.vendor     = PCI_VENDOR_ID_ACCESIO,
 | 
				
			||||||
 | 
							.device     = PCI_ANY_ID,
 | 
				
			||||||
 | 
							.subvendor  = PCI_ANY_ID,
 | 
				
			||||||
 | 
							.subdevice  = PCI_ANY_ID,
 | 
				
			||||||
 | 
							.setup      = pci_pericom_setup,
 | 
				
			||||||
 | 
						},	/*
 | 
				
			||||||
	 * SBS Technologies, Inc., PMC-OCTALPRO 232
 | 
						 * SBS Technologies, Inc., PMC-OCTALPRO 232
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue