TTY / Serial driver updates for 6.13-rc1

Here is a small set of tty and serial driver updates for 6.13-rc1.
 Nothing major at all this time, only some small changes:
   - few device tree binding updates
   - 8250_exar serial driver updates
   - imx serial driver updates
   - sprd_serial driver updates
   - other tiny serial driver updates, full details in the shortlog
 
 All of these have been in linux-next for a while with one reported
 issue, but that commit has now been reverted.
 
 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 -----BEGIN PGP SIGNATURE-----
 
 iG0EABECAC0WIQT0tgzFv3jCIUoxPcsxR9QN2y37KQUCZ0s3DA8cZ3JlZ0Brcm9h
 aC5jb20ACgkQMUfUDdst+ykmgQCeIDU0GHWFuzEiZNmsO5bLN8AcoFQAn1rlOaHu
 9lOOf7xVSCUBU0GgynI5
 =SEtJ
 -----END PGP SIGNATURE-----

Merge tag 'tty-6.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty

Pull tty / serial driver updates from Greg KH:
 "Here is a small set of tty and serial driver updates for 6.13-rc1.
  Nothing major at all this time, only some small changes:

   - few device tree binding updates

   - 8250_exar serial driver updates

   - imx serial driver updates

   - sprd_serial driver updates

   - other tiny serial driver updates, full details in the shortlog

  All of these have been in linux-next for a while with one reported
  issue, but that commit has now been reverted"

* tag 'tty-6.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty: (37 commits)
  Revert "serial: sh-sci: Clean sci_ports[0] after at earlycon exit"
  serial: amba-pl011: fix build regression
  dt-bindings: serial: Add a new compatible string for ums9632
  serial: sprd: Add support for sc9632
  tty/serial/altera_uart: unwrap error log string
  tty/serial/altera_jtaguart: unwrap error log string
  serial: amba-pl011: Fix RX stall when DMA is used
  tty: ldsic: fix tty_ldisc_autoload sysctl's proc_handler
  serial: 8250_fintek: Add support for F81216E
  serial: sh-sci: Clean sci_ports[0] after at earlycon exit
  tty: atmel_serial: Fix typo retreives to retrieves
  tty: atmel_serial: Use devm_platform_ioremap_resource()
  serial: 8250: omap: Move pm_runtime_get_sync
  tty: serial: samsung: Add Exynos8895 compatible
  dt-bindings: serial: samsung: Add samsung,exynos8895-uart compatible
  serial: 8250_dw: Add Sophgo SG2044 quirk
  dt-bindings: serial: snps-dw-apb-uart: Add Sophgo SG2044 uarts
  dt-bindings: serial: snps,dw-apb-uart: merge duplicate compatible entry.
  altera_jtaguart: Use dev_err() to report error attaching IRQ
  altera_uart: Use dev_err() to report error attaching IRQ handler
  ...
This commit is contained in:
Linus Torvalds 2024-11-30 09:03:16 -08:00
commit d8b78066f4
81 changed files with 385 additions and 245 deletions

View File

@ -18,16 +18,15 @@ properties:
description: prop-encoded-array <a b> description: prop-encoded-array <a b>
$ref: /schemas/types.yaml#/definitions/uint32-array $ref: /schemas/types.yaml#/definitions/uint32-array
items: items:
items: - description: Delay between rts signal and beginning of data sent in
- description: Delay between rts signal and beginning of data sent in milliseconds. It corresponds to the delay before sending data.
milliseconds. It corresponds to the delay before sending data. default: 0
default: 0 maximum: 100
maximum: 100 - description: Delay between end of data sent and rts signal in milliseconds.
- description: Delay between end of data sent and rts signal in milliseconds. It corresponds to the delay after sending data and actual release
It corresponds to the delay after sending data and actual release of the line.
of the line. default: 0
default: 0 maximum: 100
maximum: 100
rs485-rts-active-high: rs485-rts-active-high:
description: drive RTS high when sending (this is the default). description: drive RTS high when sending (this is the default).

View File

@ -27,6 +27,7 @@ properties:
- samsung,exynos4210-uart - samsung,exynos4210-uart
- samsung,exynos5433-uart - samsung,exynos5433-uart
- samsung,exynos850-uart - samsung,exynos850-uart
- samsung,exynos8895-uart
- items: - items:
- enum: - enum:
- samsung,exynos7-uart - samsung,exynos7-uart
@ -160,18 +161,27 @@ allOf:
contains: contains:
enum: enum:
- google,gs101-uart - google,gs101-uart
- samsung,exynos8895-uart
then: then:
required: required:
- samsung,uart-fifosize - samsung,uart-fifosize
properties: properties:
reg-io-width: false
clocks: clocks:
maxItems: 2 maxItems: 2
clock-names: clock-names:
maxItems: 2 maxItems: 2
- if:
properties:
compatible:
contains:
enum:
- google,gs101-uart
then:
properties:
reg-io-width: false
unevaluatedProperties: false unevaluatedProperties: false
examples: examples:

View File

@ -37,6 +37,8 @@ properties:
- const: renesas,rzn1-uart - const: renesas,rzn1-uart
- items: - items:
- enum: - enum:
- brcm,bcm11351-dw-apb-uart
- brcm,bcm21664-dw-apb-uart
- rockchip,px30-uart - rockchip,px30-uart
- rockchip,rk1808-uart - rockchip,rk1808-uart
- rockchip,rk3036-uart - rockchip,rk3036-uart
@ -48,18 +50,13 @@ properties:
- rockchip,rk3328-uart - rockchip,rk3328-uart
- rockchip,rk3368-uart - rockchip,rk3368-uart
- rockchip,rk3399-uart - rockchip,rk3399-uart
- rockchip,rk3528-uart
- rockchip,rk3568-uart - rockchip,rk3568-uart
- rockchip,rk3576-uart
- rockchip,rk3588-uart - rockchip,rk3588-uart
- rockchip,rv1108-uart - rockchip,rv1108-uart
- rockchip,rv1126-uart - rockchip,rv1126-uart
- const: snps,dw-apb-uart - sophgo,sg2044-uart
- items:
- enum:
- brcm,bcm11351-dw-apb-uart
- brcm,bcm21664-dw-apb-uart
- const: snps,dw-apb-uart
- items:
- enum:
- starfive,jh7100-hsuart - starfive,jh7100-hsuart
- starfive,jh7100-uart - starfive,jh7100-uart
- starfive,jh7110-uart - starfive,jh7110-uart

View File

@ -17,6 +17,7 @@ properties:
oneOf: oneOf:
- items: - items:
- enum: - enum:
- sprd,sc9632-uart
- sprd,sc9860-uart - sprd,sc9860-uart
- sprd,sc9863a-uart - sprd,sc9863a-uart
- sprd,ums512-uart - sprd,ums512-uart

View File

@ -15,6 +15,7 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/kfifo.h> #include <linux/kfifo.h>
#include <linux/err.h> #include <linux/err.h>
#include <linux/io.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>

View File

@ -8,6 +8,7 @@
* Supported chipsets: 93c46 & 93c66. * Supported chipsets: 93c46 & 93c66.
*/ */
#include <linux/bits.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/delay.h> #include <linux/delay.h>
@ -102,7 +103,7 @@ static void eeprom_93cx6_write_bits(struct eeprom_93cx6 *eeprom,
/* /*
* Check if this bit needs to be set. * Check if this bit needs to be set.
*/ */
eeprom->reg_data_in = !!(data & (1 << (i - 1))); eeprom->reg_data_in = !!(data & BIT(i - 1));
/* /*
* Write the bit to the eeprom register. * Write the bit to the eeprom register.
@ -152,7 +153,7 @@ static void eeprom_93cx6_read_bits(struct eeprom_93cx6 *eeprom,
* Read if the bit has been set. * Read if the bit has been set.
*/ */
if (eeprom->reg_data_out) if (eeprom->reg_data_out)
buf |= (1 << (i - 1)); buf |= BIT(i - 1);
eeprom_93cx6_pulse_low(eeprom); eeprom_93cx6_pulse_low(eeprom);
} }
@ -186,6 +187,11 @@ void eeprom_93cx6_read(struct eeprom_93cx6 *eeprom, const u8 word,
eeprom_93cx6_write_bits(eeprom, command, eeprom_93cx6_write_bits(eeprom, command,
PCI_EEPROM_WIDTH_OPCODE + eeprom->width); PCI_EEPROM_WIDTH_OPCODE + eeprom->width);
if (has_quirk_extra_read_cycle(eeprom)) {
eeprom_93cx6_pulse_high(eeprom);
eeprom_93cx6_pulse_low(eeprom);
}
/* /*
* Read the requested 16 bits. * Read the requested 16 bits.
*/ */
@ -252,6 +258,11 @@ void eeprom_93cx6_readb(struct eeprom_93cx6 *eeprom, const u8 byte,
eeprom_93cx6_write_bits(eeprom, command, eeprom_93cx6_write_bits(eeprom, command,
PCI_EEPROM_WIDTH_OPCODE + eeprom->width + 1); PCI_EEPROM_WIDTH_OPCODE + eeprom->width + 1);
if (has_quirk_extra_read_cycle(eeprom)) {
eeprom_93cx6_pulse_high(eeprom);
eeprom_93cx6_pulse_low(eeprom);
}
/* /*
* Read the requested 8 bits. * Read the requested 8 bits.
*/ */

View File

@ -569,7 +569,7 @@ static struct platform_driver aspeed_vuart_driver = {
.of_match_table = aspeed_vuart_table, .of_match_table = aspeed_vuart_table,
}, },
.probe = aspeed_vuart_probe, .probe = aspeed_vuart_probe,
.remove_new = aspeed_vuart_remove, .remove = aspeed_vuart_remove,
}; };
module_platform_driver(aspeed_vuart_driver); module_platform_driver(aspeed_vuart_driver);

View File

@ -267,7 +267,7 @@ static struct platform_driver bcm2835aux_serial_driver = {
.pm = pm_ptr(&bcm2835aux_dev_pm_ops), .pm = pm_ptr(&bcm2835aux_dev_pm_ops),
}, },
.probe = bcm2835aux_serial_probe, .probe = bcm2835aux_serial_probe,
.remove_new = bcm2835aux_serial_remove, .remove = bcm2835aux_serial_remove,
}; };
module_platform_driver(bcm2835aux_serial_driver); module_platform_driver(bcm2835aux_serial_driver);

View File

@ -812,7 +812,7 @@ static int brcmuart_handle_irq(struct uart_port *p)
/* /*
* if Receive Data Interrupt is enabled and * if Receive Data Interrupt is enabled and
* we're uing hardware flow control, deassert * we're uing hardware flow control, deassert
* RTS and wait for any chars in the pipline to * RTS and wait for any chars in the pipeline to
* arrive and then check for DR again. * arrive and then check for DR again.
*/ */
if ((ier & UART_IER_RDI) && (up->mcr & UART_MCR_AFE)) { if ((ier & UART_IER_RDI) && (up->mcr & UART_MCR_AFE)) {
@ -1204,7 +1204,7 @@ static struct platform_driver brcmuart_platform_driver = {
.of_match_table = brcmuart_dt_ids, .of_match_table = brcmuart_dt_ids,
}, },
.probe = brcmuart_probe, .probe = brcmuart_probe,
.remove_new = brcmuart_remove, .remove = brcmuart_remove,
}; };
static int __init brcmuart_init(void) static int __init brcmuart_init(void)

View File

@ -750,7 +750,7 @@ static const struct dw8250_platform_data dw8250_renesas_rzn1_data = {
.quirks = DW_UART_QUIRK_CPR_VALUE | DW_UART_QUIRK_IS_DMA_FC, .quirks = DW_UART_QUIRK_CPR_VALUE | DW_UART_QUIRK_IS_DMA_FC,
}; };
static const struct dw8250_platform_data dw8250_starfive_jh7100_data = { static const struct dw8250_platform_data dw8250_skip_set_rate_data = {
.usr_reg = DW_UART_USR, .usr_reg = DW_UART_USR,
.quirks = DW_UART_QUIRK_SKIP_SET_RATE, .quirks = DW_UART_QUIRK_SKIP_SET_RATE,
}; };
@ -760,7 +760,8 @@ static const struct of_device_id dw8250_of_match[] = {
{ .compatible = "cavium,octeon-3860-uart", .data = &dw8250_octeon_3860_data }, { .compatible = "cavium,octeon-3860-uart", .data = &dw8250_octeon_3860_data },
{ .compatible = "marvell,armada-38x-uart", .data = &dw8250_armada_38x_data }, { .compatible = "marvell,armada-38x-uart", .data = &dw8250_armada_38x_data },
{ .compatible = "renesas,rzn1-uart", .data = &dw8250_renesas_rzn1_data }, { .compatible = "renesas,rzn1-uart", .data = &dw8250_renesas_rzn1_data },
{ .compatible = "starfive,jh7100-uart", .data = &dw8250_starfive_jh7100_data }, { .compatible = "sophgo,sg2044-uart", .data = &dw8250_skip_set_rate_data },
{ .compatible = "starfive,jh7100-uart", .data = &dw8250_skip_set_rate_data },
{ /* Sentinel */ } { /* Sentinel */ }
}; };
MODULE_DEVICE_TABLE(of, dw8250_of_match); MODULE_DEVICE_TABLE(of, dw8250_of_match);
@ -796,7 +797,7 @@ static struct platform_driver dw8250_platform_driver = {
.acpi_match_table = dw8250_acpi_match, .acpi_match_table = dw8250_acpi_match,
}, },
.probe = dw8250_probe, .probe = dw8250_probe,
.remove_new = dw8250_remove, .remove = dw8250_remove,
}; };
module_platform_driver(dw8250_platform_driver); module_platform_driver(dw8250_platform_driver);

View File

@ -219,7 +219,7 @@ static struct platform_driver serial8250_em_platform_driver = {
.of_match_table = serial8250_em_dt_ids, .of_match_table = serial8250_em_dt_ids,
}, },
.probe = serial8250_em_probe, .probe = serial8250_em_probe,
.remove_new = serial8250_em_remove, .remove = serial8250_em_remove,
}; };
module_platform_driver(serial8250_em_platform_driver); module_platform_driver(serial8250_em_platform_driver);

View File

@ -11,6 +11,7 @@
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/device.h> #include <linux/device.h>
#include <linux/dmi.h> #include <linux/dmi.h>
#include <linux/eeprom_93cx6.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/math.h> #include <linux/math.h>
@ -135,8 +136,6 @@
#define UART_EXAR_REGB_EECS BIT(5) #define UART_EXAR_REGB_EECS BIT(5)
#define UART_EXAR_REGB_EEDI BIT(6) #define UART_EXAR_REGB_EEDI BIT(6)
#define UART_EXAR_REGB_EEDO BIT(7) #define UART_EXAR_REGB_EEDO BIT(7)
#define UART_EXAR_REGB_EE_ADDR_SIZE 6
#define UART_EXAR_REGB_EE_DATA_SIZE 16
#define UART_EXAR_XR17C15X_PORT_OFFSET 0x200 #define UART_EXAR_XR17C15X_PORT_OFFSET 0x200
#define UART_EXAR_XR17V25X_PORT_OFFSET 0x200 #define UART_EXAR_XR17V25X_PORT_OFFSET 0x200
@ -179,18 +178,19 @@
/* CTI EEPROM offsets */ /* CTI EEPROM offsets */
#define CTI_EE_OFF_XR17C15X_OSC_FREQ 0x04 /* 2 words */ #define CTI_EE_OFF_XR17C15X_OSC_FREQ 0x04 /* 2 words */
#define CTI_EE_OFF_XR17V25X_OSC_FREQ 0x08 /* 2 words */
#define CTI_EE_OFF_XR17C15X_PART_NUM 0x0A /* 4 words */ #define CTI_EE_OFF_XR17C15X_PART_NUM 0x0A /* 4 words */
#define CTI_EE_OFF_XR17V25X_PART_NUM 0x0E /* 4 words */
#define CTI_EE_OFF_XR17C15X_SERIAL_NUM 0x0E /* 1 word */ #define CTI_EE_OFF_XR17C15X_SERIAL_NUM 0x0E /* 1 word */
#define CTI_EE_OFF_XR17V25X_OSC_FREQ 0x08 /* 2 words */
#define CTI_EE_OFF_XR17V25X_PART_NUM 0x0E /* 4 words */
#define CTI_EE_OFF_XR17V25X_SERIAL_NUM 0x12 /* 1 word */ #define CTI_EE_OFF_XR17V25X_SERIAL_NUM 0x12 /* 1 word */
#define CTI_EE_OFF_XR17V35X_SERIAL_NUM 0x11 /* 2 word */ #define CTI_EE_OFF_XR17V35X_SERIAL_NUM 0x11 /* 2 word */
#define CTI_EE_OFF_XR17V35X_BRD_FLAGS 0x13 /* 1 word */ #define CTI_EE_OFF_XR17V35X_BRD_FLAGS 0x13 /* 1 word */
#define CTI_EE_OFF_XR17V35X_PORT_FLAGS 0x14 /* 1 word */ #define CTI_EE_OFF_XR17V35X_PORT_FLAGS 0x14 /* 1 word */
#define CTI_EE_MASK_PORT_FLAGS_TYPE GENMASK(7, 0) #define CTI_EE_MASK_PORT_FLAGS_TYPE GENMASK(7, 0)
#define CTI_EE_MASK_OSC_FREQ_LOWER GENMASK(15, 0) #define CTI_EE_MASK_OSC_FREQ GENMASK(31, 0)
#define CTI_EE_MASK_OSC_FREQ_UPPER GENMASK(31, 16)
#define CTI_FPGA_RS485_IO_REG 0x2008 #define CTI_FPGA_RS485_IO_REG 0x2008
#define CTI_FPGA_CFG_INT_EN_REG 0x48 #define CTI_FPGA_CFG_INT_EN_REG 0x48
@ -252,6 +252,7 @@ struct exar8250 {
unsigned int nr; unsigned int nr;
unsigned int osc_freq; unsigned int osc_freq;
struct exar8250_board *board; struct exar8250_board *board;
struct eeprom_93cx6 eeprom;
void __iomem *virt; void __iomem *virt;
int line[]; int line[];
}; };
@ -267,92 +268,37 @@ static inline u8 exar_read_reg(struct exar8250 *priv, unsigned int reg)
return readb(priv->virt + reg); return readb(priv->virt + reg);
} }
static inline void exar_ee_select(struct exar8250 *priv) static void exar_eeprom_93cx6_reg_read(struct eeprom_93cx6 *eeprom)
{ {
// Set chip select pin high to enable EEPROM reads/writes struct exar8250 *priv = eeprom->data;
exar_write_reg(priv, UART_EXAR_REGB, UART_EXAR_REGB_EECS); u8 regb = exar_read_reg(priv, UART_EXAR_REGB);
// Min ~500ns delay needed between CS assert and EEPROM access
udelay(1); /* EECK and EECS always read 0 from REGB so only set EEDO */
eeprom->reg_data_out = regb & UART_EXAR_REGB_EEDO;
} }
static inline void exar_ee_deselect(struct exar8250 *priv) static void exar_eeprom_93cx6_reg_write(struct eeprom_93cx6 *eeprom)
{ {
exar_write_reg(priv, UART_EXAR_REGB, 0x00); struct exar8250 *priv = eeprom->data;
u8 regb = 0;
if (eeprom->reg_data_in)
regb |= UART_EXAR_REGB_EEDI;
if (eeprom->reg_data_clock)
regb |= UART_EXAR_REGB_EECK;
if (eeprom->reg_chip_select)
regb |= UART_EXAR_REGB_EECS;
exar_write_reg(priv, UART_EXAR_REGB, regb);
} }
static inline void exar_ee_write_bit(struct exar8250 *priv, u8 bit) static void exar_eeprom_init(struct exar8250 *priv)
{ {
u8 value = UART_EXAR_REGB_EECS; priv->eeprom.data = priv;
priv->eeprom.register_read = exar_eeprom_93cx6_reg_read;
if (bit) priv->eeprom.register_write = exar_eeprom_93cx6_reg_write;
value |= UART_EXAR_REGB_EEDI; priv->eeprom.width = PCI_EEPROM_WIDTH_93C46;
priv->eeprom.quirks |= PCI_EEPROM_QUIRK_EXTRA_READ_CYCLE;
// Clock out the bit on the EEPROM interface
exar_write_reg(priv, UART_EXAR_REGB, value);
// 2us delay = ~500khz clock speed
udelay(2);
value |= UART_EXAR_REGB_EECK;
exar_write_reg(priv, UART_EXAR_REGB, value);
udelay(2);
}
static inline u8 exar_ee_read_bit(struct exar8250 *priv)
{
u8 regb;
u8 value = UART_EXAR_REGB_EECS;
// Clock in the bit on the EEPROM interface
exar_write_reg(priv, UART_EXAR_REGB, value);
// 2us delay = ~500khz clock speed
udelay(2);
value |= UART_EXAR_REGB_EECK;
exar_write_reg(priv, UART_EXAR_REGB, value);
udelay(2);
regb = exar_read_reg(priv, UART_EXAR_REGB);
return (regb & UART_EXAR_REGB_EEDO ? 1 : 0);
}
/**
* exar_ee_read() - Read a word from the EEPROM
* @priv: Device's private structure
* @ee_addr: Offset of EEPROM to read word from
*
* Read a single 16bit word from an Exar UART's EEPROM.
* The type of the EEPROM is AT93C46D.
*
* Return: EEPROM word
*/
static u16 exar_ee_read(struct exar8250 *priv, u8 ee_addr)
{
int i;
u16 data = 0;
exar_ee_select(priv);
// Send read command (opcode 110)
exar_ee_write_bit(priv, 1);
exar_ee_write_bit(priv, 1);
exar_ee_write_bit(priv, 0);
// Send address to read from
for (i = UART_EXAR_REGB_EE_ADDR_SIZE - 1; i >= 0; i--)
exar_ee_write_bit(priv, ee_addr & BIT(i));
// Read data 1 bit at a time starting with a dummy bit
for (i = UART_EXAR_REGB_EE_DATA_SIZE; i >= 0; i--) {
if (exar_ee_read_bit(priv))
data |= BIT(i);
}
exar_ee_deselect(priv);
return data;
} }
/** /**
@ -360,7 +306,7 @@ static u16 exar_ee_read(struct exar8250 *priv, u8 ee_addr)
* @priv: Device's private structure * @priv: Device's private structure
* @mpio_num: MPIO number/offset to configure * @mpio_num: MPIO number/offset to configure
* *
* Configure a single MPIO as an output and disable tristate. It is reccomended * Configure a single MPIO as an output and disable tristate. It is recommended
* to set the level with exar_mpio_set_high()/exar_mpio_set_low() prior to * to set the level with exar_mpio_set_high()/exar_mpio_set_low() prior to
* calling this function to ensure default MPIO pin state. * calling this function to ensure default MPIO pin state.
* *
@ -516,7 +462,7 @@ static int xr17v35x_startup(struct uart_port *port)
serial_port_out(port, UART_XR_EFR, UART_EFR_ECB); serial_port_out(port, UART_XR_EFR, UART_EFR_ECB);
/* /*
* Make sure all interrups are masked until initialization is * Make sure all interrupts are masked until initialization is
* complete and the FIFOs are cleared * complete and the FIFOs are cleared
* *
* Synchronize UART_IER access against the console. * Synchronize UART_IER access against the console.
@ -696,20 +642,16 @@ static int cti_plx_int_enable(struct exar8250 *priv)
*/ */
static int cti_read_osc_freq(struct exar8250 *priv, u8 eeprom_offset) static int cti_read_osc_freq(struct exar8250 *priv, u8 eeprom_offset)
{ {
u16 lower_word; __le16 ee_words[2];
u16 upper_word; u32 osc_freq;
lower_word = exar_ee_read(priv, eeprom_offset); eeprom_93cx6_multiread(&priv->eeprom, eeprom_offset, ee_words, ARRAY_SIZE(ee_words));
// Check if EEPROM word was blank
if (lower_word == 0xFFFF) osc_freq = le16_to_cpu(ee_words[0]) | (le16_to_cpu(ee_words[1]) << 16);
if (osc_freq == CTI_EE_MASK_OSC_FREQ)
return -EIO; return -EIO;
upper_word = exar_ee_read(priv, (eeprom_offset + 1)); return osc_freq;
if (upper_word == 0xFFFF)
return -EIO;
return FIELD_PREP(CTI_EE_MASK_OSC_FREQ_LOWER, lower_word) |
FIELD_PREP(CTI_EE_MASK_OSC_FREQ_UPPER, upper_word);
} }
/** /**
@ -833,7 +775,7 @@ static enum cti_port_type cti_get_port_type_xr17v35x(struct exar8250 *priv,
u8 offset; u8 offset;
offset = CTI_EE_OFF_XR17V35X_PORT_FLAGS + port_num; offset = CTI_EE_OFF_XR17V35X_PORT_FLAGS + port_num;
port_flags = exar_ee_read(priv, offset); eeprom_93cx6_read(&priv->eeprom, offset, &port_flags);
port_type = FIELD_GET(CTI_EE_MASK_PORT_FLAGS_TYPE, port_flags); port_type = FIELD_GET(CTI_EE_MASK_PORT_FLAGS_TYPE, port_flags);
if (CTI_PORT_TYPE_VALID(port_type)) if (CTI_PORT_TYPE_VALID(port_type))
@ -1551,6 +1493,8 @@ exar_pci_probe(struct pci_dev *pcidev, const struct pci_device_id *ent)
if (rc) if (rc)
return rc; return rc;
exar_eeprom_init(priv);
for (i = 0; i < nr_ports && i < maxnr; i++) { for (i = 0; i < nr_ports && i < maxnr; i++) {
rc = board->setup(priv, pcidev, &uart, i); rc = board->setup(priv, pcidev, &uart, i);
if (rc) { if (rc) {

View File

@ -21,6 +21,7 @@
#define CHIP_ID_F81866 0x1010 #define CHIP_ID_F81866 0x1010
#define CHIP_ID_F81966 0x0215 #define CHIP_ID_F81966 0x0215
#define CHIP_ID_F81216AD 0x1602 #define CHIP_ID_F81216AD 0x1602
#define CHIP_ID_F81216E 0x1617
#define CHIP_ID_F81216H 0x0501 #define CHIP_ID_F81216H 0x0501
#define CHIP_ID_F81216 0x0802 #define CHIP_ID_F81216 0x0802
#define VENDOR_ID1 0x23 #define VENDOR_ID1 0x23
@ -125,7 +126,7 @@ static int fintek_8250_enter_key(u16 base_port, u8 key)
if (!request_muxed_region(base_port, 2, "8250_fintek")) if (!request_muxed_region(base_port, 2, "8250_fintek"))
return -EBUSY; return -EBUSY;
/* Force to deactive all SuperIO in this base_port */ /* Force to deactivate all SuperIO in this base_port */
outb(EXIT_KEY, base_port + ADDR_PORT); outb(EXIT_KEY, base_port + ADDR_PORT);
outb(key, base_port + ADDR_PORT); outb(key, base_port + ADDR_PORT);
@ -158,6 +159,7 @@ static int fintek_8250_check_id(struct fintek_8250 *pdata)
case CHIP_ID_F81866: case CHIP_ID_F81866:
case CHIP_ID_F81966: case CHIP_ID_F81966:
case CHIP_ID_F81216AD: case CHIP_ID_F81216AD:
case CHIP_ID_F81216E:
case CHIP_ID_F81216H: case CHIP_ID_F81216H:
case CHIP_ID_F81216: case CHIP_ID_F81216:
break; break;
@ -181,6 +183,7 @@ static int fintek_8250_get_ldn_range(struct fintek_8250 *pdata, int *min,
return 0; return 0;
case CHIP_ID_F81216AD: case CHIP_ID_F81216AD:
case CHIP_ID_F81216E:
case CHIP_ID_F81216H: case CHIP_ID_F81216H:
case CHIP_ID_F81216: case CHIP_ID_F81216:
*min = F81216_LDN_LOW; *min = F81216_LDN_LOW;
@ -250,6 +253,7 @@ static void fintek_8250_set_irq_mode(struct fintek_8250 *pdata, bool is_level)
break; break;
case CHIP_ID_F81216AD: case CHIP_ID_F81216AD:
case CHIP_ID_F81216E:
case CHIP_ID_F81216H: case CHIP_ID_F81216H:
case CHIP_ID_F81216: case CHIP_ID_F81216:
sio_write_mask_reg(pdata, FINTEK_IRQ_MODE, IRQ_SHARE, sio_write_mask_reg(pdata, FINTEK_IRQ_MODE, IRQ_SHARE,
@ -263,7 +267,8 @@ static void fintek_8250_set_irq_mode(struct fintek_8250 *pdata, bool is_level)
static void fintek_8250_set_max_fifo(struct fintek_8250 *pdata) static void fintek_8250_set_max_fifo(struct fintek_8250 *pdata)
{ {
switch (pdata->pid) { switch (pdata->pid) {
case CHIP_ID_F81216H: /* 128Bytes FIFO */ case CHIP_ID_F81216E: /* 128Bytes FIFO */
case CHIP_ID_F81216H:
case CHIP_ID_F81966: case CHIP_ID_F81966:
case CHIP_ID_F81866: case CHIP_ID_F81866:
sio_write_mask_reg(pdata, FIFO_CTRL, sio_write_mask_reg(pdata, FIFO_CTRL,
@ -297,6 +302,7 @@ static void fintek_8250_set_termios(struct uart_port *port,
goto exit; goto exit;
switch (pdata->pid) { switch (pdata->pid) {
case CHIP_ID_F81216E:
case CHIP_ID_F81216H: case CHIP_ID_F81216H:
reg = RS485; reg = RS485;
break; break;
@ -346,6 +352,7 @@ static void fintek_8250_set_termios_handler(struct uart_8250_port *uart)
struct fintek_8250 *pdata = uart->port.private_data; struct fintek_8250 *pdata = uart->port.private_data;
switch (pdata->pid) { switch (pdata->pid) {
case CHIP_ID_F81216E:
case CHIP_ID_F81216H: case CHIP_ID_F81216H:
case CHIP_ID_F81966: case CHIP_ID_F81966:
case CHIP_ID_F81866: case CHIP_ID_F81866:
@ -438,6 +445,11 @@ static void fintek_8250_set_rs485_handler(struct uart_8250_port *uart)
uart->port.rs485_supported = fintek_8250_rs485_supported; uart->port.rs485_supported = fintek_8250_rs485_supported;
break; break;
case CHIP_ID_F81216E: /* F81216E does not support RS485 delays */
uart->port.rs485_config = fintek_8250_rs485_config;
uart->port.rs485_supported = fintek_8250_rs485_supported;
break;
default: /* No RS485 Auto direction functional */ default: /* No RS485 Auto direction functional */
break; break;
} }

View File

@ -179,7 +179,7 @@ static struct platform_driver fsl8250_platform_driver = {
.acpi_match_table = ACPI_PTR(fsl_8250_acpi_id), .acpi_match_table = ACPI_PTR(fsl_8250_acpi_id),
}, },
.probe = fsl8250_acpi_probe, .probe = fsl8250_acpi_probe,
.remove_new = fsl8250_acpi_remove, .remove = fsl8250_acpi_remove,
}; };
module_platform_driver(fsl8250_platform_driver); module_platform_driver(fsl8250_platform_driver);

View File

@ -361,7 +361,7 @@ static struct platform_driver ingenic_uart_platform_driver = {
.of_match_table = of_match, .of_match_table = of_match,
}, },
.probe = ingenic_uart_probe, .probe = ingenic_uart_probe,
.remove_new = ingenic_uart_remove, .remove = ingenic_uart_remove,
}; };
module_platform_driver(ingenic_uart_platform_driver); module_platform_driver(ingenic_uart_platform_driver);

View File

@ -84,7 +84,7 @@ static void serial8250_ioc3_remove(struct platform_device *pdev)
static struct platform_driver serial8250_ioc3_driver = { static struct platform_driver serial8250_ioc3_driver = {
.probe = serial8250_ioc3_probe, .probe = serial8250_ioc3_probe,
.remove_new = serial8250_ioc3_remove, .remove = serial8250_ioc3_remove,
.driver = { .driver = {
.name = "ioc3-serial8250", .name = "ioc3-serial8250",
} }

View File

@ -195,7 +195,7 @@ MODULE_DEVICE_TABLE(of, lpc18xx_serial_match);
static struct platform_driver lpc18xx_serial_driver = { static struct platform_driver lpc18xx_serial_driver = {
.probe = lpc18xx_serial_probe, .probe = lpc18xx_serial_probe,
.remove_new = lpc18xx_serial_remove, .remove = lpc18xx_serial_remove,
.driver = { .driver = {
.name = "lpc18xx-uart", .name = "lpc18xx-uart",
.of_match_table = lpc18xx_serial_match, .of_match_table = lpc18xx_serial_match,

View File

@ -346,8 +346,8 @@ mtk8250_set_termios(struct uart_port *port, struct ktermios *termios,
/* /*
* Mediatek UARTs use an extra highspeed register (MTK_UART_HIGHS) * Mediatek UARTs use an extra highspeed register (MTK_UART_HIGHS)
* *
* We need to recalcualte the quot register, as the claculation depends * We need to recalculate the quot register, as the calculation depends
* on the vaule in the highspeed register. * on the value in the highspeed register.
* *
* Some baudrates are not supported by the chip, so we use the next * Some baudrates are not supported by the chip, so we use the next
* lower rate supported and update termios c_flag. * lower rate supported and update termios c_flag.
@ -654,7 +654,7 @@ static struct platform_driver mtk8250_platform_driver = {
.of_match_table = mtk8250_of_match, .of_match_table = mtk8250_of_match,
}, },
.probe = mtk8250_probe, .probe = mtk8250_probe,
.remove_new = mtk8250_remove, .remove = mtk8250_remove,
}; };
module_platform_driver(mtk8250_platform_driver); module_platform_driver(mtk8250_platform_driver);

View File

@ -352,7 +352,7 @@ static struct platform_driver of_platform_serial_driver = {
.pm = &of_serial_pm_ops, .pm = &of_serial_pm_ops,
}, },
.probe = of_platform_serial_probe, .probe = of_platform_serial_probe,
.remove_new = of_platform_serial_remove, .remove = of_platform_serial_remove,
}; };
module_platform_driver(of_platform_serial_driver); module_platform_driver(of_platform_serial_driver);

View File

@ -776,12 +776,12 @@ static void omap_8250_shutdown(struct uart_port *port)
struct uart_8250_port *up = up_to_u8250p(port); struct uart_8250_port *up = up_to_u8250p(port);
struct omap8250_priv *priv = port->private_data; struct omap8250_priv *priv = port->private_data;
pm_runtime_get_sync(port->dev);
flush_work(&priv->qos_work); flush_work(&priv->qos_work);
if (up->dma) if (up->dma)
omap_8250_rx_dma_flush(up); omap_8250_rx_dma_flush(up);
pm_runtime_get_sync(port->dev);
serial_out(up, UART_OMAP_WER, 0); serial_out(up, UART_OMAP_WER, 0);
if (priv->habit & UART_HAS_EFR2) if (priv->habit & UART_HAS_EFR2)
serial_out(up, UART_OMAP_EFR2, 0x0); serial_out(up, UART_OMAP_EFR2, 0x0);
@ -1304,7 +1304,7 @@ static void am654_8250_handle_rx_dma(struct uart_8250_port *up, u8 iir,
/* /*
* This is mostly serial8250_handle_irq(). We have a slightly different DMA * This is mostly serial8250_handle_irq(). We have a slightly different DMA
* hoook for RX/TX and need different logic for them in the ISR. Therefore we * hook for RX/TX and need different logic for them in the ISR. Therefore we
* use the default routine in the non-DMA case and this one for with DMA. * use the default routine in the non-DMA case and this one for with DMA.
*/ */
static int omap_8250_dma_handle_irq(struct uart_port *port) static int omap_8250_dma_handle_irq(struct uart_port *port)
@ -1338,7 +1338,7 @@ static int omap_8250_dma_handle_irq(struct uart_port *port)
serial8250_tx_chars(up); serial8250_tx_chars(up);
} else { } else {
/* /*
* try again due to an earlier failer which * try again due to an earlier failure which
* might have been resolved by now. * might have been resolved by now.
*/ */
if (omap_8250_tx_dma(up)) if (omap_8250_tx_dma(up))
@ -1867,7 +1867,7 @@ static struct platform_driver omap8250_platform_driver = {
.of_match_table = omap8250_dt_ids, .of_match_table = omap8250_dt_ids,
}, },
.probe = omap8250_probe, .probe = omap8250_probe,
.remove_new = omap8250_remove, .remove = omap8250_remove,
}; };
module_platform_driver(omap8250_platform_driver); module_platform_driver(omap8250_platform_driver);

View File

@ -285,7 +285,7 @@ MODULE_DEVICE_TABLE(acpi, acpi_platform_serial_table);
static struct platform_driver serial8250_isa_driver = { static struct platform_driver serial8250_isa_driver = {
.probe = serial8250_probe, .probe = serial8250_probe,
.remove_new = serial8250_remove, .remove = serial8250_remove,
.suspend = serial8250_suspend, .suspend = serial8250_suspend,
.resume = serial8250_resume, .resume = serial8250_resume,
.driver = { .driver = {

View File

@ -154,7 +154,7 @@ static void serial_pxa_remove(struct platform_device *pdev)
static struct platform_driver serial_pxa_driver = { static struct platform_driver serial_pxa_driver = {
.probe = serial_pxa_probe, .probe = serial_pxa_probe,
.remove_new = serial_pxa_remove, .remove = serial_pxa_remove,
.driver = { .driver = {
.name = "pxa2xx-uart", .name = "pxa2xx-uart",

View File

@ -182,7 +182,7 @@ static struct platform_driver tegra_uart_driver = {
.acpi_match_table = ACPI_PTR(tegra_uart_acpi_match), .acpi_match_table = ACPI_PTR(tegra_uart_acpi_match),
}, },
.probe = tegra_uart_probe, .probe = tegra_uart_probe,
.remove_new = tegra_uart_remove, .remove = tegra_uart_remove,
}; };
module_platform_driver(tegra_uart_driver); module_platform_driver(tegra_uart_driver);

View File

@ -282,7 +282,7 @@ MODULE_DEVICE_TABLE(of, uniphier_uart_match);
static struct platform_driver uniphier_uart_platform_driver = { static struct platform_driver uniphier_uart_platform_driver = {
.probe = uniphier_uart_probe, .probe = uniphier_uart_probe,
.remove_new = uniphier_uart_remove, .remove = uniphier_uart_remove,
.driver = { .driver = {
.name = "uniphier-uart", .name = "uniphier-uart",
.of_match_table = uniphier_uart_match, .of_match_table = uniphier_uart_match,

View File

@ -150,6 +150,7 @@ config SERIAL_8250_EXAR
tristate "8250/16550 Exar/Commtech PCI/PCIe device support" tristate "8250/16550 Exar/Commtech PCI/PCIe device support"
depends on SERIAL_8250 && PCI depends on SERIAL_8250 && PCI
select SERIAL_8250_PCILIB select SERIAL_8250_PCILIB
select EEPROM_93CX6
default SERIAL_8250 default SERIAL_8250
help help
This builds support for XR17C1xx, XR17V3xx and some Commtech This builds support for XR17C1xx, XR17V3xx and some Commtech

View File

@ -175,8 +175,8 @@ static int altera_jtaguart_startup(struct uart_port *port)
ret = request_irq(port->irq, altera_jtaguart_interrupt, 0, ret = request_irq(port->irq, altera_jtaguart_interrupt, 0,
DRV_NAME, port); DRV_NAME, port);
if (ret) { if (ret) {
pr_err(DRV_NAME ": unable to attach Altera JTAG UART %d " dev_err(port->dev, "unable to attach Altera JTAG UART %d interrupt vector=%d\n",
"interrupt vector=%d\n", port->line, port->irq); port->line, port->irq);
return ret; return ret;
} }
@ -449,7 +449,7 @@ MODULE_DEVICE_TABLE(of, altera_jtaguart_match);
static struct platform_driver altera_jtaguart_platform_driver = { static struct platform_driver altera_jtaguart_platform_driver = {
.probe = altera_jtaguart_probe, .probe = altera_jtaguart_probe,
.remove_new = altera_jtaguart_remove, .remove = altera_jtaguart_remove,
.driver = { .driver = {
.name = DRV_NAME, .name = DRV_NAME,
.of_match_table = of_match_ptr(altera_jtaguart_match), .of_match_table = of_match_ptr(altera_jtaguart_match),

View File

@ -307,8 +307,8 @@ static int altera_uart_startup(struct uart_port *port)
ret = request_irq(port->irq, altera_uart_interrupt, 0, ret = request_irq(port->irq, altera_uart_interrupt, 0,
dev_name(port->dev), port); dev_name(port->dev), port);
if (ret) { if (ret) {
pr_err(DRV_NAME ": unable to attach Altera UART %d " dev_err(port->dev, "unable to attach Altera UART %d interrupt vector=%d\n",
"interrupt vector=%d\n", port->line, port->irq); port->line, port->irq);
return ret; return ret;
} }
} }
@ -617,7 +617,7 @@ MODULE_DEVICE_TABLE(of, altera_uart_match);
static struct platform_driver altera_uart_platform_driver = { static struct platform_driver altera_uart_platform_driver = {
.probe = altera_uart_probe, .probe = altera_uart_probe,
.remove_new = altera_uart_remove, .remove = altera_uart_remove,
.driver = { .driver = {
.name = DRV_NAME, .name = DRV_NAME,
.of_match_table = of_match_ptr(altera_uart_match), .of_match_table = of_match_ptr(altera_uart_match),

View File

@ -1819,6 +1819,13 @@ static void pl011_unthrottle_rx(struct uart_port *port)
pl011_write(uap->im, uap, REG_IMSC); pl011_write(uap->im, uap, REG_IMSC);
#ifdef CONFIG_DMA_ENGINE
if (uap->using_rx_dma) {
uap->dmacr |= UART011_RXDMAE;
pl011_write(uap->dmacr, uap, REG_DMACR);
}
#endif
uart_port_unlock_irqrestore(&uap->port, flags); uart_port_unlock_irqrestore(&uap->port, flags);
} }
@ -2937,7 +2944,7 @@ MODULE_DEVICE_TABLE(acpi, sbsa_uart_acpi_match);
static struct platform_driver arm_sbsa_uart_platform_driver = { static struct platform_driver arm_sbsa_uart_platform_driver = {
.probe = sbsa_uart_probe, .probe = sbsa_uart_probe,
.remove_new = sbsa_uart_remove, .remove = sbsa_uart_remove,
.driver = { .driver = {
.name = "sbsa-uart", .name = "sbsa-uart",
.pm = &pl011_dev_pm_ops, .pm = &pl011_dev_pm_ops,

View File

@ -832,7 +832,7 @@ MODULE_DEVICE_TABLE(of, ar933x_uart_of_ids);
static struct platform_driver ar933x_uart_platform_driver = { static struct platform_driver ar933x_uart_platform_driver = {
.probe = ar933x_uart_probe, .probe = ar933x_uart_probe,
.remove_new = ar933x_uart_remove, .remove = ar933x_uart_remove,
.driver = { .driver = {
.name = DRIVER_NAME, .name = DRIVER_NAME,
.of_match_table = of_match_ptr(ar933x_uart_of_ids), .of_match_table = of_match_ptr(ar933x_uart_of_ids),

View File

@ -1166,7 +1166,7 @@ static void atmel_rx_from_dma(struct uart_port *port)
port->icount.rx += count; port->icount.rx += count;
} }
/* USART retreives ownership of RX DMA buffer */ /* USART retrieves ownership of RX DMA buffer */
dma_sync_single_for_device(port->dev, atmel_port->rx_phys, dma_sync_single_for_device(port->dev, atmel_port->rx_phys,
ATMEL_SERIAL_RX_SIZE, DMA_FROM_DEVICE); ATMEL_SERIAL_RX_SIZE, DMA_FROM_DEVICE);
@ -2419,17 +2419,11 @@ static void atmel_release_port(struct uart_port *port)
static int atmel_request_port(struct uart_port *port) static int atmel_request_port(struct uart_port *port)
{ {
struct platform_device *mpdev = to_platform_device(port->dev->parent); struct platform_device *mpdev = to_platform_device(port->dev->parent);
int size = resource_size(mpdev->resource);
if (!request_mem_region(port->mapbase, size, "atmel_serial"))
return -EBUSY;
if (port->flags & UPF_IOREMAP) { if (port->flags & UPF_IOREMAP) {
port->membase = ioremap(port->mapbase, size); port->membase = devm_platform_ioremap_resource(mpdev, 0);
if (port->membase == NULL) { if (IS_ERR(port->membase))
release_mem_region(port->mapbase, size); return PTR_ERR(port->membase);
return -ENOMEM;
}
} }
return 0; return 0;
@ -3017,7 +3011,7 @@ static SIMPLE_DEV_PM_OPS(atmel_serial_pm_ops, atmel_serial_suspend,
static struct platform_driver atmel_serial_driver = { static struct platform_driver atmel_serial_driver = {
.probe = atmel_serial_probe, .probe = atmel_serial_probe,
.remove_new = atmel_serial_remove, .remove = atmel_serial_remove,
.driver = { .driver = {
.name = "atmel_usart_serial", .name = "atmel_usart_serial",
.of_match_table = of_match_ptr(atmel_serial_dt_ids), .of_match_table = of_match_ptr(atmel_serial_dt_ids),

View File

@ -884,7 +884,7 @@ MODULE_DEVICE_TABLE(of, bcm63xx_of_match);
*/ */
static struct platform_driver bcm_uart_platform_driver = { static struct platform_driver bcm_uart_platform_driver = {
.probe = bcm_uart_probe, .probe = bcm_uart_probe,
.remove_new = bcm_uart_remove, .remove = bcm_uart_remove,
.driver = { .driver = {
.name = "bcm63xx_uart", .name = "bcm63xx_uart",
.of_match_table = bcm63xx_of_match, .of_match_table = bcm63xx_of_match,

View File

@ -529,7 +529,7 @@ static struct platform_driver clps711x_uart_platform = {
.of_match_table = of_match_ptr(clps711x_uart_dt_ids), .of_match_table = of_match_ptr(clps711x_uart_dt_ids),
}, },
.probe = uart_clps711x_probe, .probe = uart_clps711x_probe,
.remove_new = uart_clps711x_remove, .remove = uart_clps711x_remove,
}; };
static int __init uart_clps711x_init(void) static int __init uart_clps711x_init(void)

View File

@ -1573,7 +1573,7 @@ static struct platform_driver cpm_uart_driver = {
.of_match_table = cpm_uart_match, .of_match_table = cpm_uart_match,
}, },
.probe = cpm_uart_probe, .probe = cpm_uart_probe,
.remove_new = cpm_uart_remove, .remove = cpm_uart_remove,
}; };
static int __init cpm_uart_init(void) static int __init cpm_uart_init(void)

View File

@ -522,7 +522,7 @@ static struct platform_driver digicolor_uart_platform = {
.of_match_table = of_match_ptr(digicolor_uart_dt_ids), .of_match_table = of_match_ptr(digicolor_uart_dt_ids),
}, },
.probe = digicolor_uart_probe, .probe = digicolor_uart_probe,
.remove_new = digicolor_uart_remove, .remove = digicolor_uart_remove,
}; };
static int __init digicolor_uart_init(void) static int __init digicolor_uart_init(void)

View File

@ -423,7 +423,7 @@ static void esp32s3_acm_remove(struct platform_device *pdev)
static struct platform_driver esp32s3_acm_driver = { static struct platform_driver esp32s3_acm_driver = {
.probe = esp32s3_acm_probe, .probe = esp32s3_acm_probe,
.remove_new = esp32s3_acm_remove, .remove = esp32s3_acm_remove,
.driver = { .driver = {
.name = DRIVER_NAME, .name = DRIVER_NAME,
.of_match_table = esp32s3_acm_dt_ids, .of_match_table = esp32s3_acm_dt_ids,

View File

@ -743,7 +743,7 @@ static void esp32_uart_remove(struct platform_device *pdev)
static struct platform_driver esp32_uart_driver = { static struct platform_driver esp32_uart_driver = {
.probe = esp32_uart_probe, .probe = esp32_uart_probe,
.remove_new = esp32_uart_remove, .remove = esp32_uart_remove,
.driver = { .driver = {
.name = DRIVER_NAME, .name = DRIVER_NAME,
.of_match_table = esp32_uart_dt_ids, .of_match_table = esp32_uart_dt_ids,

View File

@ -882,7 +882,7 @@ static SIMPLE_DEV_PM_OPS(linflex_pm_ops, linflex_suspend, linflex_resume);
static struct platform_driver linflex_driver = { static struct platform_driver linflex_driver = {
.probe = linflex_probe, .probe = linflex_probe,
.remove_new = linflex_remove, .remove = linflex_remove,
.driver = { .driver = {
.name = DRIVER_NAME, .name = DRIVER_NAME,
.of_match_table = linflex_dt_ids, .of_match_table = linflex_dt_ids,

View File

@ -184,6 +184,7 @@
#define UARTCTRL_SBK 0x00010000 #define UARTCTRL_SBK 0x00010000
#define UARTCTRL_MA1IE 0x00008000 #define UARTCTRL_MA1IE 0x00008000
#define UARTCTRL_MA2IE 0x00004000 #define UARTCTRL_MA2IE 0x00004000
#define UARTCTRL_M7 0x00000800
#define UARTCTRL_IDLECFG GENMASK(10, 8) #define UARTCTRL_IDLECFG GENMASK(10, 8)
#define UARTCTRL_LOOPS 0x00000080 #define UARTCTRL_LOOPS 0x00000080
#define UARTCTRL_DOZEEN 0x00000040 #define UARTCTRL_DOZEEN 0x00000040
@ -2222,8 +2223,9 @@ lpuart32_set_termios(struct uart_port *port, struct ktermios *termios,
modem = lpuart32_read(&sport->port, UARTMODIR); modem = lpuart32_read(&sport->port, UARTMODIR);
sport->is_cs7 = false; sport->is_cs7 = false;
/* /*
* only support CS8 and CS7, and for CS7 must enable PE. * only support CS8 and CS7
* supported mode: * supported mode:
* - (7,n,1) (imx only)
* - (7,e/o,1) * - (7,e/o,1)
* - (8,n,1) * - (8,n,1)
* - (8,m/s,1) * - (8,m/s,1)
@ -2238,7 +2240,7 @@ lpuart32_set_termios(struct uart_port *port, struct ktermios *termios,
if ((termios->c_cflag & CSIZE) == CS8 || if ((termios->c_cflag & CSIZE) == CS8 ||
(termios->c_cflag & CSIZE) == CS7) (termios->c_cflag & CSIZE) == CS7)
ctrl = old_ctrl & ~UARTCTRL_M; ctrl = old_ctrl & ~(UARTCTRL_M | UARTCTRL_M7);
if (termios->c_cflag & CMSPAR) { if (termios->c_cflag & CMSPAR) {
if ((termios->c_cflag & CSIZE) != CS8) { if ((termios->c_cflag & CSIZE) != CS8) {
@ -2265,9 +2267,18 @@ lpuart32_set_termios(struct uart_port *port, struct ktermios *termios,
else else
bd &= ~UARTBAUD_SBNS; bd &= ~UARTBAUD_SBNS;
/* parity must be enabled when CS7 to match 8-bits format */ /*
if ((termios->c_cflag & CSIZE) == CS7) * imx support 7-bits format, no limitation on parity when CS7
termios->c_cflag |= PARENB; * for layerscape, parity must be enabled when CS7 to match 8-bits format
*/
if ((termios->c_cflag & CSIZE) == CS7 && !(termios->c_cflag & PARENB)) {
if (is_imx7ulp_lpuart(sport) ||
is_imx8ulp_lpuart(sport) ||
is_imx8qxp_lpuart(sport))
ctrl |= UARTCTRL_M7;
else
termios->c_cflag |= PARENB;
}
if ((termios->c_cflag & PARENB)) { if ((termios->c_cflag & PARENB)) {
if (termios->c_cflag & CMSPAR) { if (termios->c_cflag & CMSPAR) {
@ -3206,7 +3217,7 @@ static const struct dev_pm_ops lpuart_pm_ops = {
static struct platform_driver lpuart_driver = { static struct platform_driver lpuart_driver = {
.probe = lpuart_probe, .probe = lpuart_probe,
.remove_new = lpuart_remove, .remove = lpuart_remove,
.driver = { .driver = {
.name = "fsl-lpuart", .name = "fsl-lpuart",
.of_match_table = lpuart_dt_ids, .of_match_table = lpuart_dt_ids,

View File

@ -230,6 +230,8 @@ struct imx_port {
unsigned int saved_reg[10]; unsigned int saved_reg[10];
bool context_saved; bool context_saved;
bool last_putchar_was_newline;
enum imx_tx_state tx_state; enum imx_tx_state tx_state;
struct hrtimer trigger_start_tx; struct hrtimer trigger_start_tx;
struct hrtimer trigger_stop_tx; struct hrtimer trigger_stop_tx;
@ -370,6 +372,7 @@ static void imx_uart_soft_reset(struct imx_port *sport)
sport->idle_counter = 0; sport->idle_counter = 0;
} }
/* called with port.lock taken and irqs off */
static void imx_uart_disable_loopback_rs485(struct imx_port *sport) static void imx_uart_disable_loopback_rs485(struct imx_port *sport)
{ {
unsigned int uts; unsigned int uts;
@ -470,6 +473,7 @@ static void imx_uart_stop_tx(struct uart_port *port)
} }
} }
/* called with port.lock taken and irqs off */
static void imx_uart_stop_rx_with_loopback_ctrl(struct uart_port *port, bool loopback) static void imx_uart_stop_rx_with_loopback_ctrl(struct uart_port *port, bool loopback)
{ {
struct imx_port *sport = to_imx_port(port); struct imx_port *sport = to_imx_port(port);
@ -818,6 +822,8 @@ static irqreturn_t imx_uart_txint(int irq, void *dev_id)
* issuing soft reset to the UART (just stop/start of RX does not help). Note * issuing soft reset to the UART (just stop/start of RX does not help). Note
* that what we do here is sending isolated start bit about 2.4 times shorter * that what we do here is sending isolated start bit about 2.4 times shorter
* than it is to be on UART configured baud rate. * than it is to be on UART configured baud rate.
*
* Called with port.lock taken and irqs off.
*/ */
static void imx_uart_check_flood(struct imx_port *sport, u32 usr2) static void imx_uart_check_flood(struct imx_port *sport, u32 usr2)
{ {
@ -853,6 +859,7 @@ static void imx_uart_check_flood(struct imx_port *sport, u32 usr2)
} }
} }
/* called with port.lock taken and irqs off */
static irqreturn_t __imx_uart_rxint(int irq, void *dev_id) static irqreturn_t __imx_uart_rxint(int irq, void *dev_id)
{ {
struct imx_port *sport = dev_id; struct imx_port *sport = dev_id;
@ -931,6 +938,7 @@ static void imx_uart_clear_rx_errors(struct imx_port *sport);
/* /*
* We have a modem side uart, so the meanings of RTS and CTS are inverted. * We have a modem side uart, so the meanings of RTS and CTS are inverted.
*/ */
/* called with port.lock taken and irqs off */
static unsigned int imx_uart_get_hwmctrl(struct imx_port *sport) static unsigned int imx_uart_get_hwmctrl(struct imx_port *sport)
{ {
unsigned int tmp = TIOCM_DSR; unsigned int tmp = TIOCM_DSR;
@ -953,6 +961,8 @@ static unsigned int imx_uart_get_hwmctrl(struct imx_port *sport)
/* /*
* Handle any change of modem status signal since we were last called. * Handle any change of modem status signal since we were last called.
*
* Called with port.lock taken and irqs off.
*/ */
static void imx_uart_mctrl_check(struct imx_port *sport) static void imx_uart_mctrl_check(struct imx_port *sport)
{ {
@ -1292,6 +1302,7 @@ static int imx_uart_start_rx_dma(struct imx_port *sport)
return 0; return 0;
} }
/* called with port.lock taken and irqs off */
static void imx_uart_clear_rx_errors(struct imx_port *sport) static void imx_uart_clear_rx_errors(struct imx_port *sport)
{ {
struct tty_port *port = &sport->port.state->port; struct tty_port *port = &sport->port.state->port;
@ -1422,6 +1433,7 @@ static int imx_uart_dma_init(struct imx_port *sport)
return ret; return ret;
} }
/* called with port.lock taken and irqs off */
static void imx_uart_enable_dma(struct imx_port *sport) static void imx_uart_enable_dma(struct imx_port *sport)
{ {
u32 ucr1; u32 ucr1;
@ -2069,26 +2081,34 @@ static void imx_uart_console_putchar(struct uart_port *port, unsigned char ch)
barrier(); barrier();
imx_uart_writel(sport, ch, URTX0); imx_uart_writel(sport, ch, URTX0);
sport->last_putchar_was_newline = (ch == '\n');
} }
/* static void imx_uart_console_device_lock(struct console *co, unsigned long *flags)
* Interrupts are disabled on entering {
*/ struct uart_port *up = &imx_uart_ports[co->index]->port;
static void
imx_uart_console_write(struct console *co, const char *s, unsigned int count) return __uart_port_lock_irqsave(up, flags);
}
static void imx_uart_console_device_unlock(struct console *co, unsigned long flags)
{
struct uart_port *up = &imx_uart_ports[co->index]->port;
return __uart_port_unlock_irqrestore(up, flags);
}
static void imx_uart_console_write_atomic(struct console *co,
struct nbcon_write_context *wctxt)
{ {
struct imx_port *sport = imx_uart_ports[co->index]; struct imx_port *sport = imx_uart_ports[co->index];
struct uart_port *port = &sport->port;
struct imx_port_ucrs old_ucr; struct imx_port_ucrs old_ucr;
unsigned long flags;
unsigned int ucr1, usr2; unsigned int ucr1, usr2;
int locked = 1;
if (sport->port.sysrq) if (!nbcon_enter_unsafe(wctxt))
locked = 0; return;
else if (oops_in_progress)
locked = uart_port_trylock_irqsave(&sport->port, &flags);
else
uart_port_lock_irqsave(&sport->port, &flags);
/* /*
* First, save UCR1/2/3 and then disable interrupts * First, save UCR1/2/3 and then disable interrupts
@ -2102,10 +2122,12 @@ imx_uart_console_write(struct console *co, const char *s, unsigned int count)
ucr1 &= ~(UCR1_TRDYEN | UCR1_RRDYEN | UCR1_RTSDEN); ucr1 &= ~(UCR1_TRDYEN | UCR1_RRDYEN | UCR1_RTSDEN);
imx_uart_writel(sport, ucr1, UCR1); imx_uart_writel(sport, ucr1, UCR1);
imx_uart_writel(sport, old_ucr.ucr2 | UCR2_TXEN, UCR2); imx_uart_writel(sport, old_ucr.ucr2 | UCR2_TXEN, UCR2);
uart_console_write(&sport->port, s, count, imx_uart_console_putchar); if (!sport->last_putchar_was_newline)
uart_console_write(port, "\n", 1, imx_uart_console_putchar);
uart_console_write(port, wctxt->outbuf, wctxt->len,
imx_uart_console_putchar);
/* /*
* Finally, wait for transmitter to become empty * Finally, wait for transmitter to become empty
@ -2115,8 +2137,73 @@ imx_uart_console_write(struct console *co, const char *s, unsigned int count)
0, USEC_PER_SEC, false, sport, USR2); 0, USEC_PER_SEC, false, sport, USR2);
imx_uart_ucrs_restore(sport, &old_ucr); imx_uart_ucrs_restore(sport, &old_ucr);
if (locked) nbcon_exit_unsafe(wctxt);
uart_port_unlock_irqrestore(&sport->port, flags); }
static void imx_uart_console_write_thread(struct console *co,
struct nbcon_write_context *wctxt)
{
struct imx_port *sport = imx_uart_ports[co->index];
struct uart_port *port = &sport->port;
struct imx_port_ucrs old_ucr;
unsigned int ucr1, usr2;
if (!nbcon_enter_unsafe(wctxt))
return;
/*
* First, save UCR1/2/3 and then disable interrupts
*/
imx_uart_ucrs_save(sport, &old_ucr);
ucr1 = old_ucr.ucr1;
if (imx_uart_is_imx1(sport))
ucr1 |= IMX1_UCR1_UARTCLKEN;
ucr1 |= UCR1_UARTEN;
ucr1 &= ~(UCR1_TRDYEN | UCR1_RRDYEN | UCR1_RTSDEN);
imx_uart_writel(sport, ucr1, UCR1);
imx_uart_writel(sport, old_ucr.ucr2 | UCR2_TXEN, UCR2);
if (nbcon_exit_unsafe(wctxt)) {
int len = READ_ONCE(wctxt->len);
int i;
/*
* Write out the message. Toggle unsafe for each byte in order
* to give another (higher priority) context the opportunity
* for a friendly takeover. If such a takeover occurs, this
* context must reacquire ownership in order to perform final
* actions (such as re-enabling the interrupts).
*
* IMPORTANT: wctxt->outbuf and wctxt->len are no longer valid
* after a reacquire so writing the message must be
* aborted.
*/
for (i = 0; i < len; i++) {
if (!nbcon_enter_unsafe(wctxt))
break;
uart_console_write(port, wctxt->outbuf + i, 1,
imx_uart_console_putchar);
if (!nbcon_exit_unsafe(wctxt))
break;
}
}
while (!nbcon_enter_unsafe(wctxt))
nbcon_reacquire_nobuf(wctxt);
/*
* Finally, wait for transmitter to become empty
* and restore UCR1/2/3
*/
read_poll_timeout(imx_uart_readl, usr2, usr2 & USR2_TXDC,
0, USEC_PER_SEC, false, sport, USR2);
imx_uart_ucrs_restore(sport, &old_ucr);
nbcon_exit_unsafe(wctxt);
} }
/* /*
@ -2208,6 +2295,8 @@ imx_uart_console_setup(struct console *co, char *options)
if (retval) if (retval)
goto error_console; goto error_console;
sport->last_putchar_was_newline = true;
if (options) if (options)
uart_parse_options(options, &baud, &parity, &bits, &flow); uart_parse_options(options, &baud, &parity, &bits, &flow);
else else
@ -2244,11 +2333,14 @@ imx_uart_console_exit(struct console *co)
static struct uart_driver imx_uart_uart_driver; static struct uart_driver imx_uart_uart_driver;
static struct console imx_uart_console = { static struct console imx_uart_console = {
.name = DEV_NAME, .name = DEV_NAME,
.write = imx_uart_console_write, .write_atomic = imx_uart_console_write_atomic,
.write_thread = imx_uart_console_write_thread,
.device_lock = imx_uart_console_device_lock,
.device_unlock = imx_uart_console_device_unlock,
.flags = CON_PRINTBUFFER | CON_NBCON,
.device = uart_console_device, .device = uart_console_device,
.setup = imx_uart_console_setup, .setup = imx_uart_console_setup,
.exit = imx_uart_console_exit, .exit = imx_uart_console_exit,
.flags = CON_PRINTBUFFER,
.index = -1, .index = -1,
.data = &imx_uart_uart_driver, .data = &imx_uart_uart_driver,
}; };
@ -2595,10 +2687,13 @@ static void imx_uart_save_context(struct imx_port *sport)
uart_port_unlock_irqrestore(&sport->port, flags); uart_port_unlock_irqrestore(&sport->port, flags);
} }
/* called with irq off */
static void imx_uart_enable_wakeup(struct imx_port *sport, bool on) static void imx_uart_enable_wakeup(struct imx_port *sport, bool on)
{ {
u32 ucr3; u32 ucr3;
uart_port_lock(&sport->port);
ucr3 = imx_uart_readl(sport, UCR3); ucr3 = imx_uart_readl(sport, UCR3);
if (on) { if (on) {
imx_uart_writel(sport, USR1_AWAKE, USR1); imx_uart_writel(sport, USR1_AWAKE, USR1);
@ -2618,6 +2713,8 @@ static void imx_uart_enable_wakeup(struct imx_port *sport, bool on)
} }
imx_uart_writel(sport, ucr1, UCR1); imx_uart_writel(sport, ucr1, UCR1);
} }
uart_port_unlock(&sport->port);
} }
static int imx_uart_suspend_noirq(struct device *dev) static int imx_uart_suspend_noirq(struct device *dev)
@ -2717,7 +2814,7 @@ static const struct dev_pm_ops imx_uart_pm_ops = {
static struct platform_driver imx_uart_platform_driver = { static struct platform_driver imx_uart_platform_driver = {
.probe = imx_uart_probe, .probe = imx_uart_probe,
.remove_new = imx_uart_remove, .remove = imx_uart_remove,
.driver = { .driver = {
.name = "imx-uart", .name = "imx-uart",

View File

@ -915,7 +915,7 @@ MODULE_DEVICE_TABLE(of, ltq_asc_match);
static struct platform_driver lqasc_driver = { static struct platform_driver lqasc_driver = {
.probe = lqasc_probe, .probe = lqasc_probe,
.remove_new = lqasc_remove, .remove = lqasc_remove,
.driver = { .driver = {
.name = DRVNAME, .name = DRVNAME,
.of_match_table = ltq_asc_match, .of_match_table = ltq_asc_match,

View File

@ -353,7 +353,7 @@ MODULE_DEVICE_TABLE(of, liteuart_of_match);
static struct platform_driver liteuart_platform_driver = { static struct platform_driver liteuart_platform_driver = {
.probe = liteuart_probe, .probe = liteuart_probe,
.remove_new = liteuart_remove, .remove = liteuart_remove,
.driver = { .driver = {
.name = KBUILD_MODNAME, .name = KBUILD_MODNAME,
.of_match_table = liteuart_of_match, .of_match_table = liteuart_of_match,

View File

@ -695,7 +695,7 @@ MODULE_DEVICE_TABLE(of, serial_hs_lpc32xx_dt_ids);
static struct platform_driver serial_hs_lpc32xx_driver = { static struct platform_driver serial_hs_lpc32xx_driver = {
.probe = serial_hs_lpc32xx_probe, .probe = serial_hs_lpc32xx_probe,
.remove_new = serial_hs_lpc32xx_remove, .remove = serial_hs_lpc32xx_remove,
.suspend = serial_hs_lpc32xx_suspend, .suspend = serial_hs_lpc32xx_suspend,
.resume = serial_hs_lpc32xx_resume, .resume = serial_hs_lpc32xx_resume,
.driver = { .driver = {

View File

@ -794,7 +794,7 @@ static int ma35d1serial_resume(struct platform_device *dev)
static struct platform_driver ma35d1serial_driver = { static struct platform_driver ma35d1serial_driver = {
.probe = ma35d1serial_probe, .probe = ma35d1serial_probe,
.remove_new = ma35d1serial_remove, .remove = ma35d1serial_remove,
.suspend = ma35d1serial_suspend, .suspend = ma35d1serial_suspend,
.resume = ma35d1serial_resume, .resume = ma35d1serial_resume,
.driver = { .driver = {

View File

@ -616,7 +616,7 @@ static void mcf_remove(struct platform_device *pdev)
static struct platform_driver mcf_platform_driver = { static struct platform_driver mcf_platform_driver = {
.probe = mcf_probe, .probe = mcf_probe,
.remove_new = mcf_remove, .remove = mcf_remove,
.driver = { .driver = {
.name = "mcfuart", .name = "mcfuart",
}, },

View File

@ -842,7 +842,7 @@ MODULE_DEVICE_TABLE(of, meson_uart_dt_match);
static struct platform_driver meson_uart_platform_driver = { static struct platform_driver meson_uart_platform_driver = {
.probe = meson_uart_probe, .probe = meson_uart_probe,
.remove_new = meson_uart_remove, .remove = meson_uart_remove,
.driver = { .driver = {
.name = "meson_uart", .name = "meson_uart",
.of_match_table = meson_uart_dt_match, .of_match_table = meson_uart_dt_match,

View File

@ -570,7 +570,7 @@ MODULE_DEVICE_TABLE(of, mlb_usio_dt_ids);
static struct platform_driver mlb_usio_driver = { static struct platform_driver mlb_usio_driver = {
.probe = mlb_usio_probe, .probe = mlb_usio_probe,
.remove_new = mlb_usio_remove, .remove = mlb_usio_remove,
.driver = { .driver = {
.name = USIO_NAME, .name = USIO_NAME,
.of_match_table = mlb_usio_dt_ids, .of_match_table = mlb_usio_dt_ids,

View File

@ -1843,7 +1843,7 @@ MODULE_DEVICE_TABLE(of, mpc52xx_uart_of_match);
static struct platform_driver mpc52xx_uart_of_driver = { static struct platform_driver mpc52xx_uart_of_driver = {
.probe = mpc52xx_uart_of_probe, .probe = mpc52xx_uart_of_probe,
.remove_new = mpc52xx_uart_of_remove, .remove = mpc52xx_uart_of_remove,
#ifdef CONFIG_PM #ifdef CONFIG_PM
.suspend = mpc52xx_uart_of_suspend, .suspend = mpc52xx_uart_of_suspend,
.resume = mpc52xx_uart_of_resume, .resume = mpc52xx_uart_of_resume,

View File

@ -1894,7 +1894,7 @@ static const struct dev_pm_ops msm_serial_dev_pm_ops = {
}; };
static struct platform_driver msm_platform_driver = { static struct platform_driver msm_platform_driver = {
.remove_new = msm_serial_remove, .remove = msm_serial_remove,
.probe = msm_serial_probe, .probe = msm_serial_probe,
.driver = { .driver = {
.name = "msm_serial", .name = "msm_serial",

View File

@ -1704,7 +1704,7 @@ static void mxs_auart_remove(struct platform_device *pdev)
static struct platform_driver mxs_auart_driver = { static struct platform_driver mxs_auart_driver = {
.probe = mxs_auart_probe, .probe = mxs_auart_probe,
.remove_new = mxs_auart_remove, .remove = mxs_auart_remove,
.driver = { .driver = {
.name = "mxs-auart", .name = "mxs-auart",
.of_match_table = mxs_auart_dt_ids, .of_match_table = mxs_auart_dt_ids,

View File

@ -1802,7 +1802,7 @@ MODULE_DEVICE_TABLE(of, omap_serial_of_match);
static struct platform_driver serial_omap_driver = { static struct platform_driver serial_omap_driver = {
.probe = serial_omap_probe, .probe = serial_omap_probe,
.remove_new = serial_omap_remove, .remove = serial_omap_remove,
.driver = { .driver = {
.name = OMAP_SERIAL_DRIVER_NAME, .name = OMAP_SERIAL_DRIVER_NAME,
.pm = &serial_omap_dev_pm_ops, .pm = &serial_omap_dev_pm_ops,

View File

@ -730,7 +730,7 @@ static void owl_uart_remove(struct platform_device *pdev)
static struct platform_driver owl_uart_platform_driver = { static struct platform_driver owl_uart_platform_driver = {
.probe = owl_uart_probe, .probe = owl_uart_probe,
.remove_new = owl_uart_remove, .remove = owl_uart_remove,
.driver = { .driver = {
.name = "owl-uart", .name = "owl-uart",
.of_match_table = owl_uart_dt_matches, .of_match_table = owl_uart_dt_matches,

View File

@ -956,7 +956,7 @@ MODULE_DEVICE_TABLE(of, pic32_serial_dt_ids);
static struct platform_driver pic32_uart_platform_driver = { static struct platform_driver pic32_uart_platform_driver = {
.probe = pic32_uart_probe, .probe = pic32_uart_probe,
.remove_new = pic32_uart_remove, .remove = pic32_uart_remove,
.driver = { .driver = {
.name = PIC32_DEV_NAME, .name = PIC32_DEV_NAME,
.of_match_table = of_match_ptr(pic32_serial_dt_ids), .of_match_table = of_match_ptr(pic32_serial_dt_ids),

View File

@ -1776,7 +1776,7 @@ static struct macio_driver pmz_driver = {
static struct platform_driver pmz_driver = { static struct platform_driver pmz_driver = {
.probe = pmz_attach, .probe = pmz_attach,
.remove_new = pmz_detach, .remove = pmz_detach,
.driver = { .driver = {
.name = "scc", .name = "scc",
}, },

View File

@ -1839,7 +1839,7 @@ static const struct of_device_id qcom_geni_serial_match_table[] = {
MODULE_DEVICE_TABLE(of, qcom_geni_serial_match_table); MODULE_DEVICE_TABLE(of, qcom_geni_serial_match_table);
static struct platform_driver qcom_geni_serial_platform_driver = { static struct platform_driver qcom_geni_serial_platform_driver = {
.remove_new = qcom_geni_serial_remove, .remove = qcom_geni_serial_remove,
.probe = qcom_geni_serial_probe, .probe = qcom_geni_serial_probe,
.driver = { .driver = {
.name = "qcom_geni_serial", .name = "qcom_geni_serial",

View File

@ -777,7 +777,7 @@ static void rda_uart_remove(struct platform_device *pdev)
static struct platform_driver rda_uart_platform_driver = { static struct platform_driver rda_uart_platform_driver = {
.probe = rda_uart_probe, .probe = rda_uart_probe,
.remove_new = rda_uart_remove, .remove = rda_uart_remove,
.driver = { .driver = {
.name = "rda-uart", .name = "rda-uart",
.of_match_table = rda_uart_dt_matches, .of_match_table = rda_uart_dt_matches,

View File

@ -880,7 +880,7 @@ static void sa1100_serial_remove(struct platform_device *pdev)
static struct platform_driver sa11x0_serial_driver = { static struct platform_driver sa11x0_serial_driver = {
.probe = sa1100_serial_probe, .probe = sa1100_serial_probe,
.remove_new = sa1100_serial_remove, .remove = sa1100_serial_remove,
.suspend = sa1100_serial_suspend, .suspend = sa1100_serial_suspend,
.resume = sa1100_serial_resume, .resume = sa1100_serial_resume,
.driver = { .driver = {

View File

@ -2498,6 +2498,12 @@ static const struct s3c24xx_serial_drv_data exynos850_serial_drv_data = {
.fifosize = { 256, 64, 64, 64 }, .fifosize = { 256, 64, 64, 64 },
}; };
static const struct s3c24xx_serial_drv_data exynos8895_serial_drv_data = {
EXYNOS_COMMON_SERIAL_DRV_DATA,
/* samsung,uart-fifosize must be specified in the device tree. */
.fifosize = { 0 },
};
static const struct s3c24xx_serial_drv_data gs101_serial_drv_data = { static const struct s3c24xx_serial_drv_data gs101_serial_drv_data = {
.info = { .info = {
.name = "Google GS101 UART", .name = "Google GS101 UART",
@ -2528,12 +2534,14 @@ static const struct s3c24xx_serial_drv_data gs101_serial_drv_data = {
#define EXYNOS4210_SERIAL_DRV_DATA (&exynos4210_serial_drv_data) #define EXYNOS4210_SERIAL_DRV_DATA (&exynos4210_serial_drv_data)
#define EXYNOS5433_SERIAL_DRV_DATA (&exynos5433_serial_drv_data) #define EXYNOS5433_SERIAL_DRV_DATA (&exynos5433_serial_drv_data)
#define EXYNOS850_SERIAL_DRV_DATA (&exynos850_serial_drv_data) #define EXYNOS850_SERIAL_DRV_DATA (&exynos850_serial_drv_data)
#define EXYNOS8895_SERIAL_DRV_DATA (&exynos8895_serial_drv_data)
#define GS101_SERIAL_DRV_DATA (&gs101_serial_drv_data) #define GS101_SERIAL_DRV_DATA (&gs101_serial_drv_data)
#else #else
#define EXYNOS4210_SERIAL_DRV_DATA NULL #define EXYNOS4210_SERIAL_DRV_DATA NULL
#define EXYNOS5433_SERIAL_DRV_DATA NULL #define EXYNOS5433_SERIAL_DRV_DATA NULL
#define EXYNOS850_SERIAL_DRV_DATA NULL #define EXYNOS850_SERIAL_DRV_DATA NULL
#define EXYNOS8895_SERIAL_DRV_DATA NULL
#define GS101_SERIAL_DRV_DATA NULL #define GS101_SERIAL_DRV_DATA NULL
#endif #endif
@ -2623,6 +2631,9 @@ static const struct platform_device_id s3c24xx_serial_driver_ids[] = {
}, { }, {
.name = "gs101-uart", .name = "gs101-uart",
.driver_data = (kernel_ulong_t)GS101_SERIAL_DRV_DATA, .driver_data = (kernel_ulong_t)GS101_SERIAL_DRV_DATA,
}, {
.name = "exynos8895-uart",
.driver_data = (kernel_ulong_t)EXYNOS8895_SERIAL_DRV_DATA,
}, },
{ }, { },
}; };
@ -2646,6 +2657,8 @@ static const struct of_device_id s3c24xx_uart_dt_match[] = {
.data = ARTPEC8_SERIAL_DRV_DATA }, .data = ARTPEC8_SERIAL_DRV_DATA },
{ .compatible = "google,gs101-uart", { .compatible = "google,gs101-uart",
.data = GS101_SERIAL_DRV_DATA }, .data = GS101_SERIAL_DRV_DATA },
{ .compatible = "samsung,exynos8895-uart",
.data = EXYNOS8895_SERIAL_DRV_DATA },
{}, {},
}; };
MODULE_DEVICE_TABLE(of, s3c24xx_uart_dt_match); MODULE_DEVICE_TABLE(of, s3c24xx_uart_dt_match);
@ -2653,7 +2666,7 @@ MODULE_DEVICE_TABLE(of, s3c24xx_uart_dt_match);
static struct platform_driver samsung_serial_driver = { static struct platform_driver samsung_serial_driver = {
.probe = s3c24xx_serial_probe, .probe = s3c24xx_serial_probe,
.remove_new = s3c24xx_serial_remove, .remove = s3c24xx_serial_remove,
.id_table = s3c24xx_serial_driver_ids, .id_table = s3c24xx_serial_driver_ids,
.driver = { .driver = {
.name = "samsung-uart", .name = "samsung-uart",

View File

@ -1473,7 +1473,7 @@ static int sc16is7xx_setup_mctrl_ports(struct sc16is7xx_port *s,
} }
static const struct serial_rs485 sc16is7xx_rs485_supported = { static const struct serial_rs485 sc16is7xx_rs485_supported = {
.flags = SER_RS485_ENABLED | SER_RS485_RTS_AFTER_SEND, .flags = SER_RS485_ENABLED | SER_RS485_RTS_ON_SEND | SER_RS485_RTS_AFTER_SEND,
.delay_rts_before_send = 1, .delay_rts_before_send = 1,
.delay_rts_after_send = 1, /* Not supported but keep returning -EINVAL */ .delay_rts_after_send = 1, /* Not supported but keep returning -EINVAL */
}; };

View File

@ -1052,7 +1052,7 @@ static struct platform_driver sccnxp_uart_driver = {
.name = SCCNXP_NAME, .name = SCCNXP_NAME,
}, },
.probe = sccnxp_probe, .probe = sccnxp_probe,
.remove_new = sccnxp_remove, .remove = sccnxp_remove,
.id_table = sccnxp_id_table, .id_table = sccnxp_id_table,
}; };
module_platform_driver(sccnxp_uart_driver); module_platform_driver(sccnxp_uart_driver);

View File

@ -1648,7 +1648,7 @@ static const struct dev_pm_ops tegra_uart_pm_ops = {
static struct platform_driver tegra_uart_platform_driver = { static struct platform_driver tegra_uart_platform_driver = {
.probe = tegra_uart_probe, .probe = tegra_uart_probe,
.remove_new = tegra_uart_remove, .remove = tegra_uart_remove,
.driver = { .driver = {
.name = "serial-tegra", .name = "serial-tegra",
.of_match_table = tegra_uart_of_match, .of_match_table = tegra_uart_of_match,

View File

@ -1097,7 +1097,7 @@ static int serial_txx9_resume(struct platform_device *dev)
static struct platform_driver serial_txx9_plat_driver = { static struct platform_driver serial_txx9_plat_driver = {
.probe = serial_txx9_probe, .probe = serial_txx9_probe,
.remove_new = serial_txx9_remove, .remove = serial_txx9_remove,
#ifdef CONFIG_PM #ifdef CONFIG_PM
.suspend = serial_txx9_suspend, .suspend = serial_txx9_suspend,
.resume = serial_txx9_resume, .resume = serial_txx9_resume,

View File

@ -3505,7 +3505,7 @@ static SIMPLE_DEV_PM_OPS(sci_dev_pm_ops, sci_suspend, sci_resume);
static struct platform_driver sci_driver = { static struct platform_driver sci_driver = {
.probe = sci_probe, .probe = sci_probe,
.remove_new = sci_remove, .remove = sci_remove,
.driver = { .driver = {
.name = "sh-sci", .name = "sh-sci",
.pm = &sci_dev_pm_ops, .pm = &sci_dev_pm_ops,

View File

@ -1040,7 +1040,7 @@ MODULE_DEVICE_TABLE(of, sifive_serial_of_match);
static struct platform_driver sifive_serial_platform_driver = { static struct platform_driver sifive_serial_platform_driver = {
.probe = sifive_serial_probe, .probe = sifive_serial_probe,
.remove_new = sifive_serial_remove, .remove = sifive_serial_remove,
.driver = { .driver = {
.name = SIFIVE_SERIAL_NAME, .name = SIFIVE_SERIAL_NAME,
.pm = pm_sleep_ptr(&sifive_uart_pm_ops), .pm = pm_sleep_ptr(&sifive_uart_pm_ops),

View File

@ -53,10 +53,12 @@
#define SPRD_IEN_TX_EMPTY BIT(1) #define SPRD_IEN_TX_EMPTY BIT(1)
#define SPRD_IEN_BREAK_DETECT BIT(7) #define SPRD_IEN_BREAK_DETECT BIT(7)
#define SPRD_IEN_TIMEOUT BIT(13) #define SPRD_IEN_TIMEOUT BIT(13)
#define SPRD_IEN_DATA_TIMEOUT BIT(17)
/* interrupt clear register */ /* interrupt clear register */
#define SPRD_ICLR 0x0014 #define SPRD_ICLR 0x0014
#define SPRD_ICLR_TIMEOUT BIT(13) #define SPRD_ICLR_TIMEOUT BIT(13)
#define SPRD_ICLR_DATA_TIMEOUT BIT(17)
/* line control register */ /* line control register */
#define SPRD_LCR 0x0018 #define SPRD_LCR 0x0018
@ -102,6 +104,7 @@
#define SPRD_IMSR_TX_FIFO_EMPTY BIT(1) #define SPRD_IMSR_TX_FIFO_EMPTY BIT(1)
#define SPRD_IMSR_BREAK_DETECT BIT(7) #define SPRD_IMSR_BREAK_DETECT BIT(7)
#define SPRD_IMSR_TIMEOUT BIT(13) #define SPRD_IMSR_TIMEOUT BIT(13)
#define SPRD_IMSR_DATA_TIMEOUT BIT(17)
#define SPRD_DEFAULT_SOURCE_CLK 26000000 #define SPRD_DEFAULT_SOURCE_CLK 26000000
#define SPRD_RX_DMA_STEP 1 #define SPRD_RX_DMA_STEP 1
@ -118,6 +121,12 @@ struct sprd_uart_dma {
bool enable; bool enable;
}; };
struct sprd_uart_data {
unsigned int timeout_ien;
unsigned int timeout_iclr;
unsigned int timeout_imsr;
};
struct sprd_uart_port { struct sprd_uart_port {
struct uart_port port; struct uart_port port;
char name[16]; char name[16];
@ -126,6 +135,7 @@ struct sprd_uart_port {
struct sprd_uart_dma rx_dma; struct sprd_uart_dma rx_dma;
dma_addr_t pos; dma_addr_t pos;
unsigned char *rx_buf_tail; unsigned char *rx_buf_tail;
const struct sprd_uart_data *pdata;
}; };
static struct sprd_uart_port *sprd_port[UART_NR_MAX]; static struct sprd_uart_port *sprd_port[UART_NR_MAX];
@ -134,6 +144,18 @@ static int sprd_ports_num;
static int sprd_start_dma_rx(struct uart_port *port); static int sprd_start_dma_rx(struct uart_port *port);
static int sprd_tx_dma_config(struct uart_port *port); static int sprd_tx_dma_config(struct uart_port *port);
static const struct sprd_uart_data sc9836_data = {
.timeout_ien = SPRD_IEN_TIMEOUT,
.timeout_iclr = SPRD_ICLR_TIMEOUT,
.timeout_imsr = SPRD_IMSR_TIMEOUT,
};
static const struct sprd_uart_data sc9632_data = {
.timeout_ien = SPRD_IEN_DATA_TIMEOUT,
.timeout_iclr = SPRD_ICLR_DATA_TIMEOUT,
.timeout_imsr = SPRD_IMSR_DATA_TIMEOUT,
};
static inline unsigned int serial_in(struct uart_port *port, static inline unsigned int serial_in(struct uart_port *port,
unsigned int offset) unsigned int offset)
{ {
@ -637,6 +659,8 @@ static irqreturn_t sprd_handle_irq(int irq, void *dev_id)
{ {
struct uart_port *port = dev_id; struct uart_port *port = dev_id;
unsigned int ims; unsigned int ims;
struct sprd_uart_port *sp =
container_of(port, struct sprd_uart_port, port);
uart_port_lock(port); uart_port_lock(port);
@ -647,14 +671,14 @@ static irqreturn_t sprd_handle_irq(int irq, void *dev_id)
return IRQ_NONE; return IRQ_NONE;
} }
if (ims & SPRD_IMSR_TIMEOUT) if (ims & sp->pdata->timeout_imsr)
serial_out(port, SPRD_ICLR, SPRD_ICLR_TIMEOUT); serial_out(port, SPRD_ICLR, sp->pdata->timeout_iclr);
if (ims & SPRD_IMSR_BREAK_DETECT) if (ims & SPRD_IMSR_BREAK_DETECT)
serial_out(port, SPRD_ICLR, SPRD_IMSR_BREAK_DETECT); serial_out(port, SPRD_ICLR, SPRD_IMSR_BREAK_DETECT);
if (ims & (SPRD_IMSR_RX_FIFO_FULL | SPRD_IMSR_BREAK_DETECT | if (ims & (SPRD_IMSR_RX_FIFO_FULL | SPRD_IMSR_BREAK_DETECT |
SPRD_IMSR_TIMEOUT)) sp->pdata->timeout_imsr))
sprd_rx(port); sprd_rx(port);
if (ims & SPRD_IMSR_TX_FIFO_EMPTY) if (ims & SPRD_IMSR_TX_FIFO_EMPTY)
@ -729,7 +753,7 @@ static int sprd_startup(struct uart_port *port)
/* enable interrupt */ /* enable interrupt */
uart_port_lock_irqsave(port, &flags); uart_port_lock_irqsave(port, &flags);
ien = serial_in(port, SPRD_IEN); ien = serial_in(port, SPRD_IEN);
ien |= SPRD_IEN_BREAK_DETECT | SPRD_IEN_TIMEOUT; ien |= SPRD_IEN_BREAK_DETECT | sp->pdata->timeout_ien;
if (!sp->rx_dma.enable) if (!sp->rx_dma.enable)
ien |= SPRD_IEN_RX_FULL; ien |= SPRD_IEN_RX_FULL;
serial_out(port, SPRD_IEN, ien); serial_out(port, SPRD_IEN, ien);
@ -1184,6 +1208,12 @@ static int sprd_probe(struct platform_device *pdev)
up->mapbase = res->start; up->mapbase = res->start;
sport->pdata = of_device_get_match_data(&pdev->dev);
if (!sport->pdata) {
dev_err(&pdev->dev, "get match data failed!\n");
return -EINVAL;
}
irq = platform_get_irq(pdev, 0); irq = platform_get_irq(pdev, 0);
if (irq < 0) if (irq < 0)
return irq; return irq;
@ -1248,14 +1278,15 @@ static int sprd_resume(struct device *dev)
static SIMPLE_DEV_PM_OPS(sprd_pm_ops, sprd_suspend, sprd_resume); static SIMPLE_DEV_PM_OPS(sprd_pm_ops, sprd_suspend, sprd_resume);
static const struct of_device_id serial_ids[] = { static const struct of_device_id serial_ids[] = {
{.compatible = "sprd,sc9836-uart",}, {.compatible = "sprd,sc9836-uart", .data = &sc9836_data},
{.compatible = "sprd,sc9632-uart", .data = &sc9632_data},
{} {}
}; };
MODULE_DEVICE_TABLE(of, serial_ids); MODULE_DEVICE_TABLE(of, serial_ids);
static struct platform_driver sprd_platform_driver = { static struct platform_driver sprd_platform_driver = {
.probe = sprd_probe, .probe = sprd_probe,
.remove_new = sprd_remove, .remove = sprd_remove,
.driver = { .driver = {
.name = "sprd_serial", .name = "sprd_serial",
.of_match_table = serial_ids, .of_match_table = serial_ids,

View File

@ -934,7 +934,7 @@ static DEFINE_SIMPLE_DEV_PM_OPS(asc_serial_pm_ops, asc_serial_suspend,
static struct platform_driver asc_serial_driver = { static struct platform_driver asc_serial_driver = {
.probe = asc_serial_probe, .probe = asc_serial_probe,
.remove_new = asc_serial_remove, .remove = asc_serial_remove,
.driver = { .driver = {
.name = DRIVER_NAME, .name = DRIVER_NAME,
.pm = pm_sleep_ptr(&asc_serial_pm_ops), .pm = pm_sleep_ptr(&asc_serial_pm_ops),

View File

@ -2188,7 +2188,7 @@ static const struct dev_pm_ops stm32_serial_pm_ops = {
static struct platform_driver stm32_serial_driver = { static struct platform_driver stm32_serial_driver = {
.probe = stm32_usart_serial_probe, .probe = stm32_usart_serial_probe,
.remove_new = stm32_usart_serial_remove, .remove = stm32_usart_serial_remove,
.driver = { .driver = {
.name = DRIVER_NAME, .name = DRIVER_NAME,
.pm = &stm32_serial_pm_ops, .pm = &stm32_serial_pm_ops,

View File

@ -633,7 +633,7 @@ static struct platform_driver hv_driver = {
.of_match_table = hv_match, .of_match_table = hv_match,
}, },
.probe = hv_probe, .probe = hv_probe,
.remove_new = hv_remove, .remove = hv_remove,
}; };
static int __init sunhv_init(void) static int __init sunhv_init(void)

View File

@ -697,7 +697,7 @@ MODULE_DEVICE_TABLE(of, sp_uart_of_match);
static struct platform_driver sunplus_uart_platform_driver = { static struct platform_driver sunplus_uart_platform_driver = {
.probe = sunplus_uart_probe, .probe = sunplus_uart_probe,
.remove_new = sunplus_uart_remove, .remove = sunplus_uart_remove,
.driver = { .driver = {
.name = "sunplus_uart", .name = "sunplus_uart",
.of_match_table = sp_uart_of_match, .of_match_table = sp_uart_of_match,

View File

@ -1100,7 +1100,7 @@ static struct platform_driver sab_driver = {
.of_match_table = sab_match, .of_match_table = sab_match,
}, },
.probe = sab_probe, .probe = sab_probe,
.remove_new = sab_remove, .remove = sab_remove,
}; };
static int __init sunsab_init(void) static int __init sunsab_init(void)

View File

@ -1549,7 +1549,7 @@ static struct platform_driver su_driver = {
.of_match_table = su_match, .of_match_table = su_match,
}, },
.probe = su_probe, .probe = su_probe,
.remove_new = su_remove, .remove = su_remove,
}; };
static int __init sunsu_init(void) static int __init sunsu_init(void)

View File

@ -1538,7 +1538,7 @@ static struct platform_driver zs_driver = {
.of_match_table = zs_match, .of_match_table = zs_match,
}, },
.probe = zs_probe, .probe = zs_probe,
.remove_new = zs_remove, .remove = zs_remove,
}; };
static int __init sunzilog_init(void) static int __init sunzilog_init(void)

View File

@ -293,7 +293,7 @@ static struct platform_driver tegra_tcu_driver = {
.of_match_table = tegra_tcu_match, .of_match_table = tegra_tcu_match,
}, },
.probe = tegra_tcu_probe, .probe = tegra_tcu_probe,
.remove_new = tegra_tcu_remove, .remove = tegra_tcu_remove,
}; };
module_platform_driver(tegra_tcu_driver); module_platform_driver(tegra_tcu_driver);

View File

@ -485,7 +485,7 @@ static struct platform_driver timbuart_platform_driver = {
.name = "timb-uart", .name = "timb-uart",
}, },
.probe = timbuart_probe, .probe = timbuart_probe,
.remove_new = timbuart_remove, .remove = timbuart_remove,
}; };
module_platform_driver(timbuart_platform_driver); module_platform_driver(timbuart_platform_driver);

View File

@ -915,7 +915,7 @@ MODULE_ALIAS("platform:uartlite");
static struct platform_driver ulite_platform_driver = { static struct platform_driver ulite_platform_driver = {
.probe = ulite_probe, .probe = ulite_probe,
.remove_new = ulite_remove, .remove = ulite_remove,
.driver = { .driver = {
.name = "uartlite", .name = "uartlite",
.of_match_table = of_match_ptr(ulite_of_match), .of_match_table = of_match_ptr(ulite_of_match),

View File

@ -1484,7 +1484,7 @@ static struct platform_driver ucc_uart_of_driver = {
.of_match_table = ucc_uart_match, .of_match_table = ucc_uart_match,
}, },
.probe = ucc_uart_probe, .probe = ucc_uart_probe,
.remove_new = ucc_uart_remove, .remove = ucc_uart_remove,
}; };
static int __init ucc_uart_init(void) static int __init ucc_uart_init(void)

View File

@ -1903,7 +1903,7 @@ static void cdns_uart_remove(struct platform_device *pdev)
static struct platform_driver cdns_uart_platform_driver = { static struct platform_driver cdns_uart_platform_driver = {
.probe = cdns_uart_probe, .probe = cdns_uart_probe,
.remove_new = cdns_uart_remove, .remove = cdns_uart_remove,
.driver = { .driver = {
.name = CDNS_UART_NAME, .name = CDNS_UART_NAME,
.of_match_table = cdns_uart_of_match, .of_match_table = cdns_uart_of_match,

View File

@ -3631,7 +3631,7 @@ static struct ctl_table tty_table[] = {
.data = &tty_ldisc_autoload, .data = &tty_ldisc_autoload,
.maxlen = sizeof(tty_ldisc_autoload), .maxlen = sizeof(tty_ldisc_autoload),
.mode = 0644, .mode = 0644,
.proc_handler = proc_dointvec, .proc_handler = proc_dointvec_minmax,
.extra1 = SYSCTL_ZERO, .extra1 = SYSCTL_ZERO,
.extra2 = SYSCTL_ONE, .extra2 = SYSCTL_ONE,
}, },

View File

@ -11,6 +11,8 @@
Supported chipsets: 93c46, 93c56 and 93c66. Supported chipsets: 93c46, 93c56 and 93c66.
*/ */
#include <linux/bits.h>
/* /*
* EEPROM operation defines. * EEPROM operation defines.
*/ */
@ -34,6 +36,7 @@
* @register_write(struct eeprom_93cx6 *eeprom): handler to * @register_write(struct eeprom_93cx6 *eeprom): handler to
* write to the eeprom register by using all reg_* fields. * write to the eeprom register by using all reg_* fields.
* @width: eeprom width, should be one of the PCI_EEPROM_WIDTH_* defines * @width: eeprom width, should be one of the PCI_EEPROM_WIDTH_* defines
* @quirks: eeprom or controller quirks
* @drive_data: Set if we're driving the data line. * @drive_data: Set if we're driving the data line.
* @reg_data_in: register field to indicate data input * @reg_data_in: register field to indicate data input
* @reg_data_out: register field to indicate data output * @reg_data_out: register field to indicate data output
@ -50,6 +53,9 @@ struct eeprom_93cx6 {
void (*register_write)(struct eeprom_93cx6 *eeprom); void (*register_write)(struct eeprom_93cx6 *eeprom);
int width; int width;
unsigned int quirks;
/* Some EEPROMs require an extra clock cycle before reading */
#define PCI_EEPROM_QUIRK_EXTRA_READ_CYCLE BIT(0)
char drive_data; char drive_data;
char reg_data_in; char reg_data_in;
@ -71,3 +77,8 @@ extern void eeprom_93cx6_wren(struct eeprom_93cx6 *eeprom, bool enable);
extern void eeprom_93cx6_write(struct eeprom_93cx6 *eeprom, extern void eeprom_93cx6_write(struct eeprom_93cx6 *eeprom,
u8 addr, u16 data); u8 addr, u16 data);
static inline bool has_quirk_extra_read_cycle(struct eeprom_93cx6 *eeprom)
{
return eeprom->quirks & PCI_EEPROM_QUIRK_EXTRA_READ_CYCLE;
}

View File

@ -37,7 +37,6 @@
*/ */
#include <linux/array_size.h> #include <linux/array_size.h>
#include <linux/dma-mapping.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/stddef.h> #include <linux/stddef.h>
#include <linux/types.h> #include <linux/types.h>

View File

@ -10,7 +10,6 @@
#define SA11X0_SERIAL_H #define SA11X0_SERIAL_H
struct uart_port; struct uart_port;
struct uart_info;
/* /*
* This is a temporary structure for registering these * This is a temporary structure for registering these

View File

@ -9,6 +9,7 @@
#include <linux/kfifo.h> #include <linux/kfifo.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/scatterlist.h> #include <linux/scatterlist.h>
#include <linux/dma-mapping.h>
/* /*
* This module shows how to handle fifo dma operations. * This module shows how to handle fifo dma operations.