[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <36a3c24a-59c1-2537-14ef-c750aaa55ea9@accesio.com>
Date: Wed, 17 Nov 2021 17:12:56 -0800
From: Jay Dolan <jay.dolan@...esio.com>
To: Andy Shevchenko <andriy.shevchenko@...ux.intel.com>,
Greg Kroah-Hartman <gregkh@...uxfoundation.org>,
linux-kernel@...r.kernel.org, linux-serial@...r.kernel.org
Cc: Jiri Slaby <jirislaby@...nel.org>
Subject: Re: [PATCH v1 1/2] serial: 8250_pci: Split out Pericom driver
On 11/17/21 6:57 AM, Andy Shevchenko wrote:
> Pericom along with Acces I/O support consumes a lot of LOCs in 8250_pci.c.
> For the sake of easier maintenance, split it to a separate driver.
>
> Signed-off-by: Andy Shevchenko <andriy.shevchenko@...ux.intel.com>
> ---
> drivers/tty/serial/8250/8250_pci.c | 405 +------------------------
> drivers/tty/serial/8250/8250_pericom.c | 217 +++++++++++++
> drivers/tty/serial/8250/Kconfig | 8 +
> drivers/tty/serial/8250/Makefile | 1 +
> 4 files changed, 231 insertions(+), 400 deletions(-)
> create mode 100644 drivers/tty/serial/8250/8250_pericom.c
>
> diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c
> index 8b29a9381c74..f8d68db73db8 100644
> --- a/drivers/tty/serial/8250/8250_pci.c
> +++ b/drivers/tty/serial/8250/8250_pci.c
> @@ -1318,89 +1318,6 @@ static int pci_default_setup(struct serial_private *priv,
>
> return setup_port(priv, port, bar, offset, board->reg_shift);
> }
> -static void
> -pericom_do_set_divisor(struct uart_port *port, unsigned int baud,
> - unsigned int quot, unsigned int quot_frac)
> -{
> - int scr;
> - int lcr;
> -
> - for (scr = 16; scr > 4; scr--) {
> - unsigned int maxrate = port->uartclk / scr;
> - unsigned int divisor = maxrate / baud;
> - int delta = maxrate / divisor - baud;
> -
> - if (baud > maxrate + baud / 50)
> - continue;
> -
> - if (divisor == 0 || delta > baud / 50)
> - divisor++;
> -
> - if (divisor > 0xffff)
> - continue;
> -
> - /* Update delta due to possible divisor change */
> - delta = maxrate / divisor - baud;
> - if (abs(delta) < baud / 50) {
> - lcr = serial_port_in(port, UART_LCR);
> - serial_port_out(port, UART_LCR, lcr | 0x80);
> - serial_port_out(port, UART_DLL, divisor & 0xff);
> - serial_port_out(port, UART_DLM, divisor >> 8 & 0xff);
> - serial_port_out(port, 2, 16 - scr);
> - serial_port_out(port, UART_LCR, lcr);
> - return;
> - }
> - }
> -}
> -static int pci_pericom_setup(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);
> - 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);
> - if (board->flags & FL_BASE_BARS)
> - bar += idx;
> - else
> - offset += idx * board->uart_offset;
> -
> - if (idx==3)
> - offset = 0x38;
> -
> - 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
> ce4100_serial_setup(struct serial_private *priv,
> @@ -1886,42 +1803,6 @@ pci_moxa_setup(struct serial_private *priv,
> #define PCIE_DEVICE_ID_WCH_CH384_8S 0x3853
> #define PCIE_DEVICE_ID_WCH_CH382_2S 0x3253
>
> -#define PCI_VENDOR_ID_ACCESIO 0x494f
> -#define PCI_DEVICE_ID_ACCESIO_PCIE_COM_2SDB 0x1051
> -#define PCI_DEVICE_ID_ACCESIO_MPCIE_COM_2S 0x1053
> -#define PCI_DEVICE_ID_ACCESIO_PCIE_COM_4SDB 0x105C
> -#define PCI_DEVICE_ID_ACCESIO_MPCIE_COM_4S 0x105E
> -#define PCI_DEVICE_ID_ACCESIO_PCIE_COM232_2DB 0x1091
> -#define PCI_DEVICE_ID_ACCESIO_MPCIE_COM232_2 0x1093
> -#define PCI_DEVICE_ID_ACCESIO_PCIE_COM232_4DB 0x1099
> -#define PCI_DEVICE_ID_ACCESIO_MPCIE_COM232_4 0x109B
> -#define PCI_DEVICE_ID_ACCESIO_PCIE_COM_2SMDB 0x10D1
> -#define PCI_DEVICE_ID_ACCESIO_MPCIE_COM_2SM 0x10D3
> -#define PCI_DEVICE_ID_ACCESIO_PCIE_COM_4SMDB 0x10DA
> -#define PCI_DEVICE_ID_ACCESIO_MPCIE_COM_4SM 0x10DC
> -#define PCI_DEVICE_ID_ACCESIO_MPCIE_ICM485_1 0x1108
> -#define PCI_DEVICE_ID_ACCESIO_MPCIE_ICM422_2 0x1110
> -#define PCI_DEVICE_ID_ACCESIO_MPCIE_ICM485_2 0x1111
> -#define PCI_DEVICE_ID_ACCESIO_MPCIE_ICM422_4 0x1118
> -#define PCI_DEVICE_ID_ACCESIO_MPCIE_ICM485_4 0x1119
> -#define PCI_DEVICE_ID_ACCESIO_PCIE_ICM_2S 0x1152
> -#define PCI_DEVICE_ID_ACCESIO_PCIE_ICM_4S 0x115A
> -#define PCI_DEVICE_ID_ACCESIO_PCIE_ICM232_2 0x1190
> -#define PCI_DEVICE_ID_ACCESIO_MPCIE_ICM232_2 0x1191
> -#define PCI_DEVICE_ID_ACCESIO_PCIE_ICM232_4 0x1198
> -#define PCI_DEVICE_ID_ACCESIO_MPCIE_ICM232_4 0x1199
> -#define PCI_DEVICE_ID_ACCESIO_PCIE_ICM_2SM 0x11D0
> -#define PCI_DEVICE_ID_ACCESIO_PCIE_COM422_4 0x105A
> -#define PCI_DEVICE_ID_ACCESIO_PCIE_COM485_4 0x105B
> -#define PCI_DEVICE_ID_ACCESIO_PCIE_COM422_8 0x106A
> -#define PCI_DEVICE_ID_ACCESIO_PCIE_COM485_8 0x106B
> -#define PCI_DEVICE_ID_ACCESIO_PCIE_COM232_4 0x1098
> -#define PCI_DEVICE_ID_ACCESIO_PCIE_COM232_8 0x10A9
> -#define PCI_DEVICE_ID_ACCESIO_PCIE_COM_4SM 0x10D9
> -#define PCI_DEVICE_ID_ACCESIO_PCIE_COM_8SM 0x10E9
> -#define PCI_DEVICE_ID_ACCESIO_PCIE_ICM_4SM 0x11D8
> -
> -
> #define PCI_DEVICE_ID_MOXA_CP102E 0x1024
> #define PCI_DEVICE_ID_MOXA_CP102EL 0x1025
> #define PCI_DEVICE_ID_MOXA_CP104EL_A 0x1045
> @@ -2198,16 +2079,6 @@ static struct pci_serial_quirk pci_serial_quirks[] = {
> .setup = pci_default_setup,
> .exit = pci_plx9050_exit,
> },
> - /*
> - * Pericom (Only 7954 - It have a offset jump for port 4)
> - */
> - {
> - .vendor = PCI_VENDOR_ID_PERICOM,
> - .device = PCI_DEVICE_ID_PERICOM_PI7C9X7954,
> - .subvendor = PCI_ANY_ID,
> - .subdevice = PCI_ANY_ID,
> - .setup = pci_pericom_setup_four_at_eight,
> - },
> /*
> * PLX
> */
> @@ -2238,125 +2109,7 @@ static struct pci_serial_quirk pci_serial_quirks[] = {
> .setup = pci_default_setup,
> .exit = pci_plx9050_exit,
> },
> - {
> - .vendor = PCI_VENDOR_ID_ACCESIO,
> - .device = PCI_DEVICE_ID_ACCESIO_PCIE_COM_4SDB,
> - .subvendor = PCI_ANY_ID,
> - .subdevice = PCI_ANY_ID,
> - .setup = pci_pericom_setup_four_at_eight,
> - },
> - {
> - .vendor = PCI_VENDOR_ID_ACCESIO,
> - .device = PCI_DEVICE_ID_ACCESIO_MPCIE_COM_4S,
> - .subvendor = PCI_ANY_ID,
> - .subdevice = PCI_ANY_ID,
> - .setup = pci_pericom_setup_four_at_eight,
> - },
> - {
> - .vendor = PCI_VENDOR_ID_ACCESIO,
> - .device = PCI_DEVICE_ID_ACCESIO_PCIE_COM232_4DB,
> - .subvendor = PCI_ANY_ID,
> - .subdevice = PCI_ANY_ID,
> - .setup = pci_pericom_setup_four_at_eight,
> - },
> - {
> - .vendor = PCI_VENDOR_ID_ACCESIO,
> - .device = PCI_DEVICE_ID_ACCESIO_MPCIE_COM232_4,
> - .subvendor = PCI_ANY_ID,
> - .subdevice = PCI_ANY_ID,
> - .setup = pci_pericom_setup_four_at_eight,
> - },
> - {
> - .vendor = PCI_VENDOR_ID_ACCESIO,
> - .device = PCI_DEVICE_ID_ACCESIO_PCIE_COM_4SMDB,
> - .subvendor = PCI_ANY_ID,
> - .subdevice = PCI_ANY_ID,
> - .setup = pci_pericom_setup_four_at_eight,
> - },
> - {
> - .vendor = PCI_VENDOR_ID_ACCESIO,
> - .device = PCI_DEVICE_ID_ACCESIO_MPCIE_COM_4SM,
> - .subvendor = PCI_ANY_ID,
> - .subdevice = PCI_ANY_ID,
> - .setup = pci_pericom_setup_four_at_eight,
> - },
> - {
> - .vendor = PCI_VENDOR_ID_ACCESIO,
> - .device = PCI_DEVICE_ID_ACCESIO_MPCIE_ICM422_4,
> - .subvendor = PCI_ANY_ID,
> - .subdevice = PCI_ANY_ID,
> - .setup = pci_pericom_setup_four_at_eight,
> - },
> - {
> - .vendor = PCI_VENDOR_ID_ACCESIO,
> - .device = PCI_DEVICE_ID_ACCESIO_MPCIE_ICM485_4,
> - .subvendor = PCI_ANY_ID,
> - .subdevice = PCI_ANY_ID,
> - .setup = pci_pericom_setup_four_at_eight,
> - },
> - {
> - .vendor = PCI_VENDOR_ID_ACCESIO,
> - .device = PCI_DEVICE_ID_ACCESIO_PCIE_ICM232_4,
> - .subvendor = PCI_ANY_ID,
> - .subdevice = PCI_ANY_ID,
> - .setup = pci_pericom_setup_four_at_eight,
> - },
> - {
> - .vendor = PCI_VENDOR_ID_ACCESIO,
> - .device = PCI_DEVICE_ID_ACCESIO_PCIE_ICM_4S,
> - .subvendor = PCI_ANY_ID,
> - .subdevice = PCI_ANY_ID,
> - .setup = pci_pericom_setup_four_at_eight,
> - },
> - {
> - .vendor = PCI_VENDOR_ID_ACCESIO,
> - .device = PCI_DEVICE_ID_ACCESIO_MPCIE_ICM232_4,
> - .subvendor = PCI_ANY_ID,
> - .subdevice = PCI_ANY_ID,
> - .setup = pci_pericom_setup_four_at_eight,
> - },
> - {
> - .vendor = PCI_VENDOR_ID_ACCESIO,
> - .device = PCI_DEVICE_ID_ACCESIO_PCIE_COM422_4,
> - .subvendor = PCI_ANY_ID,
> - .subdevice = PCI_ANY_ID,
> - .setup = pci_pericom_setup_four_at_eight,
> - },
> - {
> - .vendor = PCI_VENDOR_ID_ACCESIO,
> - .device = PCI_DEVICE_ID_ACCESIO_PCIE_COM485_4,
> - .subvendor = PCI_ANY_ID,
> - .subdevice = PCI_ANY_ID,
> - .setup = pci_pericom_setup_four_at_eight,
> - },
> - {
> - .vendor = PCI_VENDOR_ID_ACCESIO,
> - .device = PCI_DEVICE_ID_ACCESIO_PCIE_COM232_4,
> - .subvendor = PCI_ANY_ID,
> - .subdevice = PCI_ANY_ID,
> - .setup = pci_pericom_setup_four_at_eight,
> - },
> - {
> - .vendor = PCI_VENDOR_ID_ACCESIO,
> - .device = PCI_DEVICE_ID_ACCESIO_PCIE_COM_4SM,
> - .subvendor = PCI_ANY_ID,
> - .subdevice = PCI_ANY_ID,
> - .setup = pci_pericom_setup_four_at_eight,
> - },
> - {
> - .vendor = PCI_VENDOR_ID_ACCESIO,
> - .device = PCI_DEVICE_ID_ACCESIO_PCIE_ICM_4SM,
> - .subvendor = PCI_ANY_ID,
> - .subdevice = PCI_ANY_ID,
> - .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
> */
> {
> @@ -2948,10 +2701,6 @@ enum pci_board_num_t {
> pbn_wch382_2,
> pbn_wch384_4,
> pbn_wch384_8,
> - pbn_pericom_PI7C9X7951,
> - pbn_pericom_PI7C9X7952,
> - pbn_pericom_PI7C9X7954,
> - pbn_pericom_PI7C9X7958,
> pbn_sunix_pci_1s,
> pbn_sunix_pci_2s,
> pbn_sunix_pci_4s,
> @@ -3696,33 +3445,6 @@ static struct pciserial_board pci_boards[] = {
> .uart_offset = 8,
> .first_offset = 0x00,
> },
> - /*
> - * Pericom PI7C9X795[1248] Uno/Dual/Quad/Octal UART
> - */
> - [pbn_pericom_PI7C9X7951] = {
> - .flags = FL_BASE0,
> - .num_ports = 1,
> - .base_baud = 921600,
> - .uart_offset = 0x8,
> - },
> - [pbn_pericom_PI7C9X7952] = {
> - .flags = FL_BASE0,
> - .num_ports = 2,
> - .base_baud = 921600,
> - .uart_offset = 0x8,
> - },
> - [pbn_pericom_PI7C9X7954] = {
> - .flags = FL_BASE0,
> - .num_ports = 4,
> - .base_baud = 921600,
> - .uart_offset = 0x8,
> - },
> - [pbn_pericom_PI7C9X7958] = {
> - .flags = FL_BASE0,
> - .num_ports = 8,
> - .base_baud = 921600,
> - .uart_offset = 0x8,
> - },
> [pbn_sunix_pci_1s] = {
> .num_ports = 1,
> .base_baud = 921600,
> @@ -3834,6 +3556,10 @@ static const struct pci_device_id blacklist[] = {
> { PCI_VDEVICE(EXAR, PCI_ANY_ID), },
> { PCI_VDEVICE(COMMTECH, PCI_ANY_ID), },
>
> + /* Pericom devices */
> + { PCI_VDEVICE(PERICOM, PCI_ANY_ID), },
> + { PCI_VDEVICE(ACCESSIO, PCI_ANY_ID), },
> +
> /* End of the black list */
> { }
> };
> @@ -5027,127 +4753,6 @@ static const struct pci_device_id serial_pci_tbl[] = {
> { PCI_VENDOR_ID_DCI, PCI_DEVICE_ID_DCI_PCCOM8,
> PCI_ANY_ID, PCI_ANY_ID, 0, 0,
> pbn_b3_8_115200 },
> - /*
> - * Pericom PI7C9X795[1248] Uno/Dual/Quad/Octal UART
> - */
> - { PCI_VENDOR_ID_PERICOM, PCI_DEVICE_ID_PERICOM_PI7C9X7951,
> - PCI_ANY_ID, PCI_ANY_ID,
> - 0,
> - 0, pbn_pericom_PI7C9X7951 },
> - { PCI_VENDOR_ID_PERICOM, PCI_DEVICE_ID_PERICOM_PI7C9X7952,
> - PCI_ANY_ID, PCI_ANY_ID,
> - 0,
> - 0, pbn_pericom_PI7C9X7952 },
> - { PCI_VENDOR_ID_PERICOM, PCI_DEVICE_ID_PERICOM_PI7C9X7954,
> - PCI_ANY_ID, PCI_ANY_ID,
> - 0,
> - 0, pbn_pericom_PI7C9X7954 },
> - { PCI_VENDOR_ID_PERICOM, PCI_DEVICE_ID_PERICOM_PI7C9X7958,
> - PCI_ANY_ID, PCI_ANY_ID,
> - 0,
> - 0, pbn_pericom_PI7C9X7958 },
> - /*
> - * ACCES I/O Products quad
> - */
> - { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_PCIE_COM_2SDB,
> - PCI_ANY_ID, PCI_ANY_ID, 0, 0,
> - pbn_pericom_PI7C9X7952 },
> - { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_MPCIE_COM_2S,
> - PCI_ANY_ID, PCI_ANY_ID, 0, 0,
> - pbn_pericom_PI7C9X7952 },
> - { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_PCIE_COM_4SDB,
> - PCI_ANY_ID, PCI_ANY_ID, 0, 0,
> - pbn_pericom_PI7C9X7954 },
> - { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_MPCIE_COM_4S,
> - PCI_ANY_ID, PCI_ANY_ID, 0, 0,
> - pbn_pericom_PI7C9X7954 },
> - { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_PCIE_COM232_2DB,
> - PCI_ANY_ID, PCI_ANY_ID, 0, 0,
> - pbn_pericom_PI7C9X7952 },
> - { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_MPCIE_COM232_2,
> - PCI_ANY_ID, PCI_ANY_ID, 0, 0,
> - pbn_pericom_PI7C9X7952 },
> - { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_PCIE_COM232_4DB,
> - PCI_ANY_ID, PCI_ANY_ID, 0, 0,
> - pbn_pericom_PI7C9X7954 },
> - { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_MPCIE_COM232_4,
> - PCI_ANY_ID, PCI_ANY_ID, 0, 0,
> - pbn_pericom_PI7C9X7954 },
> - { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_PCIE_COM_2SMDB,
> - PCI_ANY_ID, PCI_ANY_ID, 0, 0,
> - pbn_pericom_PI7C9X7952 },
> - { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_MPCIE_COM_2SM,
> - PCI_ANY_ID, PCI_ANY_ID, 0, 0,
> - pbn_pericom_PI7C9X7952 },
> - { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_PCIE_COM_4SMDB,
> - PCI_ANY_ID, PCI_ANY_ID, 0, 0,
> - pbn_pericom_PI7C9X7954 },
> - { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_MPCIE_COM_4SM,
> - PCI_ANY_ID, PCI_ANY_ID, 0, 0,
> - pbn_pericom_PI7C9X7954 },
> - { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_MPCIE_ICM485_1,
> - PCI_ANY_ID, PCI_ANY_ID, 0, 0,
> - pbn_pericom_PI7C9X7951 },
> - { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_MPCIE_ICM422_2,
> - PCI_ANY_ID, PCI_ANY_ID, 0, 0,
> - pbn_pericom_PI7C9X7952 },
> - { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_MPCIE_ICM485_2,
> - PCI_ANY_ID, PCI_ANY_ID, 0, 0,
> - pbn_pericom_PI7C9X7952 },
> - { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_MPCIE_ICM422_4,
> - PCI_ANY_ID, PCI_ANY_ID, 0, 0,
> - pbn_pericom_PI7C9X7954 },
> - { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_MPCIE_ICM485_4,
> - PCI_ANY_ID, PCI_ANY_ID, 0, 0,
> - pbn_pericom_PI7C9X7954 },
> - { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_PCIE_ICM_2S,
> - PCI_ANY_ID, PCI_ANY_ID, 0, 0,
> - pbn_pericom_PI7C9X7952 },
> - { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_PCIE_ICM_4S,
> - PCI_ANY_ID, PCI_ANY_ID, 0, 0,
> - pbn_pericom_PI7C9X7954 },
> - { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_PCIE_ICM232_2,
> - PCI_ANY_ID, PCI_ANY_ID, 0, 0,
> - pbn_pericom_PI7C9X7952 },
> - { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_MPCIE_ICM232_2,
> - PCI_ANY_ID, PCI_ANY_ID, 0, 0,
> - pbn_pericom_PI7C9X7952 },
> - { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_PCIE_ICM232_4,
> - PCI_ANY_ID, PCI_ANY_ID, 0, 0,
> - pbn_pericom_PI7C9X7954 },
> - { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_MPCIE_ICM232_4,
> - PCI_ANY_ID, PCI_ANY_ID, 0, 0,
> - pbn_pericom_PI7C9X7954 },
> - { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_PCIE_ICM_2SM,
> - PCI_ANY_ID, PCI_ANY_ID, 0, 0,
> - pbn_pericom_PI7C9X7952 },
> - { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_PCIE_COM422_4,
> - PCI_ANY_ID, PCI_ANY_ID, 0, 0,
> - pbn_pericom_PI7C9X7954 },
> - { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_PCIE_COM485_4,
> - PCI_ANY_ID, PCI_ANY_ID, 0, 0,
> - pbn_pericom_PI7C9X7954 },
> - { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_PCIE_COM422_8,
> - PCI_ANY_ID, PCI_ANY_ID, 0, 0,
> - pbn_pericom_PI7C9X7958 },
> - { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_PCIE_COM485_8,
> - PCI_ANY_ID, PCI_ANY_ID, 0, 0,
> - pbn_pericom_PI7C9X7958 },
> - { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_PCIE_COM232_4,
> - PCI_ANY_ID, PCI_ANY_ID, 0, 0,
> - pbn_pericom_PI7C9X7954 },
> - { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_PCIE_COM232_8,
> - PCI_ANY_ID, PCI_ANY_ID, 0, 0,
> - pbn_pericom_PI7C9X7958 },
> - { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_PCIE_COM_4SM,
> - PCI_ANY_ID, PCI_ANY_ID, 0, 0,
> - pbn_pericom_PI7C9X7954 },
> - { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_PCIE_COM_8SM,
> - PCI_ANY_ID, PCI_ANY_ID, 0, 0,
> - pbn_pericom_PI7C9X7958 },
> - { PCI_VENDOR_ID_ACCESIO, PCI_DEVICE_ID_ACCESIO_PCIE_ICM_4SM,
> - PCI_ANY_ID, PCI_ANY_ID, 0, 0,
> - pbn_pericom_PI7C9X7954 },
> /*
> * Topic TP560 Data/Fax/Voice 56k modem (reported by Evan Clarke)
> */
> diff --git a/drivers/tty/serial/8250/8250_pericom.c b/drivers/tty/serial/8250/8250_pericom.c
> new file mode 100644
> index 000000000000..322c3b743a38
> --- /dev/null
> +++ b/drivers/tty/serial/8250/8250_pericom.c
> @@ -0,0 +1,217 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/* Driver for Pericom UART */
> +
> +#include <linux/bits.h>
> +#include <linux/module.h>
> +#include <linux/overflow.h>
> +#include <linux/pci.h>
> +
> +#include "8250.h"
> +
> +#define PCI_DEVICE_ID_ACCESSIO_PCIE_COM_2SDB 0x1051
> +#define PCI_DEVICE_ID_ACCESSIO_MPCIE_COM_2S 0x1053
> +#define PCI_DEVICE_ID_ACCESSIO_PCIE_COM422_4 0x105a
> +#define PCI_DEVICE_ID_ACCESSIO_PCIE_COM485_4 0x105b
> +#define PCI_DEVICE_ID_ACCESSIO_PCIE_COM_4SDB 0x105c
> +#define PCI_DEVICE_ID_ACCESSIO_MPCIE_COM_4S 0x105e
> +#define PCI_DEVICE_ID_ACCESSIO_PCIE_COM422_8 0x106a
> +#define PCI_DEVICE_ID_ACCESSIO_PCIE_COM485_8 0x106b
> +#define PCI_DEVICE_ID_ACCESSIO_PCIE_COM232_2DB 0x1091
> +#define PCI_DEVICE_ID_ACCESSIO_MPCIE_COM232_2 0x1093
> +#define PCI_DEVICE_ID_ACCESSIO_PCIE_COM232_4 0x1098
> +#define PCI_DEVICE_ID_ACCESSIO_PCIE_COM232_4DB 0x1099
> +#define PCI_DEVICE_ID_ACCESSIO_MPCIE_COM232_4 0x109b
> +#define PCI_DEVICE_ID_ACCESSIO_PCIE_COM232_8 0x10a9
> +#define PCI_DEVICE_ID_ACCESSIO_PCIE_COM_2SMDB 0x10d1
> +#define PCI_DEVICE_ID_ACCESSIO_MPCIE_COM_2SM 0x10d3
> +#define PCI_DEVICE_ID_ACCESSIO_PCIE_COM_4SM 0x10d9
> +#define PCI_DEVICE_ID_ACCESSIO_PCIE_COM_4SMDB 0x10da
> +#define PCI_DEVICE_ID_ACCESSIO_MPCIE_COM_4SM 0x10dc
> +#define PCI_DEVICE_ID_ACCESSIO_PCIE_COM_8SM 0x10e9
> +#define PCI_DEVICE_ID_ACCESSIO_MPCIE_ICM485_1 0x1108
> +#define PCI_DEVICE_ID_ACCESSIO_MPCIE_ICM422_2 0x1110
> +#define PCI_DEVICE_ID_ACCESSIO_MPCIE_ICM485_2 0x1111
> +#define PCI_DEVICE_ID_ACCESSIO_MPCIE_ICM422_4 0x1118
> +#define PCI_DEVICE_ID_ACCESSIO_MPCIE_ICM485_4 0x1119
> +#define PCI_DEVICE_ID_ACCESSIO_PCIE_ICM_2S 0x1152
> +#define PCI_DEVICE_ID_ACCESSIO_PCIE_ICM_4S 0x115a
> +#define PCI_DEVICE_ID_ACCESSIO_PCIE_ICM232_2 0x1190
> +#define PCI_DEVICE_ID_ACCESSIO_MPCIE_ICM232_2 0x1191
> +#define PCI_DEVICE_ID_ACCESSIO_PCIE_ICM232_4 0x1198
> +#define PCI_DEVICE_ID_ACCESSIO_MPCIE_ICM232_4 0x1199
> +#define PCI_DEVICE_ID_ACCESSIO_PCIE_ICM_2SM 0x11d0
> +#define PCI_DEVICE_ID_ACCESSIO_PCIE_ICM_4SM 0x11d8
> +
> +struct pericom8250 {
> + void __iomem *virt;
> + unsigned int nr;
> + int line[];
> +};
> +
> +#define PERICOM8250_DEFAUL_BAUD_RATE 921600
> +
> +static void pericom_do_set_divisor(struct uart_port *port, unsigned int baud,
> + unsigned int quot, unsigned int quot_frac)
> +{
> + int scr;
> +
> + for (scr = 16 ; scr > 4 ; scr--) {
> + int maxrate = port->uartclk / scr;
> + int divisor = maxrate / baud;
> + int delta = maxrate / divisor - baud;
> +
> + if (baud > maxrate + baud / 50)
> + continue;
> +
> + if (divisor == 0 || delta > baud / 50)
> + divisor++;
> +
> + if (divisor > 0xffff)
> + continue;
> +
> + /* Update delta due to possible divisor change */
> + delta = maxrate / divisor - baud;
> + if (abs(delta) < baud / 50) {
> + int lcr = serial_port_in(port, UART_LCR);
> +
> + serial_port_out(port, UART_LCR, lcr | 0x80);
> + serial_port_out(port, UART_DLL, divisor & 0xff);
> + serial_port_out(port, UART_DLM, (divisor >> 8) & 0xff);
> + serial_port_out(port, 2, 16 - scr);
> + serial_port_out(port, UART_LCR, lcr);
> + return;
> + }
> + }
> +}
> +
> +static int pericom8250_probe(struct pci_dev *pdev, const struct pci_device_id *id)
> +{
> + unsigned int nr, i, bar = 0, maxnr;
> + struct pericom8250 *pericom;
> + struct uart_8250_port uart;
> + int ret;
> +
> + ret = pcim_enable_device(pdev);
> + if (ret)
> + return ret;
> +
> + maxnr = pci_resource_len(pdev, bar) >> 3;
> +
> + if (pdev->vendor == PCI_VENDOR_ID_PERICOM)
> + nr = pdev->device & 0x0f;
> + else if (pdev->vendor == PCI_VENDOR_ID_ACCESSIO)
> + nr = BIT(((pdev->device & 0x38) >> 3) - 1);
> + else
> + nr = 1;
> +
> + pericom = devm_kzalloc(&pdev->dev, struct_size(pericom, line, nr), GFP_KERNEL);
> + if (!pericom)
> + return -ENOMEM;
> +
> + pericom->virt = pcim_iomap(pdev, bar, 0);
> + if (!pericom->virt)
> + return -ENOMEM;
> +
> + memset(&uart, 0, sizeof(uart));
> +
> + uart.port.dev = &pdev->dev;
> + uart.port.irq = pdev->irq;
> + uart.port.private_data = pericom;
> + uart.port.iotype = UPIO_MEM;
> + uart.port.uartclk = PERICOM8250_DEFAUL_BAUD_RATE * 16;
> + uart.port.flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ;
> + uart.port.set_divisor = pericom_do_set_divisor;
> + for (i = 0; i < nr && i < maxnr; i++) {
> + unsigned int offset = (i == 3 && nr == 4) ? 0x38 : i * 0x8;
I'm told this works for PCIe ACCES PIDS, but the PCI PIDs don't have the
fourth port at the wrong address. I didn't know this until just now.
I've never had reason to try and tell if a pci_dev is PCI or PCIe. Can
we query capabilities? It may also be possible to tell by the size of
one of the BARs. I've requested a four port PCI card and should have it
tomorrow.
I'm currently building the previous patch set for testing.
> +
> + uart.port.mapbase = pci_resource_start(pdev, bar) + offset;
> + uart.port.membase = pericom->virt + offset;
> +
> + dev_dbg(&pdev->dev, "Setup PCI port: port %lx, irq %d, type %d\n",
> + uart.port.iobase, uart.port.irq, uart.port.iotype);
> +
> + pericom->line[i] = serial8250_register_8250_port(&uart);
> + if (pericom->line[i] < 0) {
> + dev_err(&pdev->dev,
> + "Couldn't register serial port %lx, irq %d, type %d, error %d\n",
> + uart.port.iobase, uart.port.irq,
> + uart.port.iotype, pericom->line[i]);
> + break;
> + }
> + }
> + pericom->nr = i;
> +
> + pci_set_drvdata(pdev, pericom);
> + return 0;
> +}
> +
> +static void pericom8250_remove(struct pci_dev *pdev)
> +{
> + struct pericom8250 *pericom = pci_get_drvdata(pdev);
> + unsigned int i;
> +
> + for (i = 0; i < pericom->nr; i++)
> + serial8250_unregister_port(pericom->line[i]);
> +}
> +
> +static const struct pci_device_id pericom8250_pci_ids[] = {
> + /*
> + * Pericom PI7C9X795[1248] Uno/Dual/Quad/Octal UART
> + * (Only 7954 has an offset jump for port 4)
> + */
> + { PCI_VDEVICE(PERICOM, PCI_DEVICE_ID_PERICOM_PI7C9X7951) },
> + { PCI_VDEVICE(PERICOM, PCI_DEVICE_ID_PERICOM_PI7C9X7952) },
> + { PCI_VDEVICE(PERICOM, PCI_DEVICE_ID_PERICOM_PI7C9X7954) },
> + { PCI_VDEVICE(PERICOM, PCI_DEVICE_ID_PERICOM_PI7C9X7958) },
> +
> + /*
> + * ACCES I/O Products quad
> + * (Only 7954 has an offset jump for port 4)
> + */
> + { PCI_VDEVICE(ACCESSIO, PCI_DEVICE_ID_ACCESSIO_PCIE_COM_2SDB) },
> + { PCI_VDEVICE(ACCESSIO, PCI_DEVICE_ID_ACCESSIO_MPCIE_COM_2S) },
> + { PCI_VDEVICE(ACCESSIO, PCI_DEVICE_ID_ACCESSIO_PCIE_COM422_4) },
> + { PCI_VDEVICE(ACCESSIO, PCI_DEVICE_ID_ACCESSIO_PCIE_COM485_4) },
> + { PCI_VDEVICE(ACCESSIO, PCI_DEVICE_ID_ACCESSIO_PCIE_COM_4SDB) },
> + { PCI_VDEVICE(ACCESSIO, PCI_DEVICE_ID_ACCESSIO_MPCIE_COM_4S) },
> + { PCI_VDEVICE(ACCESSIO, PCI_DEVICE_ID_ACCESSIO_PCIE_COM422_8) },
> + { PCI_VDEVICE(ACCESSIO, PCI_DEVICE_ID_ACCESSIO_PCIE_COM485_8) },
> + { PCI_VDEVICE(ACCESSIO, PCI_DEVICE_ID_ACCESSIO_PCIE_COM232_2DB) },
> + { PCI_VDEVICE(ACCESSIO, PCI_DEVICE_ID_ACCESSIO_MPCIE_COM232_2) },
> + { PCI_VDEVICE(ACCESSIO, PCI_DEVICE_ID_ACCESSIO_PCIE_COM232_4) },
> + { PCI_VDEVICE(ACCESSIO, PCI_DEVICE_ID_ACCESSIO_PCIE_COM232_4DB) },
> + { PCI_VDEVICE(ACCESSIO, PCI_DEVICE_ID_ACCESSIO_MPCIE_COM232_4) },
> + { PCI_VDEVICE(ACCESSIO, PCI_DEVICE_ID_ACCESSIO_PCIE_COM232_8) },
> + { PCI_VDEVICE(ACCESSIO, PCI_DEVICE_ID_ACCESSIO_PCIE_COM_2SMDB) },
> + { PCI_VDEVICE(ACCESSIO, PCI_DEVICE_ID_ACCESSIO_MPCIE_COM_2SM) },
> + { PCI_VDEVICE(ACCESSIO, PCI_DEVICE_ID_ACCESSIO_PCIE_COM_4SM) },
> + { PCI_VDEVICE(ACCESSIO, PCI_DEVICE_ID_ACCESSIO_PCIE_COM_4SMDB) },
> + { PCI_VDEVICE(ACCESSIO, PCI_DEVICE_ID_ACCESSIO_MPCIE_COM_4SM) },
> + { PCI_VDEVICE(ACCESSIO, PCI_DEVICE_ID_ACCESSIO_PCIE_COM_8SM) },
> + { PCI_VDEVICE(ACCESSIO, PCI_DEVICE_ID_ACCESSIO_MPCIE_ICM485_1) },
> + { PCI_VDEVICE(ACCESSIO, PCI_DEVICE_ID_ACCESSIO_MPCIE_ICM422_2) },
> + { PCI_VDEVICE(ACCESSIO, PCI_DEVICE_ID_ACCESSIO_MPCIE_ICM485_2) },
> + { PCI_VDEVICE(ACCESSIO, PCI_DEVICE_ID_ACCESSIO_MPCIE_ICM422_4) },
> + { PCI_VDEVICE(ACCESSIO, PCI_DEVICE_ID_ACCESSIO_MPCIE_ICM485_4) },
> + { PCI_VDEVICE(ACCESSIO, PCI_DEVICE_ID_ACCESSIO_PCIE_ICM_2S) },
> + { PCI_VDEVICE(ACCESSIO, PCI_DEVICE_ID_ACCESSIO_PCIE_ICM_4S) },
> + { PCI_VDEVICE(ACCESSIO, PCI_DEVICE_ID_ACCESSIO_PCIE_ICM232_2) },
> + { PCI_VDEVICE(ACCESSIO, PCI_DEVICE_ID_ACCESSIO_MPCIE_ICM232_2) },
> + { PCI_VDEVICE(ACCESSIO, PCI_DEVICE_ID_ACCESSIO_PCIE_ICM232_4) },
> + { PCI_VDEVICE(ACCESSIO, PCI_DEVICE_ID_ACCESSIO_MPCIE_ICM232_4) },
> + { PCI_VDEVICE(ACCESSIO, PCI_DEVICE_ID_ACCESSIO_PCIE_ICM_2SM) },
> + { PCI_VDEVICE(ACCESSIO, PCI_DEVICE_ID_ACCESSIO_PCIE_ICM_4SM) },
> + { }
> +};
> +MODULE_DEVICE_TABLE(pci, pericom8250_pci_ids);
> +
> +static struct pci_driver pericom8250_pci_driver = {
> + .name = "8250_pericom",
> + .id_table = pericom8250_pci_ids,
> + .probe = pericom8250_probe,
> + .remove = pericom8250_remove,
> +};
> +module_pci_driver(pericom8250_pci_driver);
> +
> +MODULE_LICENSE("GPL v2");
> +MODULE_DESCRIPTION("Pericom UART driver");
> diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig
> index 8cd11aa63ed5..9d415a38cc71 100644
> --- a/drivers/tty/serial/8250/Kconfig
> +++ b/drivers/tty/serial/8250/Kconfig
> @@ -498,6 +498,14 @@ config SERIAL_8250_MID
> present on the UART found on Intel Medfield SOC and various other
> Intel platforms.
>
> +config SERIAL_8250_PERICOM
> + tristate "Support for Pericom and Acces I/O serial ports"
> + default SERIAL_8250
> + depends on SERIAL_8250 && PCI
> + help
> + Selecting this option will enable handling of the extra features
> + present on the Pericom and Acces I/O UARTs.
> +
> config SERIAL_8250_PXA
> tristate "PXA serial port support"
> depends on SERIAL_8250
> diff --git a/drivers/tty/serial/8250/Makefile b/drivers/tty/serial/8250/Makefile
> index b9bcd73c8997..4e4913e0e4d2 100644
> --- a/drivers/tty/serial/8250/Makefile
> +++ b/drivers/tty/serial/8250/Makefile
> @@ -36,6 +36,7 @@ obj-$(CONFIG_SERIAL_8250_UNIPHIER) += 8250_uniphier.o
> obj-$(CONFIG_SERIAL_8250_INGENIC) += 8250_ingenic.o
> obj-$(CONFIG_SERIAL_8250_LPSS) += 8250_lpss.o
> obj-$(CONFIG_SERIAL_8250_MID) += 8250_mid.o
> +obj-$(CONFIG_SERIAL_8250_PERICOM) += 8250_pericom.o
> obj-$(CONFIG_SERIAL_8250_PXA) += 8250_pxa.o
> obj-$(CONFIG_SERIAL_8250_TEGRA) += 8250_tegra.o
> obj-$(CONFIG_SERIAL_8250_BCM7271) += 8250_bcm7271.o
>
--
Jay Dolan
ACCES I/O Products, Inc.
Senior Linux Kernel Dev
jay.dolan@...esio.com
Powered by blists - more mailing lists