diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-02-01 20:46:00 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-02-01 20:46:00 +0300 |
commit | db5933225f2fe50d3b91ebbba73ed9c3b703b99a (patch) | |
tree | b0178b4e74c9284d8c7ca6beb46e999b3b15d1f9 /drivers/tty/serdev | |
parent | e4ee8b85b7657d9c769b727038faabdc2e6a3412 (diff) | |
parent | c7e1b4059075c9e8eed101d7cc5da43e95eb5e18 (diff) |
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
...
Diffstat (limited to 'drivers/tty/serdev')
-rw-r--r-- | drivers/tty/serdev/core.c | 75 | ||||
-rw-r--r-- | drivers/tty/serdev/serdev-ttyport.c | 8 |
2 files changed, 48 insertions, 35 deletions
diff --git a/drivers/tty/serdev/core.c b/drivers/tty/serdev/core.c index 5a135ed46159..f439c72b9e3c 100644 --- a/drivers/tty/serdev/core.c +++ b/drivers/tty/serdev/core.c @@ -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, }; /** diff --git a/drivers/tty/serdev/serdev-ttyport.c b/drivers/tty/serdev/serdev-ttyport.c index 1bdf2959ac5c..fa1672993b4c 100644 --- a/drivers/tty/serdev/serdev-ttyport.c +++ b/drivers/tty/serdev/serdev-ttyport.c @@ -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: |