Skip to content

Commit

Permalink
Merge tag 'tty-5.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel…
Browse files Browse the repository at this point in the history
…/git/gregkh/tty

Pull tty/serial driver updates from Greg KH:
 "Here is the big set of tty/serial driver changes for 5.12-rc1.

  Nothing huge, just lots of good cleanups and additions:

   - n_tty line discipline cleanups

   - vt core cleanups and reworks to make the code more "modern"

   - stm32 driver additions

   - tty led support added to the tty core and led layer

   - minor serial driver fixups and additions

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

* tag 'tty-5.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty: (54 commits)
  serial: core: Remove BUG_ON(in_interrupt()) check
  vt_ioctl: Remove in_interrupt() check
  dt-bindings: serial: imx: Switch to my personal address
  vt: keyboard, use new API for keyboard_tasklet
  serial: stm32: improve platform_get_irq condition handling in init_port
  serial: ifx6x60: Remove driver for deprecated platform
  tty: fix up iterate_tty_read() EOVERFLOW handling
  tty: fix up hung_up_tty_read() conversion
  tty: fix up hung_up_tty_write() conversion
  tty: teach the n_tty ICANON case about the new "cookie continuations" too
  tty: teach n_tty line discipline about the new "cookie continuations"
  tty: clean up legacy leftovers from n_tty line discipline
  tty: implement read_iter
  tty: convert tty_ldisc_ops 'read()' function to take a kernel pointer
  serial: remove sirf prima/atlas driver
  serial: mxs-auart: Remove <asm/cacheflush.h>
  serial: mxs-auart: Remove serial_mxs_probe_dt()
  serial: fsl_lpuart: Use of_device_get_match_data()
  dt-bindings: serial: renesas,hscif: Add r8a779a0 support
  tty: serial: Drop unused efm32 serial driver
  ...
  • Loading branch information
torvalds committed Feb 21, 2021
2 parents 3342ff2 + a157270 commit e428692
Show file tree
Hide file tree
Showing 70 changed files with 958 additions and 5,187 deletions.
6 changes: 6 additions & 0 deletions Documentation/ABI/testing/sysfs-class-led-trigger-tty
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
What: /sys/class/leds/<led>/ttyname
Date: Dec 2020
KernelVersion: 5.10
Contact: [email protected]
Description:
Specifies the tty device name of the triggering tty
2 changes: 1 addition & 1 deletion Documentation/devicetree/bindings/serial/fsl-imx-uart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
title: Freescale i.MX Universal Asynchronous Receiver/Transmitter (UART)

maintainers:
- Fabio Estevam <fabio.estevam@nxp.com>
- Fabio Estevam <festevam@gmail.com>

allOf:
- $ref: "serial.yaml"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
title: Freescale MXS Application UART (AUART)

maintainers:
- Fabio Estevam <fabio.estevam@nxp.com>
- Fabio Estevam <festevam@gmail.com>

allOf:
- $ref: "serial.yaml"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ properties:
- renesas,hscif-r8a77980 # R-Car V3H
- renesas,hscif-r8a77990 # R-Car E3
- renesas,hscif-r8a77995 # R-Car D3
- renesas,hscif-r8a779a0 # R-Car V3U
- const: renesas,rcar-gen3-hscif # R-Car Gen3 and RZ/G2
- const: renesas,hscif # generic HSCIF compatible UART

Expand Down
34 changes: 0 additions & 34 deletions Documentation/devicetree/bindings/serial/sirf-uart.txt

This file was deleted.

13 changes: 8 additions & 5 deletions Documentation/devicetree/bindings/serial/st,stm32-uart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,14 @@ properties:
minItems: 1
maxItems: 2

cts-gpios:
maxItems: 1

rts-gpios:
maxItems: 1
# cts-gpios and rts-gpios properties can be used instead of 'uart-has-rtscts'
# or 'st,hw-flow-ctrl' (deprecated) for making use of any gpio pins for flow
# control instead of dedicated pins.
#
# It should be noted that both cts-gpios/rts-gpios and 'uart-has-rtscts' or
# 'st,hw-flow-ctrl' (deprecated) properties cannot co-exist in a design.
cts-gpios: true
rts-gpios: true

wakeup-source: true

Expand Down
1 change: 0 additions & 1 deletion Documentation/networking/caif/caif.rst
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@ There are debugfs parameters provided for serial communication.
* tty_status: Prints the bit-mask tty status information

- 0x01 - tty->warned is on.
- 0x02 - tty->low_latency is on.
- 0x04 - tty->packed is on.
- 0x08 - tty->flow_stopped is on.
- 0x10 - tty->hw_stopped is on.
Expand Down
2 changes: 1 addition & 1 deletion drivers/accessibility/speakup/spk_ttyio.c
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ static int spk_ttyio_initialise_ldisc(struct spk_synth *synth)
if (ret)
return ret;

tty = tty_kopen(dev);
tty = tty_kopen_exclusive(dev);
if (IS_ERR(tty))
return PTR_ERR(tty);

Expand Down
34 changes: 17 additions & 17 deletions drivers/bluetooth/hci_ldisc.c
Original file line number Diff line number Diff line change
Expand Up @@ -801,7 +801,8 @@ static int hci_uart_tty_ioctl(struct tty_struct *tty, struct file *file,
* We don't provide read/write/poll interface for user space.
*/
static ssize_t hci_uart_tty_read(struct tty_struct *tty, struct file *file,
unsigned char __user *buf, size_t nr)
unsigned char *buf, size_t nr,
void **cookie, unsigned long offset)
{
return 0;
}
Expand All @@ -818,29 +819,28 @@ static __poll_t hci_uart_tty_poll(struct tty_struct *tty,
return 0;
}

static struct tty_ldisc_ops hci_uart_ldisc = {
.owner = THIS_MODULE,
.magic = TTY_LDISC_MAGIC,
.name = "n_hci",
.open = hci_uart_tty_open,
.close = hci_uart_tty_close,
.read = hci_uart_tty_read,
.write = hci_uart_tty_write,
.ioctl = hci_uart_tty_ioctl,
.compat_ioctl = hci_uart_tty_ioctl,
.poll = hci_uart_tty_poll,
.receive_buf = hci_uart_tty_receive,
.write_wakeup = hci_uart_tty_wakeup,
};

static int __init hci_uart_init(void)
{
static struct tty_ldisc_ops hci_uart_ldisc;
int err;

BT_INFO("HCI UART driver ver %s", VERSION);

/* Register the tty discipline */

memset(&hci_uart_ldisc, 0, sizeof(hci_uart_ldisc));
hci_uart_ldisc.magic = TTY_LDISC_MAGIC;
hci_uart_ldisc.name = "n_hci";
hci_uart_ldisc.open = hci_uart_tty_open;
hci_uart_ldisc.close = hci_uart_tty_close;
hci_uart_ldisc.read = hci_uart_tty_read;
hci_uart_ldisc.write = hci_uart_tty_write;
hci_uart_ldisc.ioctl = hci_uart_tty_ioctl;
hci_uart_ldisc.compat_ioctl = hci_uart_tty_ioctl;
hci_uart_ldisc.poll = hci_uart_tty_poll;
hci_uart_ldisc.receive_buf = hci_uart_tty_receive;
hci_uart_ldisc.write_wakeup = hci_uart_tty_wakeup;
hci_uart_ldisc.owner = THIS_MODULE;

err = tty_register_ldisc(N_HCI, &hci_uart_ldisc);
if (err) {
BT_ERR("HCI line discipline registration failed. (%d)", err);
Expand Down
2 changes: 0 additions & 2 deletions drivers/char/pcmcia/synclink_cs.c
Original file line number Diff line number Diff line change
Expand Up @@ -2494,8 +2494,6 @@ static int mgslpc_open(struct tty_struct *tty, struct file * filp)
printk("%s(%d):mgslpc_open(%s), old ref count = %d\n",
__FILE__, __LINE__, tty->driver->name, port->count);

port->low_latency = (port->flags & ASYNC_LOW_LATENCY) ? 1 : 0;

spin_lock_irqsave(&info->netlock, flags);
if (info->netcount) {
retval = -EBUSY;
Expand Down
4 changes: 3 additions & 1 deletion drivers/input/serio/serport.c
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,9 @@ static void serport_ldisc_receive(struct tty_struct *tty, const unsigned char *c
* returning 0 characters.
*/

static ssize_t serport_ldisc_read(struct tty_struct * tty, struct file * file, unsigned char __user * buf, size_t nr)
static ssize_t serport_ldisc_read(struct tty_struct * tty, struct file * file,
unsigned char *kbuf, size_t nr,
void **cookie, unsigned long offset)
{
struct serport *serport = (struct serport*) tty->disc_data;
struct serio *serio;
Expand Down
9 changes: 9 additions & 0 deletions drivers/leds/trigger/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -144,4 +144,13 @@ config LEDS_TRIGGER_AUDIO
the audio mute and mic-mute changes.
If unsure, say N

config LEDS_TRIGGER_TTY
tristate "LED Trigger for TTY devices"
depends on TTY
help
This allows LEDs to be controlled by activity on ttys which includes
serial devices like /dev/ttyS0.

When build as a module this driver will be called ledtrig-tty.

endif # LEDS_TRIGGERS
1 change: 1 addition & 0 deletions drivers/leds/trigger/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,4 @@ obj-$(CONFIG_LEDS_TRIGGER_PANIC) += ledtrig-panic.o
obj-$(CONFIG_LEDS_TRIGGER_NETDEV) += ledtrig-netdev.o
obj-$(CONFIG_LEDS_TRIGGER_PATTERN) += ledtrig-pattern.o
obj-$(CONFIG_LEDS_TRIGGER_AUDIO) += ledtrig-audio.o
obj-$(CONFIG_LEDS_TRIGGER_TTY) += ledtrig-tty.o
183 changes: 183 additions & 0 deletions drivers/leds/trigger/ledtrig-tty.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
// SPDX-License-Identifier: GPL-2.0

#include <linux/delay.h>
#include <linux/leds.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/tty.h>
#include <uapi/linux/serial.h>

struct ledtrig_tty_data {
struct led_classdev *led_cdev;
struct delayed_work dwork;
struct mutex mutex;
const char *ttyname;
struct tty_struct *tty;
int rx, tx;
};

static void ledtrig_tty_restart(struct ledtrig_tty_data *trigger_data)
{
schedule_delayed_work(&trigger_data->dwork, 0);
}

static ssize_t ttyname_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct ledtrig_tty_data *trigger_data = led_trigger_get_drvdata(dev);
ssize_t len = 0;

mutex_lock(&trigger_data->mutex);

if (trigger_data->ttyname)
len = sprintf(buf, "%s\n", trigger_data->ttyname);

mutex_unlock(&trigger_data->mutex);

return len;
}

static ssize_t ttyname_store(struct device *dev,
struct device_attribute *attr, const char *buf,
size_t size)
{
struct ledtrig_tty_data *trigger_data = led_trigger_get_drvdata(dev);
char *ttyname;
ssize_t ret = size;
bool running;

if (size > 0 && buf[size - 1] == '\n')
size -= 1;

if (size) {
ttyname = kmemdup_nul(buf, size, GFP_KERNEL);
if (!ttyname) {
ret = -ENOMEM;
goto out_unlock;
}
} else {
ttyname = NULL;
}

mutex_lock(&trigger_data->mutex);

running = trigger_data->ttyname != NULL;

kfree(trigger_data->ttyname);
tty_kref_put(trigger_data->tty);
trigger_data->tty = NULL;

trigger_data->ttyname = ttyname;

out_unlock:
mutex_unlock(&trigger_data->mutex);

if (ttyname && !running)
ledtrig_tty_restart(trigger_data);

return ret;
}
static DEVICE_ATTR_RW(ttyname);

static void ledtrig_tty_work(struct work_struct *work)
{
struct ledtrig_tty_data *trigger_data =
container_of(work, struct ledtrig_tty_data, dwork.work);
struct serial_icounter_struct icount;
int ret;

mutex_lock(&trigger_data->mutex);

if (!trigger_data->ttyname) {
/* exit without rescheduling */
mutex_unlock(&trigger_data->mutex);
return;
}

/* try to get the tty corresponding to $ttyname */
if (!trigger_data->tty) {
dev_t devno;
struct tty_struct *tty;
int ret;

ret = tty_dev_name_to_number(trigger_data->ttyname, &devno);
if (ret < 0)
/*
* A device with this name might appear later, so keep
* retrying.
*/
goto out;

tty = tty_kopen_shared(devno);
if (IS_ERR(tty) || !tty)
/* What to do? retry or abort */
goto out;

trigger_data->tty = tty;
}

ret = tty_get_icount(trigger_data->tty, &icount);
if (ret) {
dev_info(trigger_data->tty->dev, "Failed to get icount, stopped polling\n");
mutex_unlock(&trigger_data->mutex);
return;
}

if (icount.rx != trigger_data->rx ||
icount.tx != trigger_data->tx) {
led_set_brightness(trigger_data->led_cdev, LED_ON);

trigger_data->rx = icount.rx;
trigger_data->tx = icount.tx;
} else {
led_set_brightness(trigger_data->led_cdev, LED_OFF);
}

out:
mutex_unlock(&trigger_data->mutex);
schedule_delayed_work(&trigger_data->dwork, msecs_to_jiffies(100));
}

static struct attribute *ledtrig_tty_attrs[] = {
&dev_attr_ttyname.attr,
NULL
};
ATTRIBUTE_GROUPS(ledtrig_tty);

static int ledtrig_tty_activate(struct led_classdev *led_cdev)
{
struct ledtrig_tty_data *trigger_data;

trigger_data = kzalloc(sizeof(*trigger_data), GFP_KERNEL);
if (!trigger_data)
return -ENOMEM;

led_set_trigger_data(led_cdev, trigger_data);

INIT_DELAYED_WORK(&trigger_data->dwork, ledtrig_tty_work);
trigger_data->led_cdev = led_cdev;
mutex_init(&trigger_data->mutex);

return 0;
}

static void ledtrig_tty_deactivate(struct led_classdev *led_cdev)
{
struct ledtrig_tty_data *trigger_data = led_get_trigger_data(led_cdev);

cancel_delayed_work_sync(&trigger_data->dwork);

kfree(trigger_data);
}

static struct led_trigger ledtrig_tty = {
.name = "tty",
.activate = ledtrig_tty_activate,
.deactivate = ledtrig_tty_deactivate,
.groups = ledtrig_tty_groups,
};
module_led_trigger(ledtrig_tty);

MODULE_AUTHOR("Uwe Kleine-König <[email protected]>");
MODULE_DESCRIPTION("UART LED trigger");
MODULE_LICENSE("GPL v2");
3 changes: 1 addition & 2 deletions drivers/net/caif/caif_serial.c
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,7 @@ static inline void update_tty_status(struct ser_device *ser)
ser->tty_status =
ser->tty->stopped << 5 |
ser->tty->flow_stopped << 3 |
ser->tty->packet << 2 |
ser->tty->port->low_latency << 1;
ser->tty->packet << 2;
}
static inline void debugfs_init(struct ser_device *ser, struct tty_struct *tty)
{
Expand Down
Loading

0 comments on commit e428692

Please sign in to comment.