forked from torvalds/linux
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge tag 'tty-5.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel…
…/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
Showing
70 changed files
with
958 additions
and
5,187 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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"); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.