mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2024-12-28 00:33:16 +00:00
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:
commit
d8b78066f4
@ -18,16 +18,15 @@ properties:
|
||||
description: prop-encoded-array <a b>
|
||||
$ref: /schemas/types.yaml#/definitions/uint32-array
|
||||
items:
|
||||
items:
|
||||
- description: Delay between rts signal and beginning of data sent in
|
||||
milliseconds. It corresponds to the delay before sending data.
|
||||
default: 0
|
||||
maximum: 100
|
||||
- description: Delay between end of data sent and rts signal in milliseconds.
|
||||
It corresponds to the delay after sending data and actual release
|
||||
of the line.
|
||||
default: 0
|
||||
maximum: 100
|
||||
- description: Delay between rts signal and beginning of data sent in
|
||||
milliseconds. It corresponds to the delay before sending data.
|
||||
default: 0
|
||||
maximum: 100
|
||||
- description: Delay between end of data sent and rts signal in milliseconds.
|
||||
It corresponds to the delay after sending data and actual release
|
||||
of the line.
|
||||
default: 0
|
||||
maximum: 100
|
||||
|
||||
rs485-rts-active-high:
|
||||
description: drive RTS high when sending (this is the default).
|
||||
|
@ -27,6 +27,7 @@ properties:
|
||||
- samsung,exynos4210-uart
|
||||
- samsung,exynos5433-uart
|
||||
- samsung,exynos850-uart
|
||||
- samsung,exynos8895-uart
|
||||
- items:
|
||||
- enum:
|
||||
- samsung,exynos7-uart
|
||||
@ -160,18 +161,27 @@ allOf:
|
||||
contains:
|
||||
enum:
|
||||
- google,gs101-uart
|
||||
- samsung,exynos8895-uart
|
||||
then:
|
||||
required:
|
||||
- samsung,uart-fifosize
|
||||
properties:
|
||||
reg-io-width: false
|
||||
|
||||
clocks:
|
||||
maxItems: 2
|
||||
|
||||
clock-names:
|
||||
maxItems: 2
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- google,gs101-uart
|
||||
then:
|
||||
properties:
|
||||
reg-io-width: false
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
|
@ -37,6 +37,8 @@ properties:
|
||||
- const: renesas,rzn1-uart
|
||||
- items:
|
||||
- enum:
|
||||
- brcm,bcm11351-dw-apb-uart
|
||||
- brcm,bcm21664-dw-apb-uart
|
||||
- rockchip,px30-uart
|
||||
- rockchip,rk1808-uart
|
||||
- rockchip,rk3036-uart
|
||||
@ -48,18 +50,13 @@ properties:
|
||||
- rockchip,rk3328-uart
|
||||
- rockchip,rk3368-uart
|
||||
- rockchip,rk3399-uart
|
||||
- rockchip,rk3528-uart
|
||||
- rockchip,rk3568-uart
|
||||
- rockchip,rk3576-uart
|
||||
- rockchip,rk3588-uart
|
||||
- rockchip,rv1108-uart
|
||||
- rockchip,rv1126-uart
|
||||
- const: snps,dw-apb-uart
|
||||
- items:
|
||||
- enum:
|
||||
- brcm,bcm11351-dw-apb-uart
|
||||
- brcm,bcm21664-dw-apb-uart
|
||||
- const: snps,dw-apb-uart
|
||||
- items:
|
||||
- enum:
|
||||
- sophgo,sg2044-uart
|
||||
- starfive,jh7100-hsuart
|
||||
- starfive,jh7100-uart
|
||||
- starfive,jh7110-uart
|
||||
|
@ -17,6 +17,7 @@ properties:
|
||||
oneOf:
|
||||
- items:
|
||||
- enum:
|
||||
- sprd,sc9632-uart
|
||||
- sprd,sc9860-uart
|
||||
- sprd,sc9863a-uart
|
||||
- sprd,ums512-uart
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include <linux/slab.h>
|
||||
#include <linux/kfifo.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
@ -8,6 +8,7 @@
|
||||
* Supported chipsets: 93c46 & 93c66.
|
||||
*/
|
||||
|
||||
#include <linux/bits.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.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.
|
||||
*/
|
||||
eeprom->reg_data_in = !!(data & (1 << (i - 1)));
|
||||
eeprom->reg_data_in = !!(data & BIT(i - 1));
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
if (eeprom->reg_data_out)
|
||||
buf |= (1 << (i - 1));
|
||||
buf |= BIT(i - 1);
|
||||
|
||||
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,
|
||||
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.
|
||||
*/
|
||||
@ -252,6 +258,11 @@ void eeprom_93cx6_readb(struct eeprom_93cx6 *eeprom, const u8 byte,
|
||||
eeprom_93cx6_write_bits(eeprom, command,
|
||||
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.
|
||||
*/
|
||||
|
@ -569,7 +569,7 @@ static struct platform_driver aspeed_vuart_driver = {
|
||||
.of_match_table = aspeed_vuart_table,
|
||||
},
|
||||
.probe = aspeed_vuart_probe,
|
||||
.remove_new = aspeed_vuart_remove,
|
||||
.remove = aspeed_vuart_remove,
|
||||
};
|
||||
|
||||
module_platform_driver(aspeed_vuart_driver);
|
||||
|
@ -267,7 +267,7 @@ static struct platform_driver bcm2835aux_serial_driver = {
|
||||
.pm = pm_ptr(&bcm2835aux_dev_pm_ops),
|
||||
},
|
||||
.probe = bcm2835aux_serial_probe,
|
||||
.remove_new = bcm2835aux_serial_remove,
|
||||
.remove = bcm2835aux_serial_remove,
|
||||
};
|
||||
module_platform_driver(bcm2835aux_serial_driver);
|
||||
|
||||
|
@ -812,7 +812,7 @@ static int brcmuart_handle_irq(struct uart_port *p)
|
||||
/*
|
||||
* if Receive Data Interrupt is enabled and
|
||||
* 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.
|
||||
*/
|
||||
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,
|
||||
},
|
||||
.probe = brcmuart_probe,
|
||||
.remove_new = brcmuart_remove,
|
||||
.remove = brcmuart_remove,
|
||||
};
|
||||
|
||||
static int __init brcmuart_init(void)
|
||||
|
@ -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,
|
||||
};
|
||||
|
||||
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,
|
||||
.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 = "marvell,armada-38x-uart", .data = &dw8250_armada_38x_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 */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, dw8250_of_match);
|
||||
@ -796,7 +797,7 @@ static struct platform_driver dw8250_platform_driver = {
|
||||
.acpi_match_table = dw8250_acpi_match,
|
||||
},
|
||||
.probe = dw8250_probe,
|
||||
.remove_new = dw8250_remove,
|
||||
.remove = dw8250_remove,
|
||||
};
|
||||
|
||||
module_platform_driver(dw8250_platform_driver);
|
||||
|
@ -219,7 +219,7 @@ static struct platform_driver serial8250_em_platform_driver = {
|
||||
.of_match_table = serial8250_em_dt_ids,
|
||||
},
|
||||
.probe = serial8250_em_probe,
|
||||
.remove_new = serial8250_em_remove,
|
||||
.remove = serial8250_em_remove,
|
||||
};
|
||||
|
||||
module_platform_driver(serial8250_em_platform_driver);
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include <linux/delay.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/dmi.h>
|
||||
#include <linux/eeprom_93cx6.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/math.h>
|
||||
@ -135,8 +136,6 @@
|
||||
#define UART_EXAR_REGB_EECS BIT(5)
|
||||
#define UART_EXAR_REGB_EEDI BIT(6)
|
||||
#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_XR17V25X_PORT_OFFSET 0x200
|
||||
@ -179,18 +178,19 @@
|
||||
|
||||
/* CTI EEPROM offsets */
|
||||
#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_XR17V25X_PART_NUM 0x0E /* 4 words */
|
||||
#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_XR17V35X_SERIAL_NUM 0x11 /* 2 word */
|
||||
#define CTI_EE_OFF_XR17V35X_BRD_FLAGS 0x13 /* 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_OSC_FREQ_LOWER GENMASK(15, 0)
|
||||
#define CTI_EE_MASK_OSC_FREQ_UPPER GENMASK(31, 16)
|
||||
#define CTI_EE_MASK_OSC_FREQ GENMASK(31, 0)
|
||||
|
||||
#define CTI_FPGA_RS485_IO_REG 0x2008
|
||||
#define CTI_FPGA_CFG_INT_EN_REG 0x48
|
||||
@ -252,6 +252,7 @@ struct exar8250 {
|
||||
unsigned int nr;
|
||||
unsigned int osc_freq;
|
||||
struct exar8250_board *board;
|
||||
struct eeprom_93cx6 eeprom;
|
||||
void __iomem *virt;
|
||||
int line[];
|
||||
};
|
||||
@ -267,92 +268,37 @@ static inline u8 exar_read_reg(struct exar8250 *priv, unsigned int 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
|
||||
exar_write_reg(priv, UART_EXAR_REGB, UART_EXAR_REGB_EECS);
|
||||
// Min ~500ns delay needed between CS assert and EEPROM access
|
||||
udelay(1);
|
||||
struct exar8250 *priv = eeprom->data;
|
||||
u8 regb = exar_read_reg(priv, UART_EXAR_REGB);
|
||||
|
||||
/* 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;
|
||||
|
||||
if (bit)
|
||||
value |= UART_EXAR_REGB_EEDI;
|
||||
|
||||
// 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;
|
||||
priv->eeprom.data = priv;
|
||||
priv->eeprom.register_read = exar_eeprom_93cx6_reg_read;
|
||||
priv->eeprom.register_write = exar_eeprom_93cx6_reg_write;
|
||||
priv->eeprom.width = PCI_EEPROM_WIDTH_93C46;
|
||||
priv->eeprom.quirks |= PCI_EEPROM_QUIRK_EXTRA_READ_CYCLE;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -360,7 +306,7 @@ static u16 exar_ee_read(struct exar8250 *priv, u8 ee_addr)
|
||||
* @priv: Device's private structure
|
||||
* @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
|
||||
* 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);
|
||||
|
||||
/*
|
||||
* Make sure all interrups are masked until initialization is
|
||||
* Make sure all interrupts are masked until initialization is
|
||||
* complete and the FIFOs are cleared
|
||||
*
|
||||
* 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)
|
||||
{
|
||||
u16 lower_word;
|
||||
u16 upper_word;
|
||||
__le16 ee_words[2];
|
||||
u32 osc_freq;
|
||||
|
||||
lower_word = exar_ee_read(priv, eeprom_offset);
|
||||
// Check if EEPROM word was blank
|
||||
if (lower_word == 0xFFFF)
|
||||
eeprom_93cx6_multiread(&priv->eeprom, eeprom_offset, ee_words, ARRAY_SIZE(ee_words));
|
||||
|
||||
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;
|
||||
|
||||
upper_word = exar_ee_read(priv, (eeprom_offset + 1));
|
||||
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);
|
||||
return osc_freq;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -833,7 +775,7 @@ static enum cti_port_type cti_get_port_type_xr17v35x(struct exar8250 *priv,
|
||||
u8 offset;
|
||||
|
||||
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);
|
||||
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)
|
||||
return rc;
|
||||
|
||||
exar_eeprom_init(priv);
|
||||
|
||||
for (i = 0; i < nr_ports && i < maxnr; i++) {
|
||||
rc = board->setup(priv, pcidev, &uart, i);
|
||||
if (rc) {
|
||||
|
@ -21,6 +21,7 @@
|
||||
#define CHIP_ID_F81866 0x1010
|
||||
#define CHIP_ID_F81966 0x0215
|
||||
#define CHIP_ID_F81216AD 0x1602
|
||||
#define CHIP_ID_F81216E 0x1617
|
||||
#define CHIP_ID_F81216H 0x0501
|
||||
#define CHIP_ID_F81216 0x0802
|
||||
#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"))
|
||||
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(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_F81966:
|
||||
case CHIP_ID_F81216AD:
|
||||
case CHIP_ID_F81216E:
|
||||
case CHIP_ID_F81216H:
|
||||
case CHIP_ID_F81216:
|
||||
break;
|
||||
@ -181,6 +183,7 @@ static int fintek_8250_get_ldn_range(struct fintek_8250 *pdata, int *min,
|
||||
return 0;
|
||||
|
||||
case CHIP_ID_F81216AD:
|
||||
case CHIP_ID_F81216E:
|
||||
case CHIP_ID_F81216H:
|
||||
case CHIP_ID_F81216:
|
||||
*min = F81216_LDN_LOW;
|
||||
@ -250,6 +253,7 @@ static void fintek_8250_set_irq_mode(struct fintek_8250 *pdata, bool is_level)
|
||||
break;
|
||||
|
||||
case CHIP_ID_F81216AD:
|
||||
case CHIP_ID_F81216E:
|
||||
case CHIP_ID_F81216H:
|
||||
case CHIP_ID_F81216:
|
||||
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)
|
||||
{
|
||||
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_F81866:
|
||||
sio_write_mask_reg(pdata, FIFO_CTRL,
|
||||
@ -297,6 +302,7 @@ static void fintek_8250_set_termios(struct uart_port *port,
|
||||
goto exit;
|
||||
|
||||
switch (pdata->pid) {
|
||||
case CHIP_ID_F81216E:
|
||||
case CHIP_ID_F81216H:
|
||||
reg = RS485;
|
||||
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;
|
||||
|
||||
switch (pdata->pid) {
|
||||
case CHIP_ID_F81216E:
|
||||
case CHIP_ID_F81216H:
|
||||
case CHIP_ID_F81966:
|
||||
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;
|
||||
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 */
|
||||
break;
|
||||
}
|
||||
|
@ -179,7 +179,7 @@ static struct platform_driver fsl8250_platform_driver = {
|
||||
.acpi_match_table = ACPI_PTR(fsl_8250_acpi_id),
|
||||
},
|
||||
.probe = fsl8250_acpi_probe,
|
||||
.remove_new = fsl8250_acpi_remove,
|
||||
.remove = fsl8250_acpi_remove,
|
||||
};
|
||||
|
||||
module_platform_driver(fsl8250_platform_driver);
|
||||
|
@ -361,7 +361,7 @@ static struct platform_driver ingenic_uart_platform_driver = {
|
||||
.of_match_table = of_match,
|
||||
},
|
||||
.probe = ingenic_uart_probe,
|
||||
.remove_new = ingenic_uart_remove,
|
||||
.remove = ingenic_uart_remove,
|
||||
};
|
||||
|
||||
module_platform_driver(ingenic_uart_platform_driver);
|
||||
|
@ -84,7 +84,7 @@ static void serial8250_ioc3_remove(struct platform_device *pdev)
|
||||
|
||||
static struct platform_driver serial8250_ioc3_driver = {
|
||||
.probe = serial8250_ioc3_probe,
|
||||
.remove_new = serial8250_ioc3_remove,
|
||||
.remove = serial8250_ioc3_remove,
|
||||
.driver = {
|
||||
.name = "ioc3-serial8250",
|
||||
}
|
||||
|
@ -195,7 +195,7 @@ MODULE_DEVICE_TABLE(of, lpc18xx_serial_match);
|
||||
|
||||
static struct platform_driver lpc18xx_serial_driver = {
|
||||
.probe = lpc18xx_serial_probe,
|
||||
.remove_new = lpc18xx_serial_remove,
|
||||
.remove = lpc18xx_serial_remove,
|
||||
.driver = {
|
||||
.name = "lpc18xx-uart",
|
||||
.of_match_table = lpc18xx_serial_match,
|
||||
|
@ -346,8 +346,8 @@ mtk8250_set_termios(struct uart_port *port, struct ktermios *termios,
|
||||
/*
|
||||
* Mediatek UARTs use an extra highspeed register (MTK_UART_HIGHS)
|
||||
*
|
||||
* We need to recalcualte the quot register, as the claculation depends
|
||||
* on the vaule in the highspeed register.
|
||||
* We need to recalculate the quot register, as the calculation depends
|
||||
* on the value in the highspeed register.
|
||||
*
|
||||
* Some baudrates are not supported by the chip, so we use the next
|
||||
* 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,
|
||||
},
|
||||
.probe = mtk8250_probe,
|
||||
.remove_new = mtk8250_remove,
|
||||
.remove = mtk8250_remove,
|
||||
};
|
||||
module_platform_driver(mtk8250_platform_driver);
|
||||
|
||||
|
@ -352,7 +352,7 @@ static struct platform_driver of_platform_serial_driver = {
|
||||
.pm = &of_serial_pm_ops,
|
||||
},
|
||||
.probe = of_platform_serial_probe,
|
||||
.remove_new = of_platform_serial_remove,
|
||||
.remove = of_platform_serial_remove,
|
||||
};
|
||||
|
||||
module_platform_driver(of_platform_serial_driver);
|
||||
|
@ -776,12 +776,12 @@ static void omap_8250_shutdown(struct uart_port *port)
|
||||
struct uart_8250_port *up = up_to_u8250p(port);
|
||||
struct omap8250_priv *priv = port->private_data;
|
||||
|
||||
pm_runtime_get_sync(port->dev);
|
||||
|
||||
flush_work(&priv->qos_work);
|
||||
if (up->dma)
|
||||
omap_8250_rx_dma_flush(up);
|
||||
|
||||
pm_runtime_get_sync(port->dev);
|
||||
|
||||
serial_out(up, UART_OMAP_WER, 0);
|
||||
if (priv->habit & UART_HAS_EFR2)
|
||||
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
|
||||
* 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.
|
||||
*/
|
||||
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);
|
||||
} else {
|
||||
/*
|
||||
* try again due to an earlier failer which
|
||||
* try again due to an earlier failure which
|
||||
* might have been resolved by now.
|
||||
*/
|
||||
if (omap_8250_tx_dma(up))
|
||||
@ -1867,7 +1867,7 @@ static struct platform_driver omap8250_platform_driver = {
|
||||
.of_match_table = omap8250_dt_ids,
|
||||
},
|
||||
.probe = omap8250_probe,
|
||||
.remove_new = omap8250_remove,
|
||||
.remove = omap8250_remove,
|
||||
};
|
||||
module_platform_driver(omap8250_platform_driver);
|
||||
|
||||
|
@ -285,7 +285,7 @@ MODULE_DEVICE_TABLE(acpi, acpi_platform_serial_table);
|
||||
|
||||
static struct platform_driver serial8250_isa_driver = {
|
||||
.probe = serial8250_probe,
|
||||
.remove_new = serial8250_remove,
|
||||
.remove = serial8250_remove,
|
||||
.suspend = serial8250_suspend,
|
||||
.resume = serial8250_resume,
|
||||
.driver = {
|
||||
|
@ -154,7 +154,7 @@ static void serial_pxa_remove(struct platform_device *pdev)
|
||||
|
||||
static struct platform_driver serial_pxa_driver = {
|
||||
.probe = serial_pxa_probe,
|
||||
.remove_new = serial_pxa_remove,
|
||||
.remove = serial_pxa_remove,
|
||||
|
||||
.driver = {
|
||||
.name = "pxa2xx-uart",
|
||||
|
@ -182,7 +182,7 @@ static struct platform_driver tegra_uart_driver = {
|
||||
.acpi_match_table = ACPI_PTR(tegra_uart_acpi_match),
|
||||
},
|
||||
.probe = tegra_uart_probe,
|
||||
.remove_new = tegra_uart_remove,
|
||||
.remove = tegra_uart_remove,
|
||||
};
|
||||
|
||||
module_platform_driver(tegra_uart_driver);
|
||||
|
@ -282,7 +282,7 @@ MODULE_DEVICE_TABLE(of, uniphier_uart_match);
|
||||
|
||||
static struct platform_driver uniphier_uart_platform_driver = {
|
||||
.probe = uniphier_uart_probe,
|
||||
.remove_new = uniphier_uart_remove,
|
||||
.remove = uniphier_uart_remove,
|
||||
.driver = {
|
||||
.name = "uniphier-uart",
|
||||
.of_match_table = uniphier_uart_match,
|
||||
|
@ -150,6 +150,7 @@ config SERIAL_8250_EXAR
|
||||
tristate "8250/16550 Exar/Commtech PCI/PCIe device support"
|
||||
depends on SERIAL_8250 && PCI
|
||||
select SERIAL_8250_PCILIB
|
||||
select EEPROM_93CX6
|
||||
default SERIAL_8250
|
||||
help
|
||||
This builds support for XR17C1xx, XR17V3xx and some Commtech
|
||||
|
@ -175,8 +175,8 @@ static int altera_jtaguart_startup(struct uart_port *port)
|
||||
ret = request_irq(port->irq, altera_jtaguart_interrupt, 0,
|
||||
DRV_NAME, port);
|
||||
if (ret) {
|
||||
pr_err(DRV_NAME ": unable to attach Altera JTAG UART %d "
|
||||
"interrupt vector=%d\n", port->line, port->irq);
|
||||
dev_err(port->dev, "unable to attach Altera JTAG UART %d interrupt vector=%d\n",
|
||||
port->line, port->irq);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -449,7 +449,7 @@ MODULE_DEVICE_TABLE(of, altera_jtaguart_match);
|
||||
|
||||
static struct platform_driver altera_jtaguart_platform_driver = {
|
||||
.probe = altera_jtaguart_probe,
|
||||
.remove_new = altera_jtaguart_remove,
|
||||
.remove = altera_jtaguart_remove,
|
||||
.driver = {
|
||||
.name = DRV_NAME,
|
||||
.of_match_table = of_match_ptr(altera_jtaguart_match),
|
||||
|
@ -307,8 +307,8 @@ static int altera_uart_startup(struct uart_port *port)
|
||||
ret = request_irq(port->irq, altera_uart_interrupt, 0,
|
||||
dev_name(port->dev), port);
|
||||
if (ret) {
|
||||
pr_err(DRV_NAME ": unable to attach Altera UART %d "
|
||||
"interrupt vector=%d\n", port->line, port->irq);
|
||||
dev_err(port->dev, "unable to attach Altera UART %d interrupt vector=%d\n",
|
||||
port->line, port->irq);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
@ -617,7 +617,7 @@ MODULE_DEVICE_TABLE(of, altera_uart_match);
|
||||
|
||||
static struct platform_driver altera_uart_platform_driver = {
|
||||
.probe = altera_uart_probe,
|
||||
.remove_new = altera_uart_remove,
|
||||
.remove = altera_uart_remove,
|
||||
.driver = {
|
||||
.name = DRV_NAME,
|
||||
.of_match_table = of_match_ptr(altera_uart_match),
|
||||
|
@ -1819,6 +1819,13 @@ static void pl011_unthrottle_rx(struct uart_port *port)
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@ -2937,7 +2944,7 @@ MODULE_DEVICE_TABLE(acpi, sbsa_uart_acpi_match);
|
||||
|
||||
static struct platform_driver arm_sbsa_uart_platform_driver = {
|
||||
.probe = sbsa_uart_probe,
|
||||
.remove_new = sbsa_uart_remove,
|
||||
.remove = sbsa_uart_remove,
|
||||
.driver = {
|
||||
.name = "sbsa-uart",
|
||||
.pm = &pl011_dev_pm_ops,
|
||||
|
@ -832,7 +832,7 @@ MODULE_DEVICE_TABLE(of, ar933x_uart_of_ids);
|
||||
|
||||
static struct platform_driver ar933x_uart_platform_driver = {
|
||||
.probe = ar933x_uart_probe,
|
||||
.remove_new = ar933x_uart_remove,
|
||||
.remove = ar933x_uart_remove,
|
||||
.driver = {
|
||||
.name = DRIVER_NAME,
|
||||
.of_match_table = of_match_ptr(ar933x_uart_of_ids),
|
||||
|
@ -1166,7 +1166,7 @@ static void atmel_rx_from_dma(struct uart_port *port)
|
||||
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,
|
||||
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)
|
||||
{
|
||||
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) {
|
||||
port->membase = ioremap(port->mapbase, size);
|
||||
if (port->membase == NULL) {
|
||||
release_mem_region(port->mapbase, size);
|
||||
return -ENOMEM;
|
||||
}
|
||||
port->membase = devm_platform_ioremap_resource(mpdev, 0);
|
||||
if (IS_ERR(port->membase))
|
||||
return PTR_ERR(port->membase);
|
||||
}
|
||||
|
||||
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 = {
|
||||
.probe = atmel_serial_probe,
|
||||
.remove_new = atmel_serial_remove,
|
||||
.remove = atmel_serial_remove,
|
||||
.driver = {
|
||||
.name = "atmel_usart_serial",
|
||||
.of_match_table = of_match_ptr(atmel_serial_dt_ids),
|
||||
|
@ -884,7 +884,7 @@ MODULE_DEVICE_TABLE(of, bcm63xx_of_match);
|
||||
*/
|
||||
static struct platform_driver bcm_uart_platform_driver = {
|
||||
.probe = bcm_uart_probe,
|
||||
.remove_new = bcm_uart_remove,
|
||||
.remove = bcm_uart_remove,
|
||||
.driver = {
|
||||
.name = "bcm63xx_uart",
|
||||
.of_match_table = bcm63xx_of_match,
|
||||
|
@ -529,7 +529,7 @@ static struct platform_driver clps711x_uart_platform = {
|
||||
.of_match_table = of_match_ptr(clps711x_uart_dt_ids),
|
||||
},
|
||||
.probe = uart_clps711x_probe,
|
||||
.remove_new = uart_clps711x_remove,
|
||||
.remove = uart_clps711x_remove,
|
||||
};
|
||||
|
||||
static int __init uart_clps711x_init(void)
|
||||
|
@ -1573,7 +1573,7 @@ static struct platform_driver cpm_uart_driver = {
|
||||
.of_match_table = cpm_uart_match,
|
||||
},
|
||||
.probe = cpm_uart_probe,
|
||||
.remove_new = cpm_uart_remove,
|
||||
.remove = cpm_uart_remove,
|
||||
};
|
||||
|
||||
static int __init cpm_uart_init(void)
|
||||
|
@ -522,7 +522,7 @@ static struct platform_driver digicolor_uart_platform = {
|
||||
.of_match_table = of_match_ptr(digicolor_uart_dt_ids),
|
||||
},
|
||||
.probe = digicolor_uart_probe,
|
||||
.remove_new = digicolor_uart_remove,
|
||||
.remove = digicolor_uart_remove,
|
||||
};
|
||||
|
||||
static int __init digicolor_uart_init(void)
|
||||
|
@ -423,7 +423,7 @@ static void esp32s3_acm_remove(struct platform_device *pdev)
|
||||
|
||||
static struct platform_driver esp32s3_acm_driver = {
|
||||
.probe = esp32s3_acm_probe,
|
||||
.remove_new = esp32s3_acm_remove,
|
||||
.remove = esp32s3_acm_remove,
|
||||
.driver = {
|
||||
.name = DRIVER_NAME,
|
||||
.of_match_table = esp32s3_acm_dt_ids,
|
||||
|
@ -743,7 +743,7 @@ static void esp32_uart_remove(struct platform_device *pdev)
|
||||
|
||||
static struct platform_driver esp32_uart_driver = {
|
||||
.probe = esp32_uart_probe,
|
||||
.remove_new = esp32_uart_remove,
|
||||
.remove = esp32_uart_remove,
|
||||
.driver = {
|
||||
.name = DRIVER_NAME,
|
||||
.of_match_table = esp32_uart_dt_ids,
|
||||
|
@ -882,7 +882,7 @@ static SIMPLE_DEV_PM_OPS(linflex_pm_ops, linflex_suspend, linflex_resume);
|
||||
|
||||
static struct platform_driver linflex_driver = {
|
||||
.probe = linflex_probe,
|
||||
.remove_new = linflex_remove,
|
||||
.remove = linflex_remove,
|
||||
.driver = {
|
||||
.name = DRIVER_NAME,
|
||||
.of_match_table = linflex_dt_ids,
|
||||
|
@ -184,6 +184,7 @@
|
||||
#define UARTCTRL_SBK 0x00010000
|
||||
#define UARTCTRL_MA1IE 0x00008000
|
||||
#define UARTCTRL_MA2IE 0x00004000
|
||||
#define UARTCTRL_M7 0x00000800
|
||||
#define UARTCTRL_IDLECFG GENMASK(10, 8)
|
||||
#define UARTCTRL_LOOPS 0x00000080
|
||||
#define UARTCTRL_DOZEEN 0x00000040
|
||||
@ -2222,8 +2223,9 @@ lpuart32_set_termios(struct uart_port *port, struct ktermios *termios,
|
||||
modem = lpuart32_read(&sport->port, UARTMODIR);
|
||||
sport->is_cs7 = false;
|
||||
/*
|
||||
* only support CS8 and CS7, and for CS7 must enable PE.
|
||||
* only support CS8 and CS7
|
||||
* supported mode:
|
||||
* - (7,n,1) (imx only)
|
||||
* - (7,e/o,1)
|
||||
* - (8,n,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 ||
|
||||
(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 & CSIZE) != CS8) {
|
||||
@ -2265,9 +2267,18 @@ lpuart32_set_termios(struct uart_port *port, struct ktermios *termios,
|
||||
else
|
||||
bd &= ~UARTBAUD_SBNS;
|
||||
|
||||
/* parity must be enabled when CS7 to match 8-bits format */
|
||||
if ((termios->c_cflag & CSIZE) == CS7)
|
||||
termios->c_cflag |= PARENB;
|
||||
/*
|
||||
* imx support 7-bits format, no limitation on parity when CS7
|
||||
* 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 & CMSPAR) {
|
||||
@ -3206,7 +3217,7 @@ static const struct dev_pm_ops lpuart_pm_ops = {
|
||||
|
||||
static struct platform_driver lpuart_driver = {
|
||||
.probe = lpuart_probe,
|
||||
.remove_new = lpuart_remove,
|
||||
.remove = lpuart_remove,
|
||||
.driver = {
|
||||
.name = "fsl-lpuart",
|
||||
.of_match_table = lpuart_dt_ids,
|
||||
|
@ -230,6 +230,8 @@ struct imx_port {
|
||||
unsigned int saved_reg[10];
|
||||
bool context_saved;
|
||||
|
||||
bool last_putchar_was_newline;
|
||||
|
||||
enum imx_tx_state tx_state;
|
||||
struct hrtimer trigger_start_tx;
|
||||
struct hrtimer trigger_stop_tx;
|
||||
@ -370,6 +372,7 @@ static void imx_uart_soft_reset(struct imx_port *sport)
|
||||
sport->idle_counter = 0;
|
||||
}
|
||||
|
||||
/* called with port.lock taken and irqs off */
|
||||
static void imx_uart_disable_loopback_rs485(struct imx_port *sport)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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
|
||||
* 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.
|
||||
*
|
||||
* Called with port.lock taken and irqs off.
|
||||
*/
|
||||
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)
|
||||
{
|
||||
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.
|
||||
*/
|
||||
/* called with port.lock taken and irqs off */
|
||||
static unsigned int imx_uart_get_hwmctrl(struct imx_port *sport)
|
||||
{
|
||||
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.
|
||||
*
|
||||
* Called with port.lock taken and irqs off.
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
/* called with port.lock taken and irqs off */
|
||||
static void imx_uart_clear_rx_errors(struct imx_port *sport)
|
||||
{
|
||||
struct tty_port *port = &sport->port.state->port;
|
||||
@ -1422,6 +1433,7 @@ static int imx_uart_dma_init(struct imx_port *sport)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* called with port.lock taken and irqs off */
|
||||
static void imx_uart_enable_dma(struct imx_port *sport)
|
||||
{
|
||||
u32 ucr1;
|
||||
@ -2069,26 +2081,34 @@ static void imx_uart_console_putchar(struct uart_port *port, unsigned char ch)
|
||||
barrier();
|
||||
|
||||
imx_uart_writel(sport, ch, URTX0);
|
||||
|
||||
sport->last_putchar_was_newline = (ch == '\n');
|
||||
}
|
||||
|
||||
/*
|
||||
* Interrupts are disabled on entering
|
||||
*/
|
||||
static void
|
||||
imx_uart_console_write(struct console *co, const char *s, unsigned int count)
|
||||
static void imx_uart_console_device_lock(struct console *co, unsigned long *flags)
|
||||
{
|
||||
struct uart_port *up = &imx_uart_ports[co->index]->port;
|
||||
|
||||
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 uart_port *port = &sport->port;
|
||||
struct imx_port_ucrs old_ucr;
|
||||
unsigned long flags;
|
||||
unsigned int ucr1, usr2;
|
||||
int locked = 1;
|
||||
|
||||
if (sport->port.sysrq)
|
||||
locked = 0;
|
||||
else if (oops_in_progress)
|
||||
locked = uart_port_trylock_irqsave(&sport->port, &flags);
|
||||
else
|
||||
uart_port_lock_irqsave(&sport->port, &flags);
|
||||
if (!nbcon_enter_unsafe(wctxt))
|
||||
return;
|
||||
|
||||
/*
|
||||
* 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);
|
||||
|
||||
imx_uart_writel(sport, ucr1, UCR1);
|
||||
|
||||
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
|
||||
@ -2115,8 +2137,73 @@ imx_uart_console_write(struct console *co, const char *s, unsigned int count)
|
||||
0, USEC_PER_SEC, false, sport, USR2);
|
||||
imx_uart_ucrs_restore(sport, &old_ucr);
|
||||
|
||||
if (locked)
|
||||
uart_port_unlock_irqrestore(&sport->port, flags);
|
||||
nbcon_exit_unsafe(wctxt);
|
||||
}
|
||||
|
||||
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)
|
||||
goto error_console;
|
||||
|
||||
sport->last_putchar_was_newline = true;
|
||||
|
||||
if (options)
|
||||
uart_parse_options(options, &baud, &parity, &bits, &flow);
|
||||
else
|
||||
@ -2244,11 +2333,14 @@ imx_uart_console_exit(struct console *co)
|
||||
static struct uart_driver imx_uart_uart_driver;
|
||||
static struct console imx_uart_console = {
|
||||
.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,
|
||||
.setup = imx_uart_console_setup,
|
||||
.exit = imx_uart_console_exit,
|
||||
.flags = CON_PRINTBUFFER,
|
||||
.index = -1,
|
||||
.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);
|
||||
}
|
||||
|
||||
/* called with irq off */
|
||||
static void imx_uart_enable_wakeup(struct imx_port *sport, bool on)
|
||||
{
|
||||
u32 ucr3;
|
||||
|
||||
uart_port_lock(&sport->port);
|
||||
|
||||
ucr3 = imx_uart_readl(sport, UCR3);
|
||||
if (on) {
|
||||
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);
|
||||
}
|
||||
|
||||
uart_port_unlock(&sport->port);
|
||||
}
|
||||
|
||||
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 = {
|
||||
.probe = imx_uart_probe,
|
||||
.remove_new = imx_uart_remove,
|
||||
.remove = imx_uart_remove,
|
||||
|
||||
.driver = {
|
||||
.name = "imx-uart",
|
||||
|
@ -915,7 +915,7 @@ MODULE_DEVICE_TABLE(of, ltq_asc_match);
|
||||
|
||||
static struct platform_driver lqasc_driver = {
|
||||
.probe = lqasc_probe,
|
||||
.remove_new = lqasc_remove,
|
||||
.remove = lqasc_remove,
|
||||
.driver = {
|
||||
.name = DRVNAME,
|
||||
.of_match_table = ltq_asc_match,
|
||||
|
@ -353,7 +353,7 @@ MODULE_DEVICE_TABLE(of, liteuart_of_match);
|
||||
|
||||
static struct platform_driver liteuart_platform_driver = {
|
||||
.probe = liteuart_probe,
|
||||
.remove_new = liteuart_remove,
|
||||
.remove = liteuart_remove,
|
||||
.driver = {
|
||||
.name = KBUILD_MODNAME,
|
||||
.of_match_table = liteuart_of_match,
|
||||
|
@ -695,7 +695,7 @@ MODULE_DEVICE_TABLE(of, serial_hs_lpc32xx_dt_ids);
|
||||
|
||||
static struct platform_driver serial_hs_lpc32xx_driver = {
|
||||
.probe = serial_hs_lpc32xx_probe,
|
||||
.remove_new = serial_hs_lpc32xx_remove,
|
||||
.remove = serial_hs_lpc32xx_remove,
|
||||
.suspend = serial_hs_lpc32xx_suspend,
|
||||
.resume = serial_hs_lpc32xx_resume,
|
||||
.driver = {
|
||||
|
@ -794,7 +794,7 @@ static int ma35d1serial_resume(struct platform_device *dev)
|
||||
|
||||
static struct platform_driver ma35d1serial_driver = {
|
||||
.probe = ma35d1serial_probe,
|
||||
.remove_new = ma35d1serial_remove,
|
||||
.remove = ma35d1serial_remove,
|
||||
.suspend = ma35d1serial_suspend,
|
||||
.resume = ma35d1serial_resume,
|
||||
.driver = {
|
||||
|
@ -616,7 +616,7 @@ static void mcf_remove(struct platform_device *pdev)
|
||||
|
||||
static struct platform_driver mcf_platform_driver = {
|
||||
.probe = mcf_probe,
|
||||
.remove_new = mcf_remove,
|
||||
.remove = mcf_remove,
|
||||
.driver = {
|
||||
.name = "mcfuart",
|
||||
},
|
||||
|
@ -842,7 +842,7 @@ MODULE_DEVICE_TABLE(of, meson_uart_dt_match);
|
||||
|
||||
static struct platform_driver meson_uart_platform_driver = {
|
||||
.probe = meson_uart_probe,
|
||||
.remove_new = meson_uart_remove,
|
||||
.remove = meson_uart_remove,
|
||||
.driver = {
|
||||
.name = "meson_uart",
|
||||
.of_match_table = meson_uart_dt_match,
|
||||
|
@ -570,7 +570,7 @@ MODULE_DEVICE_TABLE(of, mlb_usio_dt_ids);
|
||||
|
||||
static struct platform_driver mlb_usio_driver = {
|
||||
.probe = mlb_usio_probe,
|
||||
.remove_new = mlb_usio_remove,
|
||||
.remove = mlb_usio_remove,
|
||||
.driver = {
|
||||
.name = USIO_NAME,
|
||||
.of_match_table = mlb_usio_dt_ids,
|
||||
|
@ -1843,7 +1843,7 @@ MODULE_DEVICE_TABLE(of, mpc52xx_uart_of_match);
|
||||
|
||||
static struct platform_driver mpc52xx_uart_of_driver = {
|
||||
.probe = mpc52xx_uart_of_probe,
|
||||
.remove_new = mpc52xx_uart_of_remove,
|
||||
.remove = mpc52xx_uart_of_remove,
|
||||
#ifdef CONFIG_PM
|
||||
.suspend = mpc52xx_uart_of_suspend,
|
||||
.resume = mpc52xx_uart_of_resume,
|
||||
|
@ -1894,7 +1894,7 @@ static const struct dev_pm_ops msm_serial_dev_pm_ops = {
|
||||
};
|
||||
|
||||
static struct platform_driver msm_platform_driver = {
|
||||
.remove_new = msm_serial_remove,
|
||||
.remove = msm_serial_remove,
|
||||
.probe = msm_serial_probe,
|
||||
.driver = {
|
||||
.name = "msm_serial",
|
||||
|
@ -1704,7 +1704,7 @@ static void mxs_auart_remove(struct platform_device *pdev)
|
||||
|
||||
static struct platform_driver mxs_auart_driver = {
|
||||
.probe = mxs_auart_probe,
|
||||
.remove_new = mxs_auart_remove,
|
||||
.remove = mxs_auart_remove,
|
||||
.driver = {
|
||||
.name = "mxs-auart",
|
||||
.of_match_table = mxs_auart_dt_ids,
|
||||
|
@ -1802,7 +1802,7 @@ MODULE_DEVICE_TABLE(of, omap_serial_of_match);
|
||||
|
||||
static struct platform_driver serial_omap_driver = {
|
||||
.probe = serial_omap_probe,
|
||||
.remove_new = serial_omap_remove,
|
||||
.remove = serial_omap_remove,
|
||||
.driver = {
|
||||
.name = OMAP_SERIAL_DRIVER_NAME,
|
||||
.pm = &serial_omap_dev_pm_ops,
|
||||
|
@ -730,7 +730,7 @@ static void owl_uart_remove(struct platform_device *pdev)
|
||||
|
||||
static struct platform_driver owl_uart_platform_driver = {
|
||||
.probe = owl_uart_probe,
|
||||
.remove_new = owl_uart_remove,
|
||||
.remove = owl_uart_remove,
|
||||
.driver = {
|
||||
.name = "owl-uart",
|
||||
.of_match_table = owl_uart_dt_matches,
|
||||
|
@ -956,7 +956,7 @@ MODULE_DEVICE_TABLE(of, pic32_serial_dt_ids);
|
||||
|
||||
static struct platform_driver pic32_uart_platform_driver = {
|
||||
.probe = pic32_uart_probe,
|
||||
.remove_new = pic32_uart_remove,
|
||||
.remove = pic32_uart_remove,
|
||||
.driver = {
|
||||
.name = PIC32_DEV_NAME,
|
||||
.of_match_table = of_match_ptr(pic32_serial_dt_ids),
|
||||
|
@ -1776,7 +1776,7 @@ static struct macio_driver pmz_driver = {
|
||||
|
||||
static struct platform_driver pmz_driver = {
|
||||
.probe = pmz_attach,
|
||||
.remove_new = pmz_detach,
|
||||
.remove = pmz_detach,
|
||||
.driver = {
|
||||
.name = "scc",
|
||||
},
|
||||
|
@ -1839,7 +1839,7 @@ static const struct of_device_id qcom_geni_serial_match_table[] = {
|
||||
MODULE_DEVICE_TABLE(of, qcom_geni_serial_match_table);
|
||||
|
||||
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,
|
||||
.driver = {
|
||||
.name = "qcom_geni_serial",
|
||||
|
@ -777,7 +777,7 @@ static void rda_uart_remove(struct platform_device *pdev)
|
||||
|
||||
static struct platform_driver rda_uart_platform_driver = {
|
||||
.probe = rda_uart_probe,
|
||||
.remove_new = rda_uart_remove,
|
||||
.remove = rda_uart_remove,
|
||||
.driver = {
|
||||
.name = "rda-uart",
|
||||
.of_match_table = rda_uart_dt_matches,
|
||||
|
@ -880,7 +880,7 @@ static void sa1100_serial_remove(struct platform_device *pdev)
|
||||
|
||||
static struct platform_driver sa11x0_serial_driver = {
|
||||
.probe = sa1100_serial_probe,
|
||||
.remove_new = sa1100_serial_remove,
|
||||
.remove = sa1100_serial_remove,
|
||||
.suspend = sa1100_serial_suspend,
|
||||
.resume = sa1100_serial_resume,
|
||||
.driver = {
|
||||
|
@ -2498,6 +2498,12 @@ static const struct s3c24xx_serial_drv_data exynos850_serial_drv_data = {
|
||||
.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 = {
|
||||
.info = {
|
||||
.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 EXYNOS5433_SERIAL_DRV_DATA (&exynos5433_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)
|
||||
|
||||
#else
|
||||
#define EXYNOS4210_SERIAL_DRV_DATA NULL
|
||||
#define EXYNOS5433_SERIAL_DRV_DATA NULL
|
||||
#define EXYNOS850_SERIAL_DRV_DATA NULL
|
||||
#define EXYNOS8895_SERIAL_DRV_DATA NULL
|
||||
#define GS101_SERIAL_DRV_DATA NULL
|
||||
#endif
|
||||
|
||||
@ -2623,6 +2631,9 @@ static const struct platform_device_id s3c24xx_serial_driver_ids[] = {
|
||||
}, {
|
||||
.name = "gs101-uart",
|
||||
.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 },
|
||||
{ .compatible = "google,gs101-uart",
|
||||
.data = GS101_SERIAL_DRV_DATA },
|
||||
{ .compatible = "samsung,exynos8895-uart",
|
||||
.data = EXYNOS8895_SERIAL_DRV_DATA },
|
||||
{},
|
||||
};
|
||||
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 = {
|
||||
.probe = s3c24xx_serial_probe,
|
||||
.remove_new = s3c24xx_serial_remove,
|
||||
.remove = s3c24xx_serial_remove,
|
||||
.id_table = s3c24xx_serial_driver_ids,
|
||||
.driver = {
|
||||
.name = "samsung-uart",
|
||||
|
@ -1473,7 +1473,7 @@ static int sc16is7xx_setup_mctrl_ports(struct sc16is7xx_port *s,
|
||||
}
|
||||
|
||||
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_after_send = 1, /* Not supported but keep returning -EINVAL */
|
||||
};
|
||||
|
@ -1052,7 +1052,7 @@ static struct platform_driver sccnxp_uart_driver = {
|
||||
.name = SCCNXP_NAME,
|
||||
},
|
||||
.probe = sccnxp_probe,
|
||||
.remove_new = sccnxp_remove,
|
||||
.remove = sccnxp_remove,
|
||||
.id_table = sccnxp_id_table,
|
||||
};
|
||||
module_platform_driver(sccnxp_uart_driver);
|
||||
|
@ -1648,7 +1648,7 @@ static const struct dev_pm_ops tegra_uart_pm_ops = {
|
||||
|
||||
static struct platform_driver tegra_uart_platform_driver = {
|
||||
.probe = tegra_uart_probe,
|
||||
.remove_new = tegra_uart_remove,
|
||||
.remove = tegra_uart_remove,
|
||||
.driver = {
|
||||
.name = "serial-tegra",
|
||||
.of_match_table = tegra_uart_of_match,
|
||||
|
@ -1097,7 +1097,7 @@ static int serial_txx9_resume(struct platform_device *dev)
|
||||
|
||||
static struct platform_driver serial_txx9_plat_driver = {
|
||||
.probe = serial_txx9_probe,
|
||||
.remove_new = serial_txx9_remove,
|
||||
.remove = serial_txx9_remove,
|
||||
#ifdef CONFIG_PM
|
||||
.suspend = serial_txx9_suspend,
|
||||
.resume = serial_txx9_resume,
|
||||
|
@ -3505,7 +3505,7 @@ static SIMPLE_DEV_PM_OPS(sci_dev_pm_ops, sci_suspend, sci_resume);
|
||||
|
||||
static struct platform_driver sci_driver = {
|
||||
.probe = sci_probe,
|
||||
.remove_new = sci_remove,
|
||||
.remove = sci_remove,
|
||||
.driver = {
|
||||
.name = "sh-sci",
|
||||
.pm = &sci_dev_pm_ops,
|
||||
|
@ -1040,7 +1040,7 @@ MODULE_DEVICE_TABLE(of, sifive_serial_of_match);
|
||||
|
||||
static struct platform_driver sifive_serial_platform_driver = {
|
||||
.probe = sifive_serial_probe,
|
||||
.remove_new = sifive_serial_remove,
|
||||
.remove = sifive_serial_remove,
|
||||
.driver = {
|
||||
.name = SIFIVE_SERIAL_NAME,
|
||||
.pm = pm_sleep_ptr(&sifive_uart_pm_ops),
|
||||
|
@ -53,10 +53,12 @@
|
||||
#define SPRD_IEN_TX_EMPTY BIT(1)
|
||||
#define SPRD_IEN_BREAK_DETECT BIT(7)
|
||||
#define SPRD_IEN_TIMEOUT BIT(13)
|
||||
#define SPRD_IEN_DATA_TIMEOUT BIT(17)
|
||||
|
||||
/* interrupt clear register */
|
||||
#define SPRD_ICLR 0x0014
|
||||
#define SPRD_ICLR_TIMEOUT BIT(13)
|
||||
#define SPRD_ICLR_DATA_TIMEOUT BIT(17)
|
||||
|
||||
/* line control register */
|
||||
#define SPRD_LCR 0x0018
|
||||
@ -102,6 +104,7 @@
|
||||
#define SPRD_IMSR_TX_FIFO_EMPTY BIT(1)
|
||||
#define SPRD_IMSR_BREAK_DETECT BIT(7)
|
||||
#define SPRD_IMSR_TIMEOUT BIT(13)
|
||||
#define SPRD_IMSR_DATA_TIMEOUT BIT(17)
|
||||
#define SPRD_DEFAULT_SOURCE_CLK 26000000
|
||||
|
||||
#define SPRD_RX_DMA_STEP 1
|
||||
@ -118,6 +121,12 @@ struct sprd_uart_dma {
|
||||
bool enable;
|
||||
};
|
||||
|
||||
struct sprd_uart_data {
|
||||
unsigned int timeout_ien;
|
||||
unsigned int timeout_iclr;
|
||||
unsigned int timeout_imsr;
|
||||
};
|
||||
|
||||
struct sprd_uart_port {
|
||||
struct uart_port port;
|
||||
char name[16];
|
||||
@ -126,6 +135,7 @@ struct sprd_uart_port {
|
||||
struct sprd_uart_dma rx_dma;
|
||||
dma_addr_t pos;
|
||||
unsigned char *rx_buf_tail;
|
||||
const struct sprd_uart_data *pdata;
|
||||
};
|
||||
|
||||
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_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,
|
||||
unsigned int offset)
|
||||
{
|
||||
@ -637,6 +659,8 @@ static irqreturn_t sprd_handle_irq(int irq, void *dev_id)
|
||||
{
|
||||
struct uart_port *port = dev_id;
|
||||
unsigned int ims;
|
||||
struct sprd_uart_port *sp =
|
||||
container_of(port, struct sprd_uart_port, port);
|
||||
|
||||
uart_port_lock(port);
|
||||
|
||||
@ -647,14 +671,14 @@ static irqreturn_t sprd_handle_irq(int irq, void *dev_id)
|
||||
return IRQ_NONE;
|
||||
}
|
||||
|
||||
if (ims & SPRD_IMSR_TIMEOUT)
|
||||
serial_out(port, SPRD_ICLR, SPRD_ICLR_TIMEOUT);
|
||||
if (ims & sp->pdata->timeout_imsr)
|
||||
serial_out(port, SPRD_ICLR, sp->pdata->timeout_iclr);
|
||||
|
||||
if (ims & SPRD_IMSR_BREAK_DETECT)
|
||||
serial_out(port, SPRD_ICLR, 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);
|
||||
|
||||
if (ims & SPRD_IMSR_TX_FIFO_EMPTY)
|
||||
@ -729,7 +753,7 @@ static int sprd_startup(struct uart_port *port)
|
||||
/* enable interrupt */
|
||||
uart_port_lock_irqsave(port, &flags);
|
||||
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)
|
||||
ien |= SPRD_IEN_RX_FULL;
|
||||
serial_out(port, SPRD_IEN, ien);
|
||||
@ -1184,6 +1208,12 @@ static int sprd_probe(struct platform_device *pdev)
|
||||
|
||||
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);
|
||||
if (irq < 0)
|
||||
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 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);
|
||||
|
||||
static struct platform_driver sprd_platform_driver = {
|
||||
.probe = sprd_probe,
|
||||
.remove_new = sprd_remove,
|
||||
.remove = sprd_remove,
|
||||
.driver = {
|
||||
.name = "sprd_serial",
|
||||
.of_match_table = serial_ids,
|
||||
|
@ -934,7 +934,7 @@ static DEFINE_SIMPLE_DEV_PM_OPS(asc_serial_pm_ops, asc_serial_suspend,
|
||||
|
||||
static struct platform_driver asc_serial_driver = {
|
||||
.probe = asc_serial_probe,
|
||||
.remove_new = asc_serial_remove,
|
||||
.remove = asc_serial_remove,
|
||||
.driver = {
|
||||
.name = DRIVER_NAME,
|
||||
.pm = pm_sleep_ptr(&asc_serial_pm_ops),
|
||||
|
@ -2188,7 +2188,7 @@ static const struct dev_pm_ops stm32_serial_pm_ops = {
|
||||
|
||||
static struct platform_driver stm32_serial_driver = {
|
||||
.probe = stm32_usart_serial_probe,
|
||||
.remove_new = stm32_usart_serial_remove,
|
||||
.remove = stm32_usart_serial_remove,
|
||||
.driver = {
|
||||
.name = DRIVER_NAME,
|
||||
.pm = &stm32_serial_pm_ops,
|
||||
|
@ -633,7 +633,7 @@ static struct platform_driver hv_driver = {
|
||||
.of_match_table = hv_match,
|
||||
},
|
||||
.probe = hv_probe,
|
||||
.remove_new = hv_remove,
|
||||
.remove = hv_remove,
|
||||
};
|
||||
|
||||
static int __init sunhv_init(void)
|
||||
|
@ -697,7 +697,7 @@ MODULE_DEVICE_TABLE(of, sp_uart_of_match);
|
||||
|
||||
static struct platform_driver sunplus_uart_platform_driver = {
|
||||
.probe = sunplus_uart_probe,
|
||||
.remove_new = sunplus_uart_remove,
|
||||
.remove = sunplus_uart_remove,
|
||||
.driver = {
|
||||
.name = "sunplus_uart",
|
||||
.of_match_table = sp_uart_of_match,
|
||||
|
@ -1100,7 +1100,7 @@ static struct platform_driver sab_driver = {
|
||||
.of_match_table = sab_match,
|
||||
},
|
||||
.probe = sab_probe,
|
||||
.remove_new = sab_remove,
|
||||
.remove = sab_remove,
|
||||
};
|
||||
|
||||
static int __init sunsab_init(void)
|
||||
|
@ -1549,7 +1549,7 @@ static struct platform_driver su_driver = {
|
||||
.of_match_table = su_match,
|
||||
},
|
||||
.probe = su_probe,
|
||||
.remove_new = su_remove,
|
||||
.remove = su_remove,
|
||||
};
|
||||
|
||||
static int __init sunsu_init(void)
|
||||
|
@ -1538,7 +1538,7 @@ static struct platform_driver zs_driver = {
|
||||
.of_match_table = zs_match,
|
||||
},
|
||||
.probe = zs_probe,
|
||||
.remove_new = zs_remove,
|
||||
.remove = zs_remove,
|
||||
};
|
||||
|
||||
static int __init sunzilog_init(void)
|
||||
|
@ -293,7 +293,7 @@ static struct platform_driver tegra_tcu_driver = {
|
||||
.of_match_table = tegra_tcu_match,
|
||||
},
|
||||
.probe = tegra_tcu_probe,
|
||||
.remove_new = tegra_tcu_remove,
|
||||
.remove = tegra_tcu_remove,
|
||||
};
|
||||
module_platform_driver(tegra_tcu_driver);
|
||||
|
||||
|
@ -485,7 +485,7 @@ static struct platform_driver timbuart_platform_driver = {
|
||||
.name = "timb-uart",
|
||||
},
|
||||
.probe = timbuart_probe,
|
||||
.remove_new = timbuart_remove,
|
||||
.remove = timbuart_remove,
|
||||
};
|
||||
|
||||
module_platform_driver(timbuart_platform_driver);
|
||||
|
@ -915,7 +915,7 @@ MODULE_ALIAS("platform:uartlite");
|
||||
|
||||
static struct platform_driver ulite_platform_driver = {
|
||||
.probe = ulite_probe,
|
||||
.remove_new = ulite_remove,
|
||||
.remove = ulite_remove,
|
||||
.driver = {
|
||||
.name = "uartlite",
|
||||
.of_match_table = of_match_ptr(ulite_of_match),
|
||||
|
@ -1484,7 +1484,7 @@ static struct platform_driver ucc_uart_of_driver = {
|
||||
.of_match_table = ucc_uart_match,
|
||||
},
|
||||
.probe = ucc_uart_probe,
|
||||
.remove_new = ucc_uart_remove,
|
||||
.remove = ucc_uart_remove,
|
||||
};
|
||||
|
||||
static int __init ucc_uart_init(void)
|
||||
|
@ -1903,7 +1903,7 @@ static void cdns_uart_remove(struct platform_device *pdev)
|
||||
|
||||
static struct platform_driver cdns_uart_platform_driver = {
|
||||
.probe = cdns_uart_probe,
|
||||
.remove_new = cdns_uart_remove,
|
||||
.remove = cdns_uart_remove,
|
||||
.driver = {
|
||||
.name = CDNS_UART_NAME,
|
||||
.of_match_table = cdns_uart_of_match,
|
||||
|
@ -3631,7 +3631,7 @@ static struct ctl_table tty_table[] = {
|
||||
.data = &tty_ldisc_autoload,
|
||||
.maxlen = sizeof(tty_ldisc_autoload),
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_dointvec,
|
||||
.proc_handler = proc_dointvec_minmax,
|
||||
.extra1 = SYSCTL_ZERO,
|
||||
.extra2 = SYSCTL_ONE,
|
||||
},
|
||||
|
@ -11,6 +11,8 @@
|
||||
Supported chipsets: 93c46, 93c56 and 93c66.
|
||||
*/
|
||||
|
||||
#include <linux/bits.h>
|
||||
|
||||
/*
|
||||
* EEPROM operation defines.
|
||||
*/
|
||||
@ -34,6 +36,7 @@
|
||||
* @register_write(struct eeprom_93cx6 *eeprom): handler to
|
||||
* write to the eeprom register by using all reg_* fields.
|
||||
* @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.
|
||||
* @reg_data_in: register field to indicate data input
|
||||
* @reg_data_out: register field to indicate data output
|
||||
@ -50,6 +53,9 @@ struct eeprom_93cx6 {
|
||||
void (*register_write)(struct eeprom_93cx6 *eeprom);
|
||||
|
||||
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 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,
|
||||
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;
|
||||
}
|
||||
|
@ -37,7 +37,6 @@
|
||||
*/
|
||||
|
||||
#include <linux/array_size.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/stddef.h>
|
||||
#include <linux/types.h>
|
||||
|
@ -10,7 +10,6 @@
|
||||
#define SA11X0_SERIAL_H
|
||||
|
||||
struct uart_port;
|
||||
struct uart_info;
|
||||
|
||||
/*
|
||||
* This is a temporary structure for registering these
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include <linux/kfifo.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/scatterlist.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
|
||||
/*
|
||||
* This module shows how to handle fifo dma operations.
|
||||
|
Loading…
Reference in New Issue
Block a user