diff options
author | Angelo Butti <buttiangelo@gmail.com> | 2016-11-07 16:39:03 +0100 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2016-11-10 14:41:25 +0100 |
commit | 5c31ef91c06db7800ad573174bd92be4df34ecb2 (patch) | |
tree | 172ff2d843b9ee78ad9c4a3e7980fca4010b5477 /drivers/tty | |
parent | 6fc5a520429e29ae84cb9ce8e8c584166a54a1ee (diff) | |
download | linux-5c31ef91c06db7800ad573174bd92be4df34ecb2.tar.bz2 |
8250: FIX Fourth port offset of Pericom PI7C9X7954 boards
Hi,
below patch to fix Fourth port offset of Percom PI7C9X7954 boards.
I had a problem using Fourth port on a pci express serial board based on Pericom
PI7C9X7954. Reading datasheet I notice a "special" offset assign to this port
when used in I/O mode.
Offset 0x0 -> UART 0
Offset 0x8 -> UART 1
Offset 0x10 -> UART 2
Offset 0x38 -> UART 3 <<---- This don't follow a logical sequence
This patch add a different init to last port, to have right offset.
I check also Pericom 7952 and 7958 but that devices follow logical sequence,
so they are ok.
Regards,
Angelo
Signed-off-by: Angelo Butti <buttiangelo@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/tty')
-rw-r--r-- | drivers/tty/serial/8250/8250_pci.c | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c index b98c1578f45a..5aeabf732d74 100644 --- a/drivers/tty/serial/8250/8250_pci.c +++ b/drivers/tty/serial/8250/8250_pci.c @@ -1329,6 +1329,30 @@ static int pci_default_setup(struct serial_private *priv, return setup_port(priv, port, bar, offset, board->reg_shift); } +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; + + 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; + + return setup_port(priv, port, bar, offset, board->reg_shift); +} + static int ce4100_serial_setup(struct serial_private *priv, const struct pciserial_board *board, @@ -2096,6 +2120,16 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = { .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, + }, + /* * PLX */ { |