Commit db593322 authored by Linus Torvalds's avatar Linus Torvalds

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

Pull tty/staging driver updates from Greg KH:
 "Here is the big tty/serial driver update for 4.16-rc1.

  The usual number of various serial driver fixes and updates to try to
  get them to work with crazy hardware configurations (seriously, how
  many different ways are hardware engineers going to come up with to
  hook up a simple UART?)

  There is also some serdev bugfixes and updates, as well as a
  smattering of other small fixes in here.

  All have been in the linux-next tree for a while, with no reported
  issues"

* tag 'tty-4.16-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty: (65 commits)
  tty: serial: exar: Relocate sleep wake-up handling
  tty: fix data race between tty_init_dev and flush of buf
  serial: imx: fix endless loop during suspend
  serial: core: mark port as initialized after successful IRQ change
  serdev: only match serdev devices
  serdev: do not generate modaliases for controllers
  serial: mxs-auart: don't use GPIOF_* with gpiod_get_direction
  serial: 8250_dw: Revert "Improve clock rate setting"
  MAINTAINERS: Add myself as designated reviewer for 8250_dw
  gpio: serial: max310x: Support open-drain configuration for GPIOs
  serdev: Fix serdev_uevent failure on ACPI enumerated serdev-controllers
  serial: 8250_ingenic: Parse earlycon options
  serial: 8250_ingenic: Add support for the JZ4770 SoC
  serial: core: Make uart_parse_options take const char* argument
  serial: 8250_of: fix return code when probe function fails to get reset
  serial: imx: Only wakeup via RTSDEN bit if the system has RTS/CTS
  serial: 8250_uniphier: fix error return code in uniphier_uart_probe()
  tty: n_gsm: Allow ADM response in addition to UA for control dlci
  tty: omap-serial: Fix initial on-boot RTS GPIO level
  tty: serial: jsm: Add one check against NULL pointer dereference
  ...
parents e4ee8b85 c7e1b405
......@@ -6,10 +6,10 @@ Required properties:
- interrupts : Should contain uart interrupt
Optional properties:
- fsl,irda-mode : Indicate the uart supports irda mode
- fsl,dte-mode : Indicate the uart works in DTE mode. The uart works
in DCE mode by default.
- rs485-rts-delay, rs485-rx-during-tx, linux,rs485-enabled-at-boot-time: see rs485.txt
- rs485-rts-delay, rs485-rts-active-low, rs485-rx-during-tx,
linux,rs485-enabled-at-boot-time: see rs485.txt
Please check Documentation/devicetree/bindings/serial/serial.txt
for the complete list of generic properties.
......
......@@ -16,7 +16,8 @@ Required properties:
Optional properties:
- dmas: A list of two dma specifiers, one for each entry in dma-names.
- dma-names: should contain "tx" and "rx".
- rs485-rts-delay, rs485-rx-during-tx, linux,rs485-enabled-at-boot-time: see rs485.txt
- rs485-rts-delay, rs485-rts-active-low, rs485-rx-during-tx,
linux,rs485-enabled-at-boot-time: see rs485.txt
Note: Optional properties for DMA support. Write them both or both not.
......
* Ingenic SoC UART
Required properties:
- compatible : "ingenic,jz4740-uart", "ingenic,jz4760-uart",
"ingenic,jz4775-uart" or "ingenic,jz4780-uart"
- compatible : One of:
- "ingenic,jz4740-uart",
- "ingenic,jz4760-uart",
- "ingenic,jz4770-uart",
- "ingenic,jz4775-uart",
- "ingenic,jz4780-uart".
- reg : offset and length of the register set for the device.
- interrupts : should contain uart interrupt.
- clocks : phandles to the module & baud clocks.
......
......@@ -24,13 +24,27 @@ Optional properties:
1 = active low.
Example:
/ {
clocks {
spi_uart_clk: osc_max14830 {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <3686400>;
};
};
};
&spi0 {
max14830: max14830@0 {
compatible = "maxim,max14830";
reg = <0>;
clocks = <&clk20m>;
clocks = <&spi_uart_clk>;
clock-names = "osc";
interrupt-parent = <&gpio3>;
interrupts = <7 IRQ_TYPE_EDGE_FALLING>;
interrupts = <7 IRQ_TYPE_LEVEL_LOW>;
gpio-controller;
#gpio-cells = <2>;
};
};
* Marvell UART : Non standard UART used in some of Marvell EBU SoCs (e.g., Armada-3700)
* Marvell UART : Non standard UART used in some of Marvell EBU SoCs
e.g., Armada-3700.
Required properties:
- compatible: "marvell,armada-3700-uart"
- compatible:
- "marvell,armada-3700-uart" for the standard variant of the UART
(32 bytes FIFO, no DMA, level interrupts, 8-bit access to the
FIFO, baudrate limited to 230400).
- "marvell,armada-3700-uart-ext" for the extended variant of the
UART (128 bytes FIFO, DMA, front interrupts, 8-bit or 32-bit
accesses to the FIFO, baudrate unlimited by the dividers).
- reg: offset and length of the register set for the device.
- interrupts: device interrupt
- clocks: UART reference clock used to derive the baudrate. If no clock
is provided (possible only with the "marvell,armada-3700-uart"
compatible string for backward compatibility), it will only work
if the baudrate was initialized by the bootloader and no baudrate
change will then be possible.
- interrupts:
- Must contain three elements for the standard variant of the IP
(marvell,armada-3700-uart): "uart-sum", "uart-tx" and "uart-rx",
respectively the UART sum interrupt, the UART TX interrupt and
UART RX interrupt. A corresponding interrupt-names property must
be defined.
- Must contain two elements for the extended variant of the IP
(marvell,armada-3700-uart-ext): "uart-tx" and "uart-rx",
respectively the UART TX interrupt and the UART RX interrupt. A
corresponding interrupts-names property must be defined.
- For backward compatibility reasons, a single element interrupts
property is also supported for the standard variant of the IP,
containing only the UART sum interrupt. This form is deprecated
and should no longer be used.
Example:
serial@12000 {
uart0: serial@12000 {
compatible = "marvell,armada-3700-uart";
reg = <0x12000 0x200>;
interrupts = <43>;
clocks = <&xtalclk>;
interrupts =
<GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "uart-sum", "uart-tx", "uart-rx";
};
uart1: serial@12200 {
compatible = "marvell,armada-3700-uart-ext";
reg = <0x12200 0x30>;
clocks = <&xtalclk>;
interrupts =
<GIC_SPI 30 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 31 IRQ_TYPE_EDGE_RISING>;
interrupt-names = "uart-tx", "uart-rx";
};
......@@ -20,6 +20,7 @@ Optional properties:
node and a DMA channel number.
- dma-names : "rx" for receive channel, "tx" for transmit channel.
- rs485-rts-delay, rs485-rx-during-tx, linux,rs485-enabled-at-boot-time: see rs485.txt
- rs485-rts-active-high: drive RTS high when sending (default is low).
Example:
......
......@@ -12,6 +12,7 @@ Optional properties:
* b is the 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.
If this property is not specified, <0 0> is assumed.
- rs485-rts-active-low: drive RTS low when sending (default is high).
- linux,rs485-enabled-at-boot-time: empty property telling to enable the rs485
feature at boot time. It can be disabled later with proper ioctl.
- rs485-rx-during-tx: empty property that enables the receiving of data even
......
......@@ -13181,6 +13181,11 @@ S: Supported
F: drivers/reset/reset-axs10x.c
F: Documentation/devicetree/bindings/reset/snps,axs10x-reset.txt
SYNOPSYS DESIGNWARE 8250 UART DRIVER
R: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
S: Maintained
F: drivers/tty/serial/8250/8250_dw.c
SYNOPSYS DESIGNWARE APB GPIO DRIVER
M: Hoan Tran <hotran@apm.com>
L: linux-gpio@vger.kernel.org
......
......@@ -394,10 +394,14 @@ config GOLDFISH_TTY
depends on GOLDFISH
select SERIAL_CORE
select SERIAL_CORE_CONSOLE
select SERIAL_EARLYCON
help
Console and system TTY driver for the Goldfish virtual platform.
config GOLDFISH_TTY_EARLY_CONSOLE
bool
default y if GOLDFISH_TTY=y
select SERIAL_EARLYCON
config DA_TTY
bool "DA TTY"
depends on METAG_DA
......
......@@ -433,6 +433,7 @@ static int goldfish_tty_remove(struct platform_device *pdev)
return 0;
}
#ifdef CONFIG_GOLDFISH_TTY_EARLY_CONSOLE
static void gf_early_console_putchar(struct uart_port *port, int ch)
{
__raw_writel(ch, port->membase);
......@@ -456,6 +457,7 @@ static int __init gf_earlycon_setup(struct earlycon_device *device,
}
OF_EARLYCON_DECLARE(early_gf_tty, "google,goldfish-tty", gf_earlycon_setup);
#endif
static const struct of_device_id goldfish_tty_of_match[] = {
{ .compatible = "google,goldfish-tty", },
......
......@@ -219,13 +219,9 @@ static struct isi_port isi_ports[PORT_COUNT];
static int WaitTillCardIsFree(unsigned long base)
{
unsigned int count = 0;
unsigned int a = in_atomic(); /* do we run under spinlock? */
while (!(inw(base + 0xe) & 0x1) && count++ < 100)
if (a)
mdelay(1);
else
msleep(1);
mdelay(1);
return !(inw(base + 0xe) & 0x1);
}
......
......@@ -1487,8 +1487,6 @@ static void moxa_set_tty_param(struct tty_struct *tty, struct ktermios *old_term
if (ts->c_iflag & IXANY)
xany = 1;
/* Clear the features we don't support */
ts->c_cflag &= ~CMSPAR;
MoxaPortFlowCtrl(ch, rts, cts, txflow, rxflow, xany);
baud = MoxaPortSetTermio(ch, ts, tty_get_baud_rate(tty));
if (baud == -1)
......@@ -1781,10 +1779,17 @@ static int MoxaPortSetTermio(struct moxa_port *port, struct ktermios *termio,
mode |= MX_STOP1;
if (termio->c_cflag & PARENB) {
if (termio->c_cflag & PARODD)
mode |= MX_PARODD;
else
mode |= MX_PAREVEN;
if (termio->c_cflag & PARODD) {
if (termio->c_cflag & CMSPAR)
mode |= MX_PARMARK;
else
mode |= MX_PARODD;
} else {
if (termio->c_cflag & CMSPAR)
mode |= MX_PARSPACE;
else
mode |= MX_PAREVEN;
}
} else
mode |= MX_PARNONE;
......
......@@ -301,5 +301,7 @@
#define MX_PARNONE 0x00
#define MX_PAREVEN 0x40
#define MX_PARODD 0xC0
#define MX_PARMARK 0xA0
#define MX_PARSPACE 0x20
#endif
......@@ -1451,6 +1451,10 @@ static void gsm_dlci_open(struct gsm_dlci *dlci)
* in which case an opening port goes back to closed and a closing port
* is simply put into closed state (any further frames from the other
* end will get a DM response)
*
* Some control dlci can stay in ADM mode with other dlci working just
* fine. In that case we can just keep the control dlci open after the
* DLCI_OPENING retries time out.
*/
static void gsm_dlci_t1(struct timer_list *t)
......@@ -1464,8 +1468,15 @@ static void gsm_dlci_t1(struct timer_list *t)
if (dlci->retries) {
gsm_command(dlci->gsm, dlci->addr, SABM|PF);
mod_timer(&dlci->t1, jiffies + gsm->t1 * HZ / 100);
} else
} else if (!dlci->addr && gsm->control == (DM | PF)) {
if (debug & 8)
pr_info("DLCI %d opening in ADM mode.\n",
dlci->addr);
gsm_dlci_open(dlci);
} else {
gsm_dlci_close(dlci);
}
break;
case DLCI_CLOSING:
dlci->retries--;
......@@ -1483,8 +1494,8 @@ static void gsm_dlci_t1(struct timer_list *t)
* @dlci: DLCI to open
*
* Commence opening a DLCI from the Linux side. We issue SABM messages
* to the modem which should then reply with a UA, at which point we
* will move into open state. Opening is done asynchronously with retry
* to the modem which should then reply with a UA or ADM, at which point
* we will move into open state. Opening is done asynchronously with retry
* running off timers and the responses.
*/
......@@ -2955,7 +2966,6 @@ static int gsmtty_open(struct tty_struct *tty, struct file *filp)
static void gsmtty_close(struct tty_struct *tty, struct file *filp)
{
struct gsm_dlci *dlci = tty->driver_data;
struct gsm_mux *gsm;
if (dlci == NULL)
return;
......@@ -2964,7 +2974,6 @@ static void gsmtty_close(struct tty_struct *tty, struct file *filp)
mutex_lock(&dlci->mutex);
gsm_destroy_network(dlci);
mutex_unlock(&dlci->mutex);
gsm = dlci->gsm;
if (tty_port_close_start(&dlci->port, tty, filp) == 0)
return;
gsm_dlci_begin_close(dlci);
......
......@@ -19,6 +19,38 @@
static bool is_registered;
static DEFINE_IDA(ctrl_ida);
static ssize_t modalias_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
int len;
len = acpi_device_modalias(dev, buf, PAGE_SIZE - 1);
if (len != -ENODEV)
return len;
return of_device_modalias(dev, buf, PAGE_SIZE);
}
static DEVICE_ATTR_RO(modalias);
static struct attribute *serdev_device_attrs[] = {
&dev_attr_modalias.attr,
NULL,
};
ATTRIBUTE_GROUPS(serdev_device);
static int serdev_device_uevent(struct device *dev, struct kobj_uevent_env *env)
{
int rc;
/* TODO: platform modalias */
rc = acpi_device_uevent_modalias(dev, env);
if (rc != -ENODEV)
return rc;
return of_device_uevent_modalias(dev, env);
}
static void serdev_device_release(struct device *dev)
{
struct serdev_device *serdev = to_serdev_device(dev);
......@@ -26,9 +58,16 @@ static void serdev_device_release(struct device *dev)
}
static const struct device_type serdev_device_type = {
.groups = serdev_device_groups,
.uevent = serdev_device_uevent,
.release = serdev_device_release,
};
static bool is_serdev_device(const struct device *dev)
{
return dev->type == &serdev_device_type;
}
static void serdev_ctrl_release(struct device *dev)
{
struct serdev_controller *ctrl = to_serdev_controller(dev);
......@@ -42,6 +81,9 @@ static const struct device_type serdev_ctrl_type = {
static int serdev_device_match(struct device *dev, struct device_driver *drv)
{
if (!is_serdev_device(dev))
return 0;
/* TODO: platform matching */
if (acpi_driver_match_device(dev, drv))
return 1;
......@@ -49,18 +91,6 @@ static int serdev_device_match(struct device *dev, struct device_driver *drv)
return of_driver_match_device(dev, drv);
}
static int serdev_uevent(struct device *dev, struct kobj_uevent_env *env)
{
int rc;
/* TODO: platform modalias */
rc = acpi_device_uevent_modalias(dev, env);
if (rc != -ENODEV)
return rc;
return of_device_uevent_modalias(dev, env);
}
/**
* serdev_device_add() - add a device previously constructed via serdev_device_alloc()
* @serdev: serdev_device to be added
......@@ -312,32 +342,11 @@ static int serdev_drv_remove(struct device *dev)
return 0;
}
static ssize_t modalias_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
int len;
len = acpi_device_modalias(dev, buf, PAGE_SIZE - 1);
if (len != -ENODEV)
return len;
return of_device_modalias(dev, buf, PAGE_SIZE);
}
DEVICE_ATTR_RO(modalias);
static struct attribute *serdev_device_attrs[] = {
&dev_attr_modalias.attr,
NULL,
};
ATTRIBUTE_GROUPS(serdev_device);
static struct bus_type serdev_bus_type = {
.name = "serial",
.match = serdev_device_match,
.probe = serdev_drv_probe,
.remove = serdev_drv_remove,
.uevent = serdev_uevent,
.dev_groups = serdev_device_groups,
};
/**
......
......@@ -59,7 +59,8 @@ static void ttyport_write_wakeup(struct tty_port *port)
test_bit(SERPORT_ACTIVE, &serport->flags))
serdev_controller_write_wakeup(ctrl);
wake_up_interruptible_poll(&tty->write_wait, POLLOUT);
/* Wake up any tty_wait_until_sent() */
wake_up_interruptible(&tty->write_wait);
tty_kref_put(tty);
}
......@@ -122,6 +123,8 @@ static int ttyport_open(struct serdev_controller *ctrl)
if (ret)
goto err_close;
tty_unlock(serport->tty);
/* Bring the UART into a known 8 bits no parity hw fc state */
ktermios = tty->termios;
ktermios.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP |
......@@ -131,11 +134,12 @@ static int ttyport_open(struct serdev_controller *ctrl)
ktermios.c_cflag &= ~(CSIZE | PARENB);
ktermios.c_cflag |= CS8;
ktermios.c_cflag |= CRTSCTS;
/* Hangups are not supported so make sure to ignore carrier detect. */
ktermios.c_cflag |= CLOCAL;
tty_set_termios(tty, &ktermios);
set_bit(SERPORT_ACTIVE, &serport->flags);
tty_unlock(serport->tty);
return 0;
err_close:
......
......@@ -252,31 +252,25 @@ static void dw8250_set_termios(struct uart_port *p, struct ktermios *termios,
struct ktermios *old)
{
unsigned int baud = tty_termios_baud_rate(termios);
unsigned int target_rate, min_rate, max_rate;
struct dw8250_data *d = p->private_data;
long rate;
int i, ret;
int ret;
if (IS_ERR(d->clk) || !old)
goto out;
/* Find a clk rate within +/-1.6% of an integer multiple of baudx16 */
target_rate = baud * 16;
min_rate = target_rate - (target_rate >> 6);
max_rate = target_rate + (target_rate >> 6);
for (i = 1; i <= UART_DIV_MAX; i++) {
rate = clk_round_rate(d->clk, i * target_rate);
if (rate >= i * min_rate && rate <= i * max_rate)
break;
}
if (i <= UART_DIV_MAX) {
clk_disable_unprepare(d->clk);
clk_disable_unprepare(d->clk);
rate = clk_round_rate(d->clk, baud * 16);
if (rate < 0)
ret = rate;
else if (rate == 0)
ret = -ENOENT;
else
ret = clk_set_rate(d->clk, rate);
clk_prepare_enable(d->clk);
if (!ret)
p->uartclk = rate;
}
clk_prepare_enable(d->clk);
if (!ret)
p->uartclk = rate;
out:
p->status &= ~UPSTAT_AUTOCTS;
......@@ -515,7 +509,8 @@ static int dw8250_probe(struct platform_device *pdev)
/* If no clock rate is defined, fail. */
if (!p->uartclk) {
dev_err(dev, "clock rate not defined\n");
return -EINVAL;
err = -EINVAL;
goto err_clk;
}
data->pclk = devm_clk_get(dev, "apb_pclk");
......
......@@ -34,6 +34,7 @@
#define PCI_DEVICE_ID_EXAR_XR17V4358 0x4358
#define PCI_DEVICE_ID_EXAR_XR17V8358 0x8358
#define UART_EXAR_INT0 0x80
#define UART_EXAR_8XMODE 0x88 /* 8X sampling rate select */
#define UART_EXAR_FCTR 0x08 /* Feature Control Register */
......@@ -121,6 +122,7 @@ struct exar8250_board {
struct exar8250 {
unsigned int nr;
struct exar8250_board *board;
void __iomem *virt;
int line[0];
};
......@@ -131,12 +133,9 @@ static int default_setup(struct exar8250 *priv, struct pci_dev *pcidev,
const struct exar8250_board *board = priv->board;
unsigned int bar = 0;
if (!pcim_iomap_table(pcidev)[bar] && !pcim_iomap(pcidev, bar, 0))
return -ENOMEM;
port->port.iotype = UPIO_MEM;
port->port.mapbase = pci_resource_start(pcidev, bar) + offset;
port->port.membase = pcim_iomap_table(pcidev)[bar] + offset;
port->port.membase = priv->virt + offset;
port->port.regshift = board->reg_shift;
return 0;
......@@ -420,6 +419,25 @@ static void pci_xr17v35x_exit(struct pci_dev *pcidev)
port->port.private_data = NULL;
}
/*
* These Exar UARTs have an extra interrupt indicator that could fire for a
* few interrupts that are not presented/cleared through IIR. One of which is
* a wakeup interrupt when coming out of sleep. These interrupts are only
* cleared by reading global INT0 or INT1 registers as interrupts are
* associated with channel 0. The INT[3:0] registers _are_ accessible from each
* channel's address space, but for the sake of bus efficiency we register a
* dedicated handler at the PCI device level to handle them.
*/
static irqreturn_t exar_misc_handler(int irq, void *data)
{
struct exar8250 *priv = data;
/* Clear all PCI interrupts by reading INT0. No effect on IIR */
ioread8(priv->virt + UART_EXAR_INT0);
return IRQ_HANDLED;
}
static int
exar_pci_probe(struct pci_dev *pcidev, const struct pci_device_id *ent)
{
......@@ -448,6 +466,9 @@ exar_pci_probe(struct pci_dev *pcidev, const struct pci_device_id *ent)
return -ENOMEM;
priv->board = board;
priv->virt = pcim_iomap(pcidev, bar, 0);
if (!priv->virt)
return -ENOMEM;
pci_set_master(pcidev);
......@@ -461,6 +482,11 @@ exar_pci_probe(struct pci_dev *pcidev, const struct pci_device_id *ent)
uart.port.irq = pci_irq_vector(pcidev, 0);
uart.port.dev = &pcidev->dev;
rc = devm_request_irq(&pcidev->dev, uart.port.irq, exar_misc_handler,
IRQF_SHARED, "exar_uart", priv);
if (rc)
return rc;
for (i = 0; i < nr_ports && i < maxnr; i++) {
rc = board->setup(priv, pcidev, &uart, i);
if (rc) {
......
......@@ -91,14 +91,22 @@ static int __init ingenic_early_console_setup(struct earlycon_device *dev,
const char *opt)
{
struct uart_port *port = &dev->port;
unsigned int baud, divisor;
unsigned int divisor;
int baud = 115200;
if (!dev->port.membase)
return -ENODEV;
if (opt) {
unsigned int parity, bits, flow; /* unused for now */
uart_parse_options(opt, &baud, &parity, &bits, &flow);
}
ingenic_early_console_setup_clock(dev);
baud = dev->baud ?: 115200;
if (dev->baud)
baud = dev->baud;
divisor = DIV_ROUND_CLOSEST(port->uartclk, 16 * baud);
early_out(port, UART_IER, 0);
......@@ -125,6 +133,10 @@ EARLYCON_DECLARE(jz4740_uart, ingenic_early_console_setup);
OF_EARLYCON_DECLARE(jz4740_uart, "ingenic,jz4740-uart",
ingenic_early_console_setup);
EARLYCON_DECLARE(jz4770_uart, ingenic_early_console_setup);
OF_EARLYCON_DECLARE(jz4770_uart, "ingenic,jz4770-uart",
ingenic_early_console_setup);
EARLYCON_DECLARE(jz4775_uart, ingenic_early_console_setup);
OF_EARLYCON_DECLARE(jz4775_uart, "ingenic,jz4775-uart",
ingenic_early_console_setup);
......@@ -319,6 +331,7 @@ static const struct ingenic_uart_config jz4780_uart_config = {
static const struct of_device_id of_match[] = {
{ .compatible = "ingenic,jz4740-uart", .data = &jz4740_uart_config },
{ .compatible = "ingenic,jz4760-uart", .data = &jz4760_uart_config },
{ .compatible = "ingenic,jz4770-uart", .data = &jz4760_uart_config },
{ .compatible = "ingenic,jz4775-uart", .data = &jz4760_uart_config },
{ .compatible = "ingenic,jz4780-uart", .data = &jz4780_uart_config },
{ /* sentinel */ }
......
......@@ -136,8 +136,11 @@ static int of_platform_serial_setup(struct platform_device *ofdev,
}
info->rst = devm_reset_control_get_optional_shared(&ofdev->dev, NULL);
if (IS_ERR(info->rst))
if (IS_ERR(info->rst)) {
ret = PTR_ERR(info->rst);
goto err_dispose;
}
ret = reset_control_deassert(info->rst);
if (ret)
goto err_dispose;
......
......@@ -414,7 +414,7 @@ static void omap_8250_set_termios(struct uart_port *port,
/* Up to here it was mostly serial8250_do_set_termios() */
/*
* We enable TRIG_GRANU for RX and TX and additionaly we set
* We enable TRIG_GRANU for RX and TX and additionally we set
* SCR_TX_EMPTY bit. The result is the following:
* - RX_TRIGGER amount of bytes in the FIFO will cause an interrupt.
* - less than RX_TRIGGER number of bytes will also cause an interrupt
......
......@@ -441,7 +441,6 @@ static void io_serial_out(struct uart_port *p, int offset, int value)
}
static int serial8250_default_handle_irq(struct uart_port *port);
static int exar_handle_irq(struct uart_port *port);
static void set_io_from_upio(struct uart_port *p)
{
......@@ -1883,26 +1882,6 @@ static int serial8250_default_handle_irq(struct uart_port *port)
return ret;
}
/*
* These Exar UARTs have an extra interrupt indicator that could
* fire for a few unimplemented interrupts. One of which is a
* wakeup event when coming out of sleep. Put this here just
* to be on the safe side that these interrupts don't go unhandled.
*/
static int exar_handle_irq(struct uart_port *port)
{
unsigned int iir = serial_port_in(port, UART_IIR);
int ret = 0;
if (((port->type == PORT_XR17V35X) || (port->type == PORT_XR17D15X)) &&
serial_port_in(port, UART_EXAR_INT0) != 0)
ret = 1;
ret |= serial8250_handle_irq(port, iir);
return ret;
}
/*
* Newer 16550 compatible parts such as the SC16C650 & Altera 16550 Soft IP
* have a programmable TX threshold that triggers the THRE interrupt in
......@@ -3067,11 +3046,6 @@ static void serial8250_config_port(struct uart_port *port, int flags)
if (port->type == PORT_UNKNOWN)
serial8250_release_std_resource(up);
/* Fixme: probably not the best place for this */
if ((port->type == PORT_XR17V35X) ||
(port->type == PORT_XR17D15X))
port->handle_irq = exar_handle_irq;
register_dev_spec_attr_grp(up);
up->fcr = uart_config[up->port.type].fcr;
}
......
......@@ -250,12 +250,13 @@ static int uniphier_uart_probe(struct platform_device *pdev)
up.dl_read = uniphier_serial_dl_read;
up.dl_write = uniphier_serial_dl_write;
priv->line = serial8250_register_8250_port(&up);
if (priv->line < 0) {
ret = serial8250_register_8250_port(&up);
if (ret < 0) {
dev_err(dev, "failed to register 8250 port\n");
clk_disable_unprepare(priv->clk);
return ret;
}
priv->line = ret;
platform_set_drvdata(pdev, priv);
......
......@@ -5,6 +5,7 @@
config SERIAL_8250
tristate "8250/16550 and compatible serial support"
depends on !S390
select SERIAL_CORE
---help---
This selects whether you want to include the driver for the standard
......
......@@ -761,24 +761,30 @@ config SERIAL_SH_SCI
select SERIAL_MCTRL_GPIO if GPIOLIB
config SERIAL_SH_SCI_NR_UARTS
int "Maximum number of SCI(F) serial ports"
int "Maximum number of SCI(F) serial ports" if EXPERT
depends on SERIAL_SH_SCI
default "3" if H8300
default "10" if SUPERH
default "18" if ARCH_RENESAS
default "2"
config SERIAL_SH_SCI_CONSOLE
bool "Support for console on SuperH SCI(F)"
bool "Support for console on SuperH SCI(F)" if EXPERT
depends on SERIAL_SH_SCI=y
select SERIAL_CORE_CONSOLE
default y
config SERIAL_SH_SCI_EARLYCON
bool "Support for early console on SuperH SCI(F)"
bool "Support for early console on SuperH SCI(F)" if EXPERT
depends on SERIAL_SH_SCI=y
select SERIAL_CORE_CONSOLE
select SERIAL_EARLYCON
default ARCH_RENESAS || H8300
config SERIAL_SH_SCI_DMA
bool "DMA support"
bool "DMA support" if EXPERT
depends on SERIAL_SH_SCI && DMA_ENGINE
default ARCH_RENESAS
config SERIAL_PNX8XXX
bool "Enable PNX8XXX SoCs' UART Support"
......
......@@ -314,10 +314,9 @@ static void pl011_write(unsigned int val, const struct uart_amba_port *uap,
static int pl011_fifo_to_tty(struct uart_amba_port *uap)
{
u16 status;
unsigned int ch, flag, max_count = 256;
int fifotaken = 0;
unsigned int ch, flag, fifotaken;
while (max_count--) {
for (fifotaken = 0; fifotaken != 256; fifotaken++) {
status = pl011_read(uap, REG_FR);
if (status & UART01x_FR_RXFE)
break;
......@@ -326,7 +325,6 @@ static int pl011_fifo_to_tty(struct uart_amba_port *uap)
ch = pl011_read(uap, REG_DR) | UART_DUMMY_DR_RX;
flag = TTY_NORMAL;
uap->port.icount.rx++;
fifotaken++;
if (unlikely(ch & UART_DR_ERROR)) {
if (ch & UART011_DR_BE) {
......@@ -1482,12 +1480,10 @@ static irqreturn_t pl011_int(int irq, void *dev_id)
struct uart_amba_port *uap = dev_id;
unsigned long flags;
unsigned int status, pass_counter = AMBA_ISR_PASS_LIMIT;
u16 imsc;
int handled = 0;
spin_lock_irqsave(&uap->port.lock, flags);
imsc = pl011_read(uap, REG_IMSC);
status = pl011_read(uap, REG_RIS) & imsc;
status = pl011_read(uap, REG_RIS) & uap->im;
if (status) {
do {
check_apply_cts_event_workaround(uap);
......@@ -1511,7 +1507,7 @@ static irqreturn_t pl011_int(int irq, void *dev_id)
if (pass_counter-- == 0)
break;
status = pl011_read(uap, REG_RIS) & imsc;
status = pl011_read(uap, REG_RIS) & uap->im;
} while (status != 0);
handled = 1;
}
......
......@@ -2345,7 +2345,7 @@ static int atmel_init_port(struct atmel_uart_port *atmel_port,
atmel_init_property(atmel_port, pdev);
atmel_set_ops(port);
of_get_rs485_mode(pdev->dev.of_node, &port->rs485);
uart_get_rs485_mode(&pdev->dev, &port->rs485);
port->iotype = UPIO_MEM;
port->flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP;
......
......@@ -2206,23 +2206,16 @@ static int lpuart_probe(struct platform_device *pdev)
if (ret)
goto failed_attach_port;
of_get_rs485_mode(np, &sport->port.rs485);
uart_get_rs485_mode(&pdev->dev, &sport->port.rs485);
if (sport->port.rs485.flags & SER_RS485_RX_DURING_TX) {
if (sport->port.rs485.flags & SER_RS485_RX_DURING_TX)
dev_err(&pdev->dev, "driver doesn't support RX during TX\n");
return -ENOSYS;
}
if (sport->port.rs485.delay_rts_before_send ||
sport->port.rs485.delay_rts_after_send) {
sport->port.rs485.delay_rts_after_send)
dev_err(&pdev->dev, "driver doesn't support RTS delays\n");
return -ENOSYS;
}
if (sport->port.rs485.flags & SER_RS485_ENABLED) {
sport->port.rs485.flags |= SER_RS485_RTS_ON_SEND;
writeb(UARTMODEM_TXRTSE, sport->port.membase + UARTMODEM);
}
lpuart_config_rs485(&sport->port, &sport->port.rs485);
sport->dma_tx_chan = dma_request_slave_channel(sport->port.dev, "tx");
if (!sport->dma_tx_chan)
......
......@@ -703,25 +703,6 @@ static irqreturn_t imx_rxint(int irq, void *dev_id)
return IRQ_HANDLED;
}
static void imx_disable_rx_int(struct imx_port *sport)
{
unsigned long temp;
/* disable the receiver ready and aging timer interrupts */
temp = readl(sport->port.membase + UCR1);
temp &= ~(UCR1_RRDYEN);
writel(temp, sport->port.membase + UCR1);
temp = readl(sport->port.membase + UCR2);
temp &= ~(UCR2_ATEN);
writel(temp, sport->port.membase + UCR2);
/* disable the rx errors interrupts */
temp = readl(sport->port.membase + UCR4);
temp &= ~UCR4_OREN;
writel(temp, sport->port.membase + UCR4);
}
static void clear_rx_errors(struct imx_port *sport);
/*
......@@ -1252,18 +1233,21 @@ static int imx_startup(struct uart_port *port)
if (sport->dma_is_inited && !sport->dma_is_enabled)
imx_enable_dma(sport);
temp = readl(sport->port.membase + UCR1);
temp |= UCR1_RRDYEN | UCR1_UARTEN;
temp = readl(sport->port.membase + UCR1) & ~UCR1_RRDYEN;
if (!sport->dma_is_enabled)
temp |= UCR1_RRDYEN;
temp |= UCR1_UARTEN;
if (sport->have_rtscts)
temp |= UCR1_RTSDEN;
writel(temp, sport->port.membase + UCR1);
temp = readl(sport->port.membase + UCR4);
temp |= UCR4_OREN;
temp = readl(sport->port.membase + UCR4) & ~UCR4_OREN;
if (!sport->dma_is_enabled)
temp |= UCR4_OREN;
writel(temp, sport->port.membase + UCR4);
temp = readl(sport->port.membase + UCR2);
temp = readl(sport->port.membase + UCR2) & ~UCR2_ATEN;
temp |= (UCR2_RXEN | UCR2_TXEN);
if (!sport->have_rtscts)
temp |= UCR2_IRTS;
......@@ -1297,10 +1281,8 @@ static int imx_startup(struct uart_port *port)
* In our iMX53 the average delay for the first reception dropped from
* approximately 35000 microseconds to 1000 microseconds.
*/
if (sport->dma_is_enabled) {
imx_disable_rx_int(sport);
if (sport->dma_is_enabled)
start_rx_dma(sport);
}
spin_unlock_irqrestore(&sport->port.lock, flags);
......@@ -2017,8 +1999,6 @@ static int serial_imx_probe_dt(struct imx_port *sport,
if (of_get_property(np, "rts-gpios", NULL))
sport->have_rtsgpio = 1;
of_get_rs485_mode(np, &sport->port.rs485);
return 0;
}
#else
......@@ -2080,7 +2060,6 @@ static int serial_imx_probe(struct platform_device *pdev)
sport->port.fifosize = 32;
sport->port.ops = &imx_pops;
sport->port.rs485_config = imx_rs485_config;
sport->port.rs485.flags |= SER_RS485_RTS_ON_SEND;
sport->port.flags = UPF_BOOT_AUTOCONF;
timer_setup(&sport->timer, imx_timeout, 0);
......@@ -2111,6 +2090,14 @@ static int serial_imx_probe(struct platform_device *pdev)
return ret;
}
uart_get_rs485_mode(&pdev->dev, &sport->port.rs485);
if (sport->port.rs485.flags & SER_RS485_ENABLED &&
(!sport->have_rtscts || !sport->have_rtsgpio))
dev_err(&pdev->dev, "no RTS control, disabling rs485\n");
imx_rs485_config(&sport->port, &sport->port.rs485);
/* Disable interrupts before requesting them */
reg = readl_relaxed(sport->port.membase + UCR1);
reg &= ~(UCR1_ADEN | UCR1_TRDYEN | UCR1_IDEN | UCR1_RRDYEN |
......@@ -2232,29 +2219,28 @@ static void serial_imx_enable_wakeup(struct imx_port *sport, bool on)
unsigned int val;
val = readl(sport->port.membase + UCR3);
if (on)
if (on) {
writel(USR1_AWAKE, sport->port.membase + USR1);
val |= UCR3_AWAKEN;
}
else
val &= ~UCR3_AWAKEN;
writel(val, sport->port.membase + UCR3);
val = readl(sport->port.membase + UCR1);
if (on)
val |= UCR1_RTSDEN;
else
val &= ~UCR1_RTSDEN;
writel(val, sport->port.membase + UCR1);
if (sport->have_rtscts) {
val = readl(sport->port.membase + UCR1);
if (on)
val |= UCR1_RTSDEN;
else
val &= ~UCR1_RTSDEN;
writel(val, sport->port.membase + UCR1);
}
}
static int imx_serial_port_suspend_noirq(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct imx_port *sport = platform_get_drvdata(pdev);
int ret;
ret = clk_enable(sport->clk_ipg);
if (ret)
return ret;
serial_imx_save_context(sport);
......@@ -2275,8 +2261,6 @@ static int imx_serial_port_resume_noirq(struct device *dev)
serial_imx_restore_context(sport);
clk_disable(sport->clk_ipg);
return 0;
}
......@@ -2284,15 +2268,19 @@ static int imx_serial_port_suspend(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct imx_port *sport = platform_get_drvdata(pdev);
/* enable wakeup from i.MX UART */
serial_imx_enable_wakeup(sport, true);
int ret;
uart_suspend_port(&imx_reg, &sport->port);
disable_irq(sport->port.irq);
/* Needed to enable clock in suspend_noirq */
return clk_prepare(sport->clk_ipg);
ret = clk_prepare_enable(sport->clk_ipg);
if (ret)
return ret;
/* enable wakeup from i.MX UART */
serial_imx_enable_wakeup(sport, true);
return 0;
}
static int imx_serial_port_resume(struct device *dev)
......@@ -2306,7 +2294,7 @@ static int imx_serial_port_resume(struct device *dev)
uart_resume_port(&imx_reg, &sport->port);
enable_irq(sport->port.irq);
clk_unprepare(sport->clk_ipg);
clk_disable_unprepare(sport->clk_ipg);
return 0;
}
......@@ -2318,8 +2306,7 @@ static int imx_serial_port_freeze(struct device *dev)
uart_suspend_port(&imx_reg, &sport->port);
/* Needed to enable clock in suspend_noirq */
return clk_prepare(sport->clk_ipg);
return clk_prepare_enable(sport->clk_ipg);
}
static int imx_serial_port_thaw(struct device *dev)
......@@ -2329,7 +2316,7 @@ static int imx_serial_port_thaw(struct device *dev)
uart_resume_port(&imx_reg, &sport->port);
clk_unprepare(sport->clk_ipg);
clk_disable_unprepare(sport->clk_ipg);
return 0;
}
......
......@@ -282,9 +282,6 @@ static void neo_copy_data_from_uart_to_queue(struct jsm_channel *ch)
u16 head;
u16 tail;
if (!ch)
return;
/* cache head and tail of queue */
head = ch->ch_r_head & RQUEUEMASK;
tail = ch->ch_r_tail & RQUEUEMASK;
......@@ -1175,6 +1172,9 @@ static irqreturn_t neo_intr(int irq, void *voidbrd)
continue;
ch = brd->channels[port];
if (!ch)
continue;
neo_copy_data_from_uart_to_queue(ch);
/* Call our tty layer to enforce queue flow control if needed. */
......
......@@ -523,9 +523,6 @@ void jsm_input(struct jsm_channel *ch)
jsm_dbg(READ, &ch->ch_bd->pci_dev, "start\n");
if (!ch)
return;
port = &ch->uart_port.state->port;
tp = port->tty;
......@@ -648,11 +645,8 @@ static void jsm_carrier(struct jsm_channel *ch)
int phys_carrier = 0;
jsm_dbg(CARR, &ch->ch_bd->pci_dev, "start\n");
if (!ch)
return;
bd = ch->ch_bd;
if (!bd)
return;
......
This diff is collapsed.
......@@ -34,9 +34,15 @@
/* AML_UART_CONTROL bits */
#define AML_UART_TX_EN BIT(12)
#define AML_UART_RX_EN BIT(13)
#define AML_UART_TWO_WIRE_EN BIT(15)
#define AML_UART_STOP_BIT_LEN_MASK (0x03 << 16)
#define AML_UART_STOP_BIT_1SB (0x00 << 16)
#define AML_UART_STOP_BIT_2SB (0x01 << 16)
#define AML_UART_PARITY_TYPE BIT(18)
#define AML_UART_PARITY_EN BIT(19)
#define AML_UART_TX_RST BIT(22)
#define AML_UART_RX_RST BIT(23)
#define AML_UART_CLR_ERR BIT(24)
#define AML_UART_CLEAR_ERR BIT(24)
#define AML_UART_RX_INT_EN BIT(27)
#define AML_UART_TX_INT_EN BIT(28)
#define AML_UART_DATA_LEN_MASK (0x03 << 20)
......@@ -57,15 +63,6 @@
AML_UART_FRAME_ERR | \
AML_UART_TX_FIFO_WERR)
/* AML_UART_CONTROL bits */
#define AML_UART_TWO_WIRE_EN BIT(15)
#define AML_UART_PARITY_TYPE BIT(18)
#define AML_UART_PARITY_EN BIT(19)
#define AML_UART_CLEAR_ERR BIT(24)
#define AML_UART_STOP_BIN_LEN_MASK (0x03 << 16)
#define AML_UART_STOP_BIN_1SB (0x00 << 16)
#define AML_UART_STOP_BIN_2SB (0x01 << 16)
/* AML_UART_MISC bits */
#define AML_UART_XMIT_IRQ(c) (((c) & 0xff) << 8)
#define AML_UART_RECV_IRQ(c) ((c) & 0xff)
......@@ -263,10 +260,10 @@ static void meson_uart_reset(struct uart_port *port)
u32 val;
val = readl(port->membase + AML_UART_CONTROL);
val |= (AML_UART_RX_RST | AML_UART_TX_RST | AML_UART_CLR_ERR);
val |= (AML_UART_RX_RST | AML_UART_TX_RST | AML_UART_CLEAR_ERR);
writel(val, port->membase + AML_UART_CONTROL);
val &= ~(AML_UART_RX_RST | AML_UART_TX_RST | AML_UART_CLR_ERR);
val &= ~(AML_UART_RX_RST | AML_UART_TX_RST | AML_UART_CLEAR_ERR);
writel(val, port->membase + AML_UART_CONTROL);
}
......@@ -276,9 +273,9 @@ static int meson_uart_startup(struct uart_port *port)
int ret = 0;
val = readl(port->membase + AML_UART_CONTROL);
val |= AML_UART_CLR_ERR;
val |= AML_UART_CLEAR_ERR;
writel(val, port->membase + AML_UART_CONTROL);
val &= ~AML_UART_CLR_ERR;
val &= ~AML_UART_CLEAR_ERR;
writel(val, port->membase + AML_UART_CONTROL);
val |= (AML_UART_RX_EN | AML_UART_TX_EN);
......@@ -354,11 +351,11 @@ static void meson_uart_set_termios(struct uart_port *port,
else
val &= ~AML_UART_PARITY_TYPE;
val &= ~AML_UART_STOP_BIN_LEN_MASK;
val &= ~AML_UART_STOP_BIT_LEN_MASK;
if (cflags & CSTOPB)
val |= AML_UART_STOP_BIN_2SB;
val |= AML_UART_STOP_BIT_2SB;
else
val |= AML_UART_STOP_BIN_1SB;
val |= AML_UART_STOP_BIT_1SB;
if (cflags & CRTSCTS)
val &= ~AML_UART_TWO_WIRE_EN;
......
......@@ -40,7 +40,6 @@
#include <asm/cacheflush.h>
#include <linux/gpio.h>
#include <linux/gpio/consumer.h>
#include <linux/err.h>
#include <linux/irq.h>
......@@ -1597,7 +1596,7 @@ static int mxs_auart_init_gpios(struct mxs_auart_port *s, struct device *dev)
for (i = 0; i < UART_GPIO_MAX; i++) {
gpiod = mctrl_gpio_to_gpiod(s->gpios, i);
if (gpiod && (gpiod_get_direction(gpiod) == GPIOF_DIR_IN))
if (gpiod && (gpiod_get_direction(gpiod) == 1))
s->gpio_irq[i] = gpiod_to_irq(gpiod);
else
s->gpio_irq[i] = -EINVAL;
......@@ -1721,7 +1720,7 @@ static int mxs_auart_probe(struct platform_device *pdev)
ret = uart_add_one_port(&auart_driver, &s->port);
if (ret)
goto out_free_gpio_irq;
goto out_disable_clks_free_qpio_irq;
/* ASM9260 don't have version reg */
if (is_asm9260_auart(s)) {
......@@ -1735,7 +1734,11 @@ static int mxs_auart_probe(struct platform_device *pdev)
return 0;
out_free_gpio_irq:
out_disable_clks_free_qpio_irq:
if (s->clk)
clk_disable_unprepare(s->clk_ahb);
if (s->clk_ahb)
clk_disable_unprepare(s->clk_ahb);
mxs_auart_free_gpio_irq(s);
auart_port[pdev->id] = NULL;
return ret;
......
......@@ -1602,7 +1602,6 @@ static int serial_omap_probe_rs485(struct uart_omap_port *up,
struct device_node *np)
{
struct serial_rs485 *rs485conf = &up->port.rs485;
enum of_gpio_flags flags;
int ret;
rs485conf->flags = 0;
......@@ -1611,19 +1610,24 @@ static int serial_omap_probe_rs485(struct uart_omap_port *up,
if (!np)
return 0;
if (of_property_read_bool(np, "rs485-rts-active-high"))
uart_get_rs485_mode(up->dev, rs485conf);
if (of_property_read_bool(np, "rs485-rts-active-high")) {
rs485conf->flags |= SER_RS485_RTS_ON_SEND;
else
rs485conf->flags &= ~SER_RS485_RTS_AFTER_SEND;
} else {
rs485conf->flags &= ~SER_RS485_RTS_ON_SEND;
rs485conf->flags |= SER_RS485_RTS_AFTER_SEND;
}
/* check for tx enable gpio */
up->rts_gpio = of_get_named_gpio_flags(np, "rts-gpio", 0, &flags);
up->rts_gpio = of_get_named_gpio(np, "rts-gpio", 0);
if (gpio_is_valid(up->rts_gpio)) {
ret = devm_gpio_request(up->dev, up->rts_gpio, "omap-serial");
if (ret < 0)
return ret;
ret = gpio_direction_output(up->rts_gpio,
flags & SER_RS485_RTS_AFTER_SEND);
ret = rs485conf->flags & SER_RS485_RTS_AFTER_SEND ? 1 : 0;
ret = gpio_direction_output(up->rts_gpio, ret);
if (ret < 0)
return ret;
} else if (up->rts_gpio == -EPROBE_DEFER) {
......@@ -1632,8 +1636,6 @@ static int serial_omap_probe_rs485(struct uart_omap_port *up,
up->rts_gpio = -EINVAL;
}
of_get_rs485_mode(np, rs485conf);
return 0;
}
......
......@@ -974,6 +974,8 @@ static int uart_set_info(struct tty_struct *tty, struct tty_port *port,
}
} else {
retval = uart_startup(tty, state, 1);
if (retval == 0)
tty_port_set_initialized(port, true);
if (retval > 0)
retval = 0;
}
......@@ -1955,9 +1957,10 @@ EXPORT_SYMBOL_GPL(uart_parse_earlycon);
* eg: 115200n8r
*/
void
uart_parse_options(char *options, int *baud, int *parity, int *bits, int *flow)
uart_parse_options(const char *options, int *baud, int *parity,
int *bits, int *flow)
{
char *s = options;
const char *s = options;
*baud = simple_strtoul(s, NULL, 10);
while (*s >= '0' && *s <= '9')
......@@ -3013,19 +3016,20 @@ EXPORT_SYMBOL(uart_add_one_port);
EXPORT_SYMBOL(uart_remove_one_port);
/**
* of_get_rs485_mode() - Implement parsing rs485 properties
* @np: uart node
* uart_get_rs485_mode() - retrieve rs485 properties for given uart
* @dev: uart device
* @rs485conf: output parameter
*
* This function implements the device tree binding described in
* Documentation/devicetree/bindings/serial/rs485.txt.
*/
void of_get_rs485_mode(struct device_node *np, struct serial_rs485 *rs485conf)
void uart_get_rs485_mode(struct device *dev, struct serial_rs485 *rs485conf)
{
u32 rs485_delay[2];
int ret;
ret = of_property_read_u32_array(np, "rs485-rts-delay", rs485_delay, 2);
ret = device_property_read_u32_array(dev, "rs485-rts-delay",
rs485_delay, 2);
if (!ret) {
rs485conf->delay_rts_before_send = rs485_delay[0];
rs485conf->delay_rts_after_send = rs485_delay[1];
......@@ -3035,18 +3039,25 @@ void of_get_rs485_mode(struct device_node *np, struct serial_rs485 *rs485conf)
}
/*
* clear full-duplex and enabled flags to get to a defined state with
* the two following properties.
* Clear full-duplex and enabled flags, set RTS polarity to active high
* to get to a defined state with the following properties:
*/
rs485conf->flags &= ~(SER_RS485_RX_DURING_TX | SER_RS485_ENABLED);
rs485conf->flags &= ~(SER_RS485_RX_DURING_TX | SER_RS485_ENABLED |
SER_RS485_RTS_AFTER_SEND);
rs485conf->flags |= SER_RS485_RTS_ON_SEND;
if (of_property_read_bool(np, "rs485-rx-during-tx"))
if (device_property_read_bool(dev, "rs485-rx-during-tx"))
rs485conf->flags |= SER_RS485_RX_DURING_TX;
if (of_property_read_bool(np, "linux,rs485-enabled-at-boot-time"))
if (device_property_read_bool(dev, "linux,rs485-enabled-at-boot-time"))
rs485conf->flags |= SER_RS485_ENABLED;
if (device_property_read_bool(dev, "rs485-rts-active-low")) {
rs485conf->flags &= ~SER_RS485_RTS_ON_SEND;
rs485conf->flags |= SER_RS485_RTS_AFTER_SEND;
}
}
EXPORT_SYMBOL_GPL(of_get_rs485_mode);
EXPORT_SYMBOL_GPL(uart_get_rs485_mode);
MODULE_DESCRIPTION("Serial driver core");
MODULE_LICENSE("GPL");
......@@ -236,7 +236,7 @@ struct stm32_usart_info stm32h7_info = {
#define USART_ICR_CMCF BIT(17) /* F7 */
#define USART_ICR_WUCF BIT(20) /* H7 */
#define STM32_SERIAL_NAME "ttyS"
#define STM32_SERIAL_NAME "ttySTM"
#define STM32_MAX_PORTS 8
#define RX_BUF_L 200 /* dma rx buffer length */
......
......@@ -1323,6 +1323,9 @@ struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx)
"%s: %s driver does not set tty->port. This will crash the kernel later. Fix the driver!\n",
__func__, tty->driver->name);
retval = tty_ldisc_lock(tty, 5 * HZ);
if (retval)
goto err_release_lock;
tty->port->itty = tty;
/*
......@@ -1333,6 +1336,7 @@ struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx)
retval = tty_ldisc_setup(tty, tty->link);
if (retval)
goto err_release_tty;
tty_ldisc_unlock(tty);
/* Return the tty locked so that it cannot vanish under the caller */
return tty;
......@@ -1345,9 +1349,11 @@ struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx)
/* call the tty release_tty routine to clean out this slot */
err_release_tty:
tty_unlock(tty);
tty_ldisc_unlock(tty);
tty_info_ratelimited(tty, "ldisc open failed (%d), clearing slot %d\n",
retval, idx);
err_release_lock:
tty_unlock(tty);
release_tty(tty, idx);
return ERR_PTR(retval);
}
......@@ -1476,6 +1482,8 @@ static void release_tty(struct tty_struct *tty, int idx)
if (tty->link)
tty->link->port->itty = NULL;
tty_buffer_cancel_work(tty->port);
if (tty->link)
tty_buffer_cancel_work(tty->link->port);
tty_kref_put(tty->link);
tty_kref_put(tty);
......
......@@ -337,7 +337,7 @@ static inline void __tty_ldisc_unlock(struct tty_struct *tty)
ldsem_up_write(&tty->ldisc_sem);
}
static int tty_ldisc_lock(struct tty_struct *tty, unsigned long timeout)
int tty_ldisc_lock(struct tty_struct *tty, unsigned long timeout)
{
int ret;
......@@ -348,7 +348,7 @@ static int tty_ldisc_lock(struct tty_struct *tty, unsigned long timeout)
return 0;
}
static void tty_ldisc_unlock(struct tty_struct *tty)
void tty_ldisc_unlock(struct tty_struct *tty)
{
clear_bit(TTY_LDISC_HALTED, &tty->flags);
__tty_ldisc_unlock(tty);
......
......@@ -186,11 +186,7 @@ int set_selection(const struct tiocl_selection __user *sel, struct tty_struct *t
}
if (ps > pe) /* make sel_start <= sel_end */
{
int tmp = ps;
ps = pe;
pe = tmp;
}
swap(ps, pe);
if (sel_cons != vc_cons[fg_console].d) {
clear_selection();
......
......@@ -27,8 +27,10 @@ struct serdev_device;
/**
* struct serdev_device_ops - Callback operations for a serdev device
* @receive_buf: Function called with data received from device.
* @write_wakeup: Function called when ready to transmit more data.
* @receive_buf: Function called with data received from device;
* returns number of bytes accepted; may sleep.
* @write_wakeup: Function called when ready to transmit more data; must
* not sleep.
*/
struct serdev_device_ops {
int (*receive_buf)(struct serdev_device *, const unsigned char *, size_t);
......
......@@ -387,7 +387,7 @@ struct uart_port *uart_get_console(struct uart_port *ports, int nr,
struct console *c);
int uart_parse_earlycon(char *p, unsigned char *iotype, resource_size_t *addr,
char **options);
void uart_parse_options(char *options, int *baud, int *parity, int *bits,
void uart_parse_options(const char *options, int *baud, int *parity, int *bits,
int *flow);
int uart_set_options(struct uart_port *port, struct console *co, int baud,
int parity, int bits, int flow);
......@@ -501,9 +501,5 @@ static inline int uart_handle_break(struct uart_port *port)
(cflag) & CRTSCTS || \
!((cflag) & CLOCAL))
/*
* Common device tree parsing helpers
*/
void of_get_rs485_mode(struct device_node *np, struct serial_rs485 *rs485conf);
void uart_get_rs485_mode(struct device *dev, struct serial_rs485 *rs485conf);
#endif /* LINUX_SERIAL_CORE_H */
......@@ -405,6 +405,8 @@ extern const char *tty_name(const struct tty_struct *tty);
extern struct tty_struct *tty_kopen(dev_t device);
extern void tty_kclose(struct tty_struct *tty);
extern int tty_dev_name_to_number(const char *name, dev_t *number);
extern int tty_ldisc_lock(struct tty_struct *tty, unsigned long timeout);
extern void tty_ldisc_unlock(struct tty_struct *tty);
#else
static inline void tty_kref_put(struct tty_struct *tty)
{ }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment