Skip to content

Commit c3485ee

Browse files
robherringgregkh
authored andcommitted
tty_port: Add port client functions
Introduce a client (upward direction) operations struct for tty_port clients. Initially supported operations are for receiving data and write wake-up. This will allow for having clients other than an ldisc. Convert the calls to the ldisc to use the client ops as the default operations. Signed-off-by: Rob Herring <robh@kernel.org> Reviewed-By: Sebastian Reichel <sre@kernel.org> Tested-By: Sebastian Reichel <sre@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent a380ed4 commit c3485ee

File tree

3 files changed

+51
-21
lines changed

3 files changed

+51
-21
lines changed

drivers/tty/tty_buffer.c

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -437,15 +437,15 @@ int tty_ldisc_receive_buf(struct tty_ldisc *ld, const unsigned char *p,
437437
EXPORT_SYMBOL_GPL(tty_ldisc_receive_buf);
438438

439439
static int
440-
receive_buf(struct tty_ldisc *ld, struct tty_buffer *head, int count)
440+
receive_buf(struct tty_port *port, struct tty_buffer *head, int count)
441441
{
442442
unsigned char *p = char_buf_ptr(head, head->read);
443443
char *f = NULL;
444444

445445
if (~head->flags & TTYB_NORMAL)
446446
f = flag_buf_ptr(head, head->read);
447447

448-
return tty_ldisc_receive_buf(ld, p, f, count);
448+
return port->client_ops->receive_buf(port, p, f, count);
449449
}
450450

451451
/**
@@ -465,16 +465,6 @@ static void flush_to_ldisc(struct work_struct *work)
465465
{
466466
struct tty_port *port = container_of(work, struct tty_port, buf.work);
467467
struct tty_bufhead *buf = &port->buf;
468-
struct tty_struct *tty;
469-
struct tty_ldisc *disc;
470-
471-
tty = READ_ONCE(port->itty);
472-
if (tty == NULL)
473-
return;
474-
475-
disc = tty_ldisc_ref(tty);
476-
if (disc == NULL)
477-
return;
478468

479469
mutex_lock(&buf->lock);
480470

@@ -504,15 +494,14 @@ static void flush_to_ldisc(struct work_struct *work)
504494
continue;
505495
}
506496

507-
count = receive_buf(disc, head, count);
497+
count = receive_buf(port, head, count);
508498
if (!count)
509499
break;
510500
head->read += count;
511501
}
512502

513503
mutex_unlock(&buf->lock);
514504

515-
tty_ldisc_deref(disc);
516505
}
517506

518507
/**

drivers/tty/tty_port.c

Lines changed: 40 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,44 @@
1717
#include <linux/delay.h>
1818
#include <linux/module.h>
1919

20+
static int tty_port_default_receive_buf(struct tty_port *port,
21+
const unsigned char *p,
22+
const unsigned char *f, size_t count)
23+
{
24+
int ret;
25+
struct tty_struct *tty;
26+
struct tty_ldisc *disc;
27+
28+
tty = READ_ONCE(port->itty);
29+
if (!tty)
30+
return 0;
31+
32+
disc = tty_ldisc_ref(tty);
33+
if (!disc)
34+
return 0;
35+
36+
ret = tty_ldisc_receive_buf(disc, p, (char *)f, count);
37+
38+
tty_ldisc_deref(disc);
39+
40+
return ret;
41+
}
42+
43+
static void tty_port_default_wakeup(struct tty_port *port)
44+
{
45+
struct tty_struct *tty = tty_port_tty_get(port);
46+
47+
if (tty) {
48+
tty_wakeup(tty);
49+
tty_kref_put(tty);
50+
}
51+
}
52+
53+
static const struct tty_port_client_operations default_client_ops = {
54+
.receive_buf = tty_port_default_receive_buf,
55+
.write_wakeup = tty_port_default_wakeup,
56+
};
57+
2058
void tty_port_init(struct tty_port *port)
2159
{
2260
memset(port, 0, sizeof(*port));
@@ -28,6 +66,7 @@ void tty_port_init(struct tty_port *port)
2866
spin_lock_init(&port->lock);
2967
port->close_delay = (50 * HZ) / 100;
3068
port->closing_wait = (3000 * HZ) / 100;
69+
port->client_ops = &default_client_ops;
3170
kref_init(&port->kref);
3271
}
3372
EXPORT_SYMBOL(tty_port_init);
@@ -272,12 +311,7 @@ EXPORT_SYMBOL_GPL(tty_port_tty_hangup);
272311
*/
273312
void tty_port_tty_wakeup(struct tty_port *port)
274313
{
275-
struct tty_struct *tty = tty_port_tty_get(port);
276-
277-
if (tty) {
278-
tty_wakeup(tty);
279-
tty_kref_put(tty);
280-
}
314+
port->client_ops->write_wakeup(port);
281315
}
282316
EXPORT_SYMBOL_GPL(tty_port_tty_wakeup);
283317

include/linux/tty.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,12 +217,18 @@ struct tty_port_operations {
217217
/* Called on the final put of a port */
218218
void (*destruct)(struct tty_port *port);
219219
};
220-
220+
221+
struct tty_port_client_operations {
222+
int (*receive_buf)(struct tty_port *port, const unsigned char *, const unsigned char *, size_t);
223+
void (*write_wakeup)(struct tty_port *port);
224+
};
225+
221226
struct tty_port {
222227
struct tty_bufhead buf; /* Locked internally */
223228
struct tty_struct *tty; /* Back pointer */
224229
struct tty_struct *itty; /* internal back ptr */
225230
const struct tty_port_operations *ops; /* Port operations */
231+
const struct tty_port_client_operations *client_ops; /* Port client operations */
226232
spinlock_t lock; /* Lock protecting tty field */
227233
int blocked_open; /* Waiting to open */
228234
int count; /* Usage count */
@@ -241,6 +247,7 @@ struct tty_port {
241247
based drain is needed else
242248
set to size of fifo */
243249
struct kref kref; /* Ref counter */
250+
void *client_data;
244251
};
245252

246253
/* tty_port::iflags bits -- use atomic bit ops */

0 commit comments

Comments
 (0)