Commit 249f1efd authored by Linus Torvalds's avatar Linus Torvalds

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

Pull tty/serial fixes from Greg KH:
 "Here are some serial and tty fixes for 4.12-rc3. They are a bit bigger
  than normal, which is why I had them bake in linux-next for a few
  weeks and didn't send them to you for -rc2.

  They revert a few of the serdev patches from 4.12-rc1, and bring
  things back to how they were in 4.11, to try to make things a bit more
  stable there. Rob and Johan both agree that this is the way forward,
  so this isn't people squabbling over semantics. Other than that, just
  a few minor serial driver fixes that people have had problems with.

  All of these have been in linux-next for a few weeks with no reported
  issues"

* tag 'tty-4.12-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty:
  serial: altera_uart: call iounmap() at driver remove
  serial: imx: ensure UCR3 and UFCR are setup correctly
  MAINTAINERS/serial: Change maintainer of jsm driver
  serial: enable serdev support
  tty/serdev: add serdev registration interface
  serdev: Restore serdev_device_write_buf for atomic context
  serial: core: fix crash in uart_suspend_port
  tty: fix port buffer locking
  tty: ehv_bytechan: clean up init error handling
  serial: ifx6x60: fix use-after-free on module unload
  serial: altera_jtaguart: adding iounmap()
  serial: exar: Fix stuck MSIs
  serial: efm32: Fix parity management in 'efm32_uart_console_get_options()'
  serdev: fix tty-port client deregistration
  Revert "tty_port: register tty ports with serdev bus"
  drivers/tty: 8250: only call fintek_8250_probe when doing port I/O
parents 6f68a6ae 59fe2cc8
...@@ -7143,7 +7143,7 @@ S: Maintained ...@@ -7143,7 +7143,7 @@ S: Maintained
F: drivers/media/platform/rcar_jpu.c F: drivers/media/platform/rcar_jpu.c
JSM Neo PCI based serial card JSM Neo PCI based serial card
M: Gabriel Krisman Bertazi <krisman@linux.vnet.ibm.com> M: Guilherme G. Piccoli <gpiccoli@linux.vnet.ibm.com>
L: linux-serial@vger.kernel.org L: linux-serial@vger.kernel.org
S: Maintained S: Maintained
F: drivers/tty/serial/jsm/ F: drivers/tty/serial/jsm/
......
...@@ -764,7 +764,7 @@ static int __init ehv_bc_init(void) ...@@ -764,7 +764,7 @@ static int __init ehv_bc_init(void)
ehv_bc_driver = alloc_tty_driver(count); ehv_bc_driver = alloc_tty_driver(count);
if (!ehv_bc_driver) { if (!ehv_bc_driver) {
ret = -ENOMEM; ret = -ENOMEM;
goto error; goto err_free_bcs;
} }
ehv_bc_driver->driver_name = "ehv-bc"; ehv_bc_driver->driver_name = "ehv-bc";
...@@ -778,24 +778,23 @@ static int __init ehv_bc_init(void) ...@@ -778,24 +778,23 @@ static int __init ehv_bc_init(void)
ret = tty_register_driver(ehv_bc_driver); ret = tty_register_driver(ehv_bc_driver);
if (ret) { if (ret) {
pr_err("ehv-bc: could not register tty driver (ret=%i)\n", ret); pr_err("ehv-bc: could not register tty driver (ret=%i)\n", ret);
goto error; goto err_put_tty_driver;
} }
ret = platform_driver_register(&ehv_bc_tty_driver); ret = platform_driver_register(&ehv_bc_tty_driver);
if (ret) { if (ret) {
pr_err("ehv-bc: could not register platform driver (ret=%i)\n", pr_err("ehv-bc: could not register platform driver (ret=%i)\n",
ret); ret);
goto error; goto err_deregister_tty_driver;
} }
return 0; return 0;
error: err_deregister_tty_driver:
if (ehv_bc_driver) { tty_unregister_driver(ehv_bc_driver);
tty_unregister_driver(ehv_bc_driver); err_put_tty_driver:
put_tty_driver(ehv_bc_driver); put_tty_driver(ehv_bc_driver);
} err_free_bcs:
kfree(bcs); kfree(bcs);
return ret; return ret;
......
...@@ -122,6 +122,18 @@ void serdev_device_write_wakeup(struct serdev_device *serdev) ...@@ -122,6 +122,18 @@ void serdev_device_write_wakeup(struct serdev_device *serdev)
} }
EXPORT_SYMBOL_GPL(serdev_device_write_wakeup); EXPORT_SYMBOL_GPL(serdev_device_write_wakeup);
int serdev_device_write_buf(struct serdev_device *serdev,
const unsigned char *buf, size_t count)
{
struct serdev_controller *ctrl = serdev->ctrl;
if (!ctrl || !ctrl->ops->write_buf)
return -EINVAL;
return ctrl->ops->write_buf(ctrl, buf, count);
}
EXPORT_SYMBOL_GPL(serdev_device_write_buf);
int serdev_device_write(struct serdev_device *serdev, int serdev_device_write(struct serdev_device *serdev,
const unsigned char *buf, size_t count, const unsigned char *buf, size_t count,
unsigned long timeout) unsigned long timeout)
......
...@@ -102,9 +102,6 @@ static int ttyport_open(struct serdev_controller *ctrl) ...@@ -102,9 +102,6 @@ static int ttyport_open(struct serdev_controller *ctrl)
return PTR_ERR(tty); return PTR_ERR(tty);
serport->tty = tty; serport->tty = tty;
serport->port->client_ops = &client_ops;
serport->port->client_data = ctrl;
if (tty->ops->open) if (tty->ops->open)
tty->ops->open(serport->tty, NULL); tty->ops->open(serport->tty, NULL);
else else
...@@ -215,6 +212,7 @@ struct device *serdev_tty_port_register(struct tty_port *port, ...@@ -215,6 +212,7 @@ struct device *serdev_tty_port_register(struct tty_port *port,
struct device *parent, struct device *parent,
struct tty_driver *drv, int idx) struct tty_driver *drv, int idx)
{ {
const struct tty_port_client_operations *old_ops;
struct serdev_controller *ctrl; struct serdev_controller *ctrl;
struct serport *serport; struct serport *serport;
int ret; int ret;
...@@ -233,28 +231,37 @@ struct device *serdev_tty_port_register(struct tty_port *port, ...@@ -233,28 +231,37 @@ struct device *serdev_tty_port_register(struct tty_port *port,
ctrl->ops = &ctrl_ops; ctrl->ops = &ctrl_ops;
old_ops = port->client_ops;
port->client_ops = &client_ops;
port->client_data = ctrl;
ret = serdev_controller_add(ctrl); ret = serdev_controller_add(ctrl);
if (ret) if (ret)
goto err_controller_put; goto err_reset_data;
dev_info(&ctrl->dev, "tty port %s%d registered\n", drv->name, idx); dev_info(&ctrl->dev, "tty port %s%d registered\n", drv->name, idx);
return &ctrl->dev; return &ctrl->dev;
err_controller_put: err_reset_data:
port->client_data = NULL;
port->client_ops = old_ops;
serdev_controller_put(ctrl); serdev_controller_put(ctrl);
return ERR_PTR(ret); return ERR_PTR(ret);
} }
void serdev_tty_port_unregister(struct tty_port *port) int serdev_tty_port_unregister(struct tty_port *port)
{ {
struct serdev_controller *ctrl = port->client_data; struct serdev_controller *ctrl = port->client_data;
struct serport *serport = serdev_controller_get_drvdata(ctrl); struct serport *serport = serdev_controller_get_drvdata(ctrl);
if (!serport) if (!serport)
return; return -ENODEV;
serdev_controller_remove(ctrl); serdev_controller_remove(ctrl);
port->client_ops = NULL; port->client_ops = NULL;
port->client_data = NULL; port->client_data = NULL;
serdev_controller_put(ctrl); serdev_controller_put(ctrl);
return 0;
} }
...@@ -47,6 +47,7 @@ ...@@ -47,6 +47,7 @@
/* /*
* These are definitions for the Exar XR17V35X and XR17(C|D)15X * These are definitions for the Exar XR17V35X and XR17(C|D)15X
*/ */
#define UART_EXAR_INT0 0x80
#define UART_EXAR_SLEEP 0x8b /* Sleep mode */ #define UART_EXAR_SLEEP 0x8b /* Sleep mode */
#define UART_EXAR_DVID 0x8d /* Device identification */ #define UART_EXAR_DVID 0x8d /* Device identification */
...@@ -1337,7 +1338,7 @@ static void autoconfig(struct uart_8250_port *up) ...@@ -1337,7 +1338,7 @@ static void autoconfig(struct uart_8250_port *up)
/* /*
* Check if the device is a Fintek F81216A * Check if the device is a Fintek F81216A
*/ */
if (port->type == PORT_16550A) if (port->type == PORT_16550A && port->iotype == UPIO_PORT)
fintek_8250_probe(up); fintek_8250_probe(up);
if (up->capabilities != old_capabilities) { if (up->capabilities != old_capabilities) {
...@@ -1869,17 +1870,13 @@ static int serial8250_default_handle_irq(struct uart_port *port) ...@@ -1869,17 +1870,13 @@ static int serial8250_default_handle_irq(struct uart_port *port)
static int exar_handle_irq(struct uart_port *port) static int exar_handle_irq(struct uart_port *port)
{ {
unsigned int iir = serial_port_in(port, UART_IIR); unsigned int iir = serial_port_in(port, UART_IIR);
int ret; int ret = 0;
ret = serial8250_handle_irq(port, iir); if (((port->type == PORT_XR17V35X) || (port->type == PORT_XR17D15X)) &&
serial_port_in(port, UART_EXAR_INT0) != 0)
ret = 1;
if ((port->type == PORT_XR17V35X) || ret |= serial8250_handle_irq(port, iir);
(port->type == PORT_XR17D15X)) {
serial_port_in(port, 0x80);
serial_port_in(port, 0x81);
serial_port_in(port, 0x82);
serial_port_in(port, 0x83);
}
return ret; return ret;
} }
...@@ -2177,6 +2174,8 @@ int serial8250_do_startup(struct uart_port *port) ...@@ -2177,6 +2174,8 @@ int serial8250_do_startup(struct uart_port *port)
serial_port_in(port, UART_RX); serial_port_in(port, UART_RX);
serial_port_in(port, UART_IIR); serial_port_in(port, UART_IIR);
serial_port_in(port, UART_MSR); serial_port_in(port, UART_MSR);
if ((port->type == PORT_XR17V35X) || (port->type == PORT_XR17D15X))
serial_port_in(port, UART_EXAR_INT0);
/* /*
* At this point, there's no way the LSR could still be 0xff; * At this point, there's no way the LSR could still be 0xff;
...@@ -2335,6 +2334,8 @@ int serial8250_do_startup(struct uart_port *port) ...@@ -2335,6 +2334,8 @@ int serial8250_do_startup(struct uart_port *port)
serial_port_in(port, UART_RX); serial_port_in(port, UART_RX);
serial_port_in(port, UART_IIR); serial_port_in(port, UART_IIR);
serial_port_in(port, UART_MSR); serial_port_in(port, UART_MSR);
if ((port->type == PORT_XR17V35X) || (port->type == PORT_XR17D15X))
serial_port_in(port, UART_EXAR_INT0);
up->lsr_saved_flags = 0; up->lsr_saved_flags = 0;
up->msr_saved_flags = 0; up->msr_saved_flags = 0;
......
...@@ -478,6 +478,7 @@ static int altera_jtaguart_remove(struct platform_device *pdev) ...@@ -478,6 +478,7 @@ static int altera_jtaguart_remove(struct platform_device *pdev)
port = &altera_jtaguart_ports[i].port; port = &altera_jtaguart_ports[i].port;
uart_remove_one_port(&altera_jtaguart_driver, port); uart_remove_one_port(&altera_jtaguart_driver, port);
iounmap(port->membase);
return 0; return 0;
} }
......
...@@ -615,6 +615,7 @@ static int altera_uart_remove(struct platform_device *pdev) ...@@ -615,6 +615,7 @@ static int altera_uart_remove(struct platform_device *pdev)
if (port) { if (port) {
uart_remove_one_port(&altera_uart_driver, port); uart_remove_one_port(&altera_uart_driver, port);
port->mapbase = 0; port->mapbase = 0;
iounmap(port->membase);
} }
return 0; return 0;
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#define UARTn_FRAME 0x04 #define UARTn_FRAME 0x04
#define UARTn_FRAME_DATABITS__MASK 0x000f #define UARTn_FRAME_DATABITS__MASK 0x000f
#define UARTn_FRAME_DATABITS(n) ((n) - 3) #define UARTn_FRAME_DATABITS(n) ((n) - 3)
#define UARTn_FRAME_PARITY__MASK 0x0300
#define UARTn_FRAME_PARITY_NONE 0x0000 #define UARTn_FRAME_PARITY_NONE 0x0000
#define UARTn_FRAME_PARITY_EVEN 0x0200 #define UARTn_FRAME_PARITY_EVEN 0x0200
#define UARTn_FRAME_PARITY_ODD 0x0300 #define UARTn_FRAME_PARITY_ODD 0x0300
...@@ -572,12 +573,16 @@ static void efm32_uart_console_get_options(struct efm32_uart_port *efm_port, ...@@ -572,12 +573,16 @@ static void efm32_uart_console_get_options(struct efm32_uart_port *efm_port,
16 * (4 + (clkdiv >> 6))); 16 * (4 + (clkdiv >> 6)));
frame = efm32_uart_read32(efm_port, UARTn_FRAME); frame = efm32_uart_read32(efm_port, UARTn_FRAME);
if (frame & UARTn_FRAME_PARITY_ODD) switch (frame & UARTn_FRAME_PARITY__MASK) {
case UARTn_FRAME_PARITY_ODD:
*parity = 'o'; *parity = 'o';
else if (frame & UARTn_FRAME_PARITY_EVEN) break;
case UARTn_FRAME_PARITY_EVEN:
*parity = 'e'; *parity = 'e';
else break;
default:
*parity = 'n'; *parity = 'n';
}
*bits = (frame & UARTn_FRAME_DATABITS__MASK) - *bits = (frame & UARTn_FRAME_DATABITS__MASK) -
UARTn_FRAME_DATABITS(4) + 4; UARTn_FRAME_DATABITS(4) + 4;
......
...@@ -1382,9 +1382,9 @@ static struct spi_driver ifx_spi_driver = { ...@@ -1382,9 +1382,9 @@ static struct spi_driver ifx_spi_driver = {
static void __exit ifx_spi_exit(void) static void __exit ifx_spi_exit(void)
{ {
/* unregister */ /* unregister */
spi_unregister_driver(&ifx_spi_driver);
tty_unregister_driver(tty_drv); tty_unregister_driver(tty_drv);
put_tty_driver(tty_drv); put_tty_driver(tty_drv);
spi_unregister_driver(&ifx_spi_driver);
unregister_reboot_notifier(&ifx_modem_reboot_notifier_block); unregister_reboot_notifier(&ifx_modem_reboot_notifier_block);
} }
......
...@@ -2184,7 +2184,9 @@ static int serial_imx_probe(struct platform_device *pdev) ...@@ -2184,7 +2184,9 @@ static int serial_imx_probe(struct platform_device *pdev)
* and DCD (when they are outputs) or enables the respective * and DCD (when they are outputs) or enables the respective
* irqs. So set this bit early, i.e. before requesting irqs. * irqs. So set this bit early, i.e. before requesting irqs.
*/ */
writel(UFCR_DCEDTE, sport->port.membase + UFCR); reg = readl(sport->port.membase + UFCR);
if (!(reg & UFCR_DCEDTE))
writel(reg | UFCR_DCEDTE, sport->port.membase + UFCR);
/* /*
* Disable UCR3_RI and UCR3_DCD irqs. They are also not * Disable UCR3_RI and UCR3_DCD irqs. They are also not
...@@ -2195,7 +2197,15 @@ static int serial_imx_probe(struct platform_device *pdev) ...@@ -2195,7 +2197,15 @@ static int serial_imx_probe(struct platform_device *pdev)
sport->port.membase + UCR3); sport->port.membase + UCR3);
} else { } else {
writel(0, sport->port.membase + UFCR); unsigned long ucr3 = UCR3_DSR;
reg = readl(sport->port.membase + UFCR);
if (reg & UFCR_DCEDTE)
writel(reg & ~UFCR_DCEDTE, sport->port.membase + UFCR);
if (!is_imx1_uart(sport))
ucr3 |= IMX21_UCR3_RXDMUXSEL | UCR3_ADNIMP;
writel(ucr3, sport->port.membase + UCR3);
} }
clk_disable_unprepare(sport->clk_ipg); clk_disable_unprepare(sport->clk_ipg);
......
...@@ -2083,7 +2083,7 @@ int uart_suspend_port(struct uart_driver *drv, struct uart_port *uport) ...@@ -2083,7 +2083,7 @@ int uart_suspend_port(struct uart_driver *drv, struct uart_port *uport)
mutex_lock(&port->mutex); mutex_lock(&port->mutex);
tty_dev = device_find_child(uport->dev, &match, serial_match_port); tty_dev = device_find_child(uport->dev, &match, serial_match_port);
if (device_may_wakeup(tty_dev)) { if (tty_dev && device_may_wakeup(tty_dev)) {
if (!enable_irq_wake(uport->irq)) if (!enable_irq_wake(uport->irq))
uport->irq_wake = 1; uport->irq_wake = 1;
put_device(tty_dev); put_device(tty_dev);
...@@ -2782,7 +2782,7 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *uport) ...@@ -2782,7 +2782,7 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *uport)
* Register the port whether it's detected or not. This allows * Register the port whether it's detected or not. This allows
* setserial to be used to alter this port's parameters. * setserial to be used to alter this port's parameters.
*/ */
tty_dev = tty_port_register_device_attr(port, drv->tty_driver, tty_dev = tty_port_register_device_attr_serdev(port, drv->tty_driver,
uport->line, uport->dev, port, uport->tty_groups); uport->line, uport->dev, port, uport->tty_groups);
if (likely(!IS_ERR(tty_dev))) { if (likely(!IS_ERR(tty_dev))) {
device_set_wakeup_capable(tty_dev, 1); device_set_wakeup_capable(tty_dev, 1);
...@@ -2845,7 +2845,7 @@ int uart_remove_one_port(struct uart_driver *drv, struct uart_port *uport) ...@@ -2845,7 +2845,7 @@ int uart_remove_one_port(struct uart_driver *drv, struct uart_port *uport)
/* /*
* Remove the devices from the tty layer * Remove the devices from the tty layer
*/ */
tty_unregister_device(drv->tty_driver, uport->line); tty_port_unregister_device(port, drv->tty_driver, uport->line);
tty = tty_port_tty_get(port); tty = tty_port_tty_get(port);
if (tty) { if (tty) {
......
...@@ -34,7 +34,9 @@ static int tty_port_default_receive_buf(struct tty_port *port, ...@@ -34,7 +34,9 @@ static int tty_port_default_receive_buf(struct tty_port *port,
if (!disc) if (!disc)
return 0; return 0;
mutex_lock(&tty->atomic_write_lock);
ret = tty_ldisc_receive_buf(disc, p, (char *)f, count); ret = tty_ldisc_receive_buf(disc, p, (char *)f, count);
mutex_unlock(&tty->atomic_write_lock);
tty_ldisc_deref(disc); tty_ldisc_deref(disc);
...@@ -128,20 +130,86 @@ struct device *tty_port_register_device_attr(struct tty_port *port, ...@@ -128,20 +130,86 @@ struct device *tty_port_register_device_attr(struct tty_port *port,
struct tty_driver *driver, unsigned index, struct tty_driver *driver, unsigned index,
struct device *device, void *drvdata, struct device *device, void *drvdata,
const struct attribute_group **attr_grp) const struct attribute_group **attr_grp)
{
tty_port_link_device(port, driver, index);
return tty_register_device_attr(driver, index, device, drvdata,
attr_grp);
}
EXPORT_SYMBOL_GPL(tty_port_register_device_attr);
/**
* tty_port_register_device_attr_serdev - register tty or serdev device
* @port: tty_port of the device
* @driver: tty_driver for this device
* @index: index of the tty
* @device: parent if exists, otherwise NULL
* @drvdata: driver data for the device
* @attr_grp: attribute group for the device
*
* Register a serdev or tty device depending on if the parent device has any
* defined serdev clients or not.
*/
struct device *tty_port_register_device_attr_serdev(struct tty_port *port,
struct tty_driver *driver, unsigned index,
struct device *device, void *drvdata,
const struct attribute_group **attr_grp)
{ {
struct device *dev; struct device *dev;
tty_port_link_device(port, driver, index); tty_port_link_device(port, driver, index);
dev = serdev_tty_port_register(port, device, driver, index); dev = serdev_tty_port_register(port, device, driver, index);
if (PTR_ERR(dev) != -ENODEV) if (PTR_ERR(dev) != -ENODEV) {
/* Skip creating cdev if we registered a serdev device */ /* Skip creating cdev if we registered a serdev device */
return dev; return dev;
}
return tty_register_device_attr(driver, index, device, drvdata, return tty_register_device_attr(driver, index, device, drvdata,
attr_grp); attr_grp);
} }
EXPORT_SYMBOL_GPL(tty_port_register_device_attr); EXPORT_SYMBOL_GPL(tty_port_register_device_attr_serdev);
/**
* tty_port_register_device_serdev - register tty or serdev device
* @port: tty_port of the device
* @driver: tty_driver for this device
* @index: index of the tty
* @device: parent if exists, otherwise NULL
*
* Register a serdev or tty device depending on if the parent device has any
* defined serdev clients or not.
*/
struct device *tty_port_register_device_serdev(struct tty_port *port,
struct tty_driver *driver, unsigned index,
struct device *device)
{
return tty_port_register_device_attr_serdev(port, driver, index,
device, NULL, NULL);
}
EXPORT_SYMBOL_GPL(tty_port_register_device_serdev);
/**
* tty_port_unregister_device - deregister a tty or serdev device
* @port: tty_port of the device
* @driver: tty_driver for this device
* @index: index of the tty
*
* If a tty or serdev device is registered with a call to
* tty_port_register_device_serdev() then this function must be called when
* the device is gone.
*/
void tty_port_unregister_device(struct tty_port *port,
struct tty_driver *driver, unsigned index)
{
int ret;
ret = serdev_tty_port_unregister(port);
if (ret == 0)
return;
tty_unregister_device(driver, index);
}
EXPORT_SYMBOL_GPL(tty_port_unregister_device);
int tty_port_alloc_xmit_buf(struct tty_port *port) int tty_port_alloc_xmit_buf(struct tty_port *port)
{ {
...@@ -189,9 +257,6 @@ static void tty_port_destructor(struct kref *kref) ...@@ -189,9 +257,6 @@ static void tty_port_destructor(struct kref *kref)
/* check if last port ref was dropped before tty release */ /* check if last port ref was dropped before tty release */
if (WARN_ON(port->itty)) if (WARN_ON(port->itty))
return; return;
serdev_tty_port_unregister(port);
if (port->xmit_buf) if (port->xmit_buf)
free_page((unsigned long)port->xmit_buf); free_page((unsigned long)port->xmit_buf);
tty_port_destroy(port); tty_port_destroy(port);
......
...@@ -195,6 +195,7 @@ int serdev_device_open(struct serdev_device *); ...@@ -195,6 +195,7 @@ int serdev_device_open(struct serdev_device *);
void serdev_device_close(struct serdev_device *); void serdev_device_close(struct serdev_device *);
unsigned int serdev_device_set_baudrate(struct serdev_device *, unsigned int); unsigned int serdev_device_set_baudrate(struct serdev_device *, unsigned int);
void serdev_device_set_flow_control(struct serdev_device *, bool); void serdev_device_set_flow_control(struct serdev_device *, bool);
int serdev_device_write_buf(struct serdev_device *, const unsigned char *, size_t);
void serdev_device_wait_until_sent(struct serdev_device *, long); void serdev_device_wait_until_sent(struct serdev_device *, long);
int serdev_device_get_tiocm(struct serdev_device *); int serdev_device_get_tiocm(struct serdev_device *);
int serdev_device_set_tiocm(struct serdev_device *, int, int); int serdev_device_set_tiocm(struct serdev_device *, int, int);
...@@ -236,6 +237,12 @@ static inline unsigned int serdev_device_set_baudrate(struct serdev_device *sdev ...@@ -236,6 +237,12 @@ static inline unsigned int serdev_device_set_baudrate(struct serdev_device *sdev
return 0; return 0;
} }
static inline void serdev_device_set_flow_control(struct serdev_device *sdev, bool enable) {} static inline void serdev_device_set_flow_control(struct serdev_device *sdev, bool enable) {}
static inline int serdev_device_write_buf(struct serdev_device *serdev,
const unsigned char *buf,
size_t count)
{
return -ENODEV;
}
static inline void serdev_device_wait_until_sent(struct serdev_device *sdev, long timeout) {} static inline void serdev_device_wait_until_sent(struct serdev_device *sdev, long timeout) {}
static inline int serdev_device_get_tiocm(struct serdev_device *serdev) static inline int serdev_device_get_tiocm(struct serdev_device *serdev)
{ {
...@@ -301,7 +308,7 @@ struct tty_driver; ...@@ -301,7 +308,7 @@ struct tty_driver;
struct device *serdev_tty_port_register(struct tty_port *port, struct device *serdev_tty_port_register(struct tty_port *port,
struct device *parent, struct device *parent,
struct tty_driver *drv, int idx); struct tty_driver *drv, int idx);
void serdev_tty_port_unregister(struct tty_port *port); int serdev_tty_port_unregister(struct tty_port *port);
#else #else
static inline struct device *serdev_tty_port_register(struct tty_port *port, static inline struct device *serdev_tty_port_register(struct tty_port *port,
struct device *parent, struct device *parent,
...@@ -309,14 +316,10 @@ static inline struct device *serdev_tty_port_register(struct tty_port *port, ...@@ -309,14 +316,10 @@ static inline struct device *serdev_tty_port_register(struct tty_port *port,
{ {
return ERR_PTR(-ENODEV); return ERR_PTR(-ENODEV);
} }
static inline void serdev_tty_port_unregister(struct tty_port *port) {} static inline int serdev_tty_port_unregister(struct tty_port *port)
#endif /* CONFIG_SERIAL_DEV_CTRL_TTYPORT */
static inline int serdev_device_write_buf(struct serdev_device *serdev,
const unsigned char *data,
size_t count)
{ {
return serdev_device_write(serdev, data, count, 0); return -ENODEV;
} }
#endif /* CONFIG_SERIAL_DEV_CTRL_TTYPORT */
#endif /*_LINUX_SERDEV_H */ #endif /*_LINUX_SERDEV_H */
...@@ -558,6 +558,15 @@ extern struct device *tty_port_register_device_attr(struct tty_port *port, ...@@ -558,6 +558,15 @@ extern struct device *tty_port_register_device_attr(struct tty_port *port,
struct tty_driver *driver, unsigned index, struct tty_driver *driver, unsigned index,
struct device *device, void *drvdata, struct device *device, void *drvdata,
const struct attribute_group **attr_grp); const struct attribute_group **attr_grp);
extern struct device *tty_port_register_device_serdev(struct tty_port *port,
struct tty_driver *driver, unsigned index,
struct device *device);
extern struct device *tty_port_register_device_attr_serdev(struct tty_port *port,
struct tty_driver *driver, unsigned index,
struct device *device, void *drvdata,
const struct attribute_group **attr_grp);
extern void tty_port_unregister_device(struct tty_port *port,
struct tty_driver *driver, unsigned index);
extern int tty_port_alloc_xmit_buf(struct tty_port *port); extern int tty_port_alloc_xmit_buf(struct tty_port *port);
extern void tty_port_free_xmit_buf(struct tty_port *port); extern void tty_port_free_xmit_buf(struct tty_port *port);
extern void tty_port_destroy(struct tty_port *port); extern void tty_port_destroy(struct tty_port *port);
......
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