We may reuse ->setup() for the same purpose as it was done before. Signed-off-by: Andy Shevchenko <andriy.shevchenko@xxxxxxxxxxxxxxx> --- drivers/tty/serial/8250/8250_exar.c | 171 +++++++++++++--------------- 1 file changed, 81 insertions(+), 90 deletions(-) diff --git a/drivers/tty/serial/8250/8250_exar.c b/drivers/tty/serial/8250/8250_exar.c index 956323e2de4a..4e683ca76de0 100644 --- a/drivers/tty/serial/8250/8250_exar.c +++ b/drivers/tty/serial/8250/8250_exar.c @@ -237,14 +237,12 @@ struct exar8250_platform { * struct exar8250_board - board information * @num_ports: number of serial ports * @reg_shift: describes UART register mapping in PCI memory - * @board_init: quirk run once at ->probe() stage before setting up ports * @setup: quirk run at ->probe() stage for each port * @exit: quirk run at ->remove() stage */ struct exar8250_board { unsigned int num_ports; unsigned int reg_shift; - int (*board_init)(struct exar8250 *priv, struct pci_dev *pcidev); int (*setup)(struct exar8250 *priv, struct pci_dev *pcidev, struct uart_8250_port *port, int idx); void (*exit)(struct pci_dev *pcidev); @@ -907,9 +905,6 @@ static int cti_port_setup_common(struct exar8250 *priv, { int ret; - if (priv->osc_freq == 0) - return -EINVAL; - port->port.port_id = idx; port->port.uartclk = priv->osc_freq; @@ -927,6 +922,30 @@ static int cti_port_setup_common(struct exar8250 *priv, return 0; } +static int cti_board_init_fpga(struct exar8250 *priv, struct pci_dev *pcidev) +{ + int ret; + u16 cfg_val; + + // FPGA OSC is fixed to the 33MHz PCI clock + priv->osc_freq = CTI_DEFAULT_FPGA_OSC_FREQ; + + // Enable external interrupts in special cfg space register + ret = pci_read_config_word(pcidev, CTI_FPGA_CFG_INT_EN_REG, &cfg_val); + if (ret) + return pcibios_err_to_errno(ret); + + cfg_val |= CTI_FPGA_CFG_INT_EN_EXT_BIT; + ret = pci_write_config_word(pcidev, CTI_FPGA_CFG_INT_EN_REG, cfg_val); + if (ret) + return pcibios_err_to_errno(ret); + + // RS485 gate needs to be enabled; otherwise RTS/CTS will not work + exar_write_reg(priv, CTI_FPGA_RS485_IO_REG, 0x01); + + return 0; +} + static int cti_port_setup_fpga(struct exar8250 *priv, struct pci_dev *pcidev, struct uart_8250_port *port, @@ -934,6 +953,13 @@ static int cti_port_setup_fpga(struct exar8250 *priv, { enum cti_port_type port_type; unsigned int offset; + int ret; + + if (idx == 0) { + ret = cti_board_init_fpga(priv, pcidev); + if (ret) + return ret; + } port_type = cti_get_port_type_fpga(priv, pcidev, idx); @@ -953,6 +979,12 @@ static int cti_port_setup_fpga(struct exar8250 *priv, return cti_port_setup_common(priv, pcidev, idx, offset, port); } +static void cti_board_init_xr17v35x(struct exar8250 *priv, struct pci_dev *pcidev) +{ + // XR17V35X uses the PCIe clock rather than an oscillator + priv->osc_freq = CTI_DEFAULT_PCIE_OSC_FREQ; +} + static int cti_port_setup_xr17v35x(struct exar8250 *priv, struct pci_dev *pcidev, struct uart_8250_port *port, @@ -962,6 +994,9 @@ static int cti_port_setup_xr17v35x(struct exar8250 *priv, unsigned int offset; int ret; + if (idx == 0) + cti_board_init_xr17v35x(priv, pcidev); + port_type = cti_get_port_type_xr17v35x(priv, pcidev, idx); offset = idx * UART_EXAR_XR17V35X_PORT_OFFSET; @@ -999,6 +1034,22 @@ static int cti_port_setup_xr17v35x(struct exar8250 *priv, return 0; } +static void cti_board_init_xr17v25x(struct exar8250 *priv, struct pci_dev *pcidev) +{ + cti_board_init_osc_freq(priv, pcidev, CTI_EE_OFF_XR17V25X_OSC_FREQ); + + /* enable interrupts on cards that need the "PLX fix" */ + switch (pcidev->subsystem_device) { + case PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_8_XPRS: + case PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_16_XPRS_A: + case PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_16_XPRS_B: + cti_plx_int_enable(priv); + break; + default: + break; + } +} + static int cti_port_setup_xr17v25x(struct exar8250 *priv, struct pci_dev *pcidev, struct uart_8250_port *port, @@ -1008,6 +1059,9 @@ static int cti_port_setup_xr17v25x(struct exar8250 *priv, unsigned int offset; int ret; + if (idx == 0) + cti_board_init_xr17v25x(priv, pcidev); + port_type = cti_get_port_type_xr17c15x_xr17v25x(priv, pcidev, idx); offset = idx * UART_EXAR_XR17V25X_PORT_OFFSET; @@ -1055,6 +1109,25 @@ static int cti_port_setup_xr17v25x(struct exar8250 *priv, return 0; } +static void cti_board_init_xr17c15x(struct exar8250 *priv, struct pci_dev *pcidev) +{ + cti_board_init_osc_freq(priv, pcidev, CTI_EE_OFF_XR17C15X_OSC_FREQ); + + /* enable interrupts on cards that need the "PLX fix" */ + switch (pcidev->subsystem_device) { + case PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_2_XPRS: + case PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_4_XPRS_A: + case PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_4_XPRS_B: + case PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_2_XPRS_OPTO: + case PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_4_XPRS_OPTO_A: + case PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_4_XPRS_OPTO_B: + cti_plx_int_enable(priv); + break; + default: + break; + } +} + static int cti_port_setup_xr17c15x(struct exar8250 *priv, struct pci_dev *pcidev, struct uart_8250_port *port, @@ -1063,6 +1136,9 @@ static int cti_port_setup_xr17c15x(struct exar8250 *priv, enum cti_port_type port_type; unsigned int offset; + if (idx == 0) + cti_board_init_xr17c15x(priv, pcidev); + port_type = cti_get_port_type_xr17c15x_xr17v25x(priv, pcidev, idx); offset = idx * UART_EXAR_XR17C15X_PORT_OFFSET; @@ -1096,78 +1172,6 @@ static int cti_port_setup_xr17c15x(struct exar8250 *priv, return cti_port_setup_common(priv, pcidev, idx, offset, port); } -static int cti_board_init_xr17v35x(struct exar8250 *priv, - struct pci_dev *pcidev) -{ - // XR17V35X uses the PCIe clock rather than an oscillator - priv->osc_freq = CTI_DEFAULT_PCIE_OSC_FREQ; - - return 0; -} - -static int cti_board_init_xr17v25x(struct exar8250 *priv, struct pci_dev *pcidev) -{ - cti_board_init_osc_freq(priv, pcidev, CTI_EE_OFF_XR17V25X_OSC_FREQ); - - /* enable interrupts on cards that need the "PLX fix" */ - switch (pcidev->subsystem_device) { - case PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_8_XPRS: - case PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_16_XPRS_A: - case PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_16_XPRS_B: - cti_plx_int_enable(priv); - break; - default: - break; - } - - return 0; -} - -static int cti_board_init_xr17c15x(struct exar8250 *priv, struct pci_dev *pcidev) -{ - cti_board_init_osc_freq(priv, pcidev, CTI_EE_OFF_XR17C15X_OSC_FREQ); - - /* enable interrupts on cards that need the "PLX fix" */ - switch (pcidev->subsystem_device) { - case PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_2_XPRS: - case PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_4_XPRS_A: - case PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_4_XPRS_B: - case PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_2_XPRS_OPTO: - case PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_4_XPRS_OPTO_A: - case PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_4_XPRS_OPTO_B: - cti_plx_int_enable(priv); - break; - default: - break; - } - - return 0; -} - -static int cti_board_init_fpga(struct exar8250 *priv, struct pci_dev *pcidev) -{ - int ret; - u16 cfg_val; - - // FPGA OSC is fixed to the 33MHz PCI clock - priv->osc_freq = CTI_DEFAULT_FPGA_OSC_FREQ; - - // Enable external interrupts in special cfg space register - ret = pci_read_config_word(pcidev, CTI_FPGA_CFG_INT_EN_REG, &cfg_val); - if (ret) - return pcibios_err_to_errno(ret); - - cfg_val |= CTI_FPGA_CFG_INT_EN_EXT_BIT; - ret = pci_write_config_word(pcidev, CTI_FPGA_CFG_INT_EN_REG, cfg_val); - if (ret) - return pcibios_err_to_errno(ret); - - // RS485 gate needs to be enabled; otherwise RTS/CTS will not work - exar_write_reg(priv, CTI_FPGA_RS485_IO_REG, 0x01); - - return 0; -} - static int pci_xr17c154_setup(struct exar8250 *priv, struct pci_dev *pcidev, struct uart_8250_port *port, int idx) @@ -1574,15 +1578,6 @@ exar_pci_probe(struct pci_dev *pcidev, const struct pci_device_id *ent) if (rc) return rc; - if (board->board_init) { - rc = board->board_init(priv, pcidev); - if (rc) { - dev_err_probe(&pcidev->dev, rc, - "failed to init serial board\n"); - return rc; - } - } - for (i = 0; i < nr_ports && i < maxnr; i++) { rc = board->setup(priv, pcidev, &uart, i); if (rc) { @@ -1664,22 +1659,18 @@ static const struct exar8250_board pbn_fastcom335_8 = { }; static const struct exar8250_board pbn_cti_xr17c15x = { - .board_init = cti_board_init_xr17c15x, .setup = cti_port_setup_xr17c15x, }; static const struct exar8250_board pbn_cti_xr17v25x = { - .board_init = cti_board_init_xr17v25x, .setup = cti_port_setup_xr17v25x, }; static const struct exar8250_board pbn_cti_xr17v35x = { - .board_init = cti_board_init_xr17v35x, .setup = cti_port_setup_xr17v35x, }; static const struct exar8250_board pbn_cti_fpga = { - .board_init = cti_board_init_fpga, .setup = cti_port_setup_fpga, }; -- 2.43.0.rc1.1336.g36b5255a03ac