From: Rob Herring <robh@kernel.org>
To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
Marcel Holtmann <marcel@holtmann.org>,
Jiri Slaby <jslaby@suse.com>, Sebastian Reichel <sre@kernel.org>,
Arnd Bergmann <arnd@arndb.de>,
"Dr . H . Nikolaus Schaller" <hns@goldelico.com>,
Peter Hurley <peter@hurleysoftware.com>,
Andy Shevchenko <andriy.shevchenko@linux.intel.com>,
Alan Cox <gnomes@lxorguk.ukuu.org.uk>
Cc: Loic Poulain <loic.poulain@intel.com>,
Pavel Machek <pavel@ucw.cz>, NeilBrown <neil@brown.name>,
Linus Walleij <linus.walleij@linaro.org>,
linux-bluetooth@vger.kernel.org, linux-serial@vger.kernel.org,
linux-kernel@vger.kernel.org
Subject: [PATCH 5/9] tty_port: Add port client functions
Date: Fri, 6 Jan 2017 10:26:31 -0600 [thread overview]
Message-ID: <20170106162635.19677-6-robh@kernel.org> (raw)
In-Reply-To: <20170106162635.19677-1-robh@kernel.org>
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>
---
The major change here is the access of the tty ptr and the reference taken
on the ldisc are moved into the client_ops rx function for the the ldisc.
I *think* this should be okay, but no doubt I don't understand all the
intricacies of the locking here. It does make the implementation a bit
cleaner in that the tty buffer handling is free from struct tty and the
ldisc.
drivers/tty/tty_buffer.c | 17 +++--------------
drivers/tty/tty_port.c | 39 ++++++++++++++++++++++++++++++++++++++-
include/linux/tty.h | 9 ++++++++-
3 files changed, 49 insertions(+), 16 deletions(-)
diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c
index f4dc3e296dd5..4e7a4e9dcf4d 100644
--- a/drivers/tty/tty_buffer.c
+++ b/drivers/tty/tty_buffer.c
@@ -437,7 +437,7 @@ int tty_ldisc_receive_buf(struct tty_ldisc *ld, const unsigned char *p,
EXPORT_SYMBOL_GPL(tty_ldisc_receive_buf);
static int
-receive_buf(struct tty_ldisc *ld, struct tty_buffer *head, int count)
+receive_buf(struct tty_port *port, struct tty_buffer *head, int count)
{
unsigned char *p = char_buf_ptr(head, head->read);
char *f = NULL;
@@ -445,7 +445,7 @@ receive_buf(struct tty_ldisc *ld, struct tty_buffer *head, int count)
if (~head->flags & TTYB_NORMAL)
f = flag_buf_ptr(head, head->read);
- return tty_ldisc_receive_buf(ld, p, f, count);
+ return port->client_ops->receive_buf(port, p, f, count);
}
/**
@@ -465,16 +465,6 @@ static void flush_to_ldisc(struct work_struct *work)
{
struct tty_port *port = container_of(work, struct tty_port, buf.work);
struct tty_bufhead *buf = &port->buf;
- struct tty_struct *tty;
- struct tty_ldisc *disc;
-
- tty = READ_ONCE(port->itty);
- if (tty == NULL)
- return;
-
- disc = tty_ldisc_ref(tty);
- if (disc == NULL)
- return;
mutex_lock(&buf->lock);
@@ -504,7 +494,7 @@ static void flush_to_ldisc(struct work_struct *work)
continue;
}
- count = receive_buf(disc, head, count);
+ count = receive_buf(port, head, count);
if (!count)
break;
head->read += count;
@@ -512,7 +502,6 @@ static void flush_to_ldisc(struct work_struct *work)
mutex_unlock(&buf->lock);
- tty_ldisc_deref(disc);
}
/**
diff --git a/drivers/tty/tty_port.c b/drivers/tty/tty_port.c
index 1d8804843103..232a8cbf47bc 100644
--- a/drivers/tty/tty_port.c
+++ b/drivers/tty/tty_port.c
@@ -17,6 +17,41 @@
#include <linux/delay.h>
#include <linux/module.h>
+static int tty_port_default_receive_buf(struct tty_port *port,
+ const unsigned char *p,
+ const unsigned char *f, size_t count)
+{
+ int ret;
+ struct tty_struct *tty;
+ struct tty_ldisc *disc;
+
+ tty = READ_ONCE(port->itty);
+ if (!tty)
+ return 0;
+
+ disc = tty_ldisc_ref(tty);
+ if (!disc)
+ return 0;
+
+ ret = tty_ldisc_receive_buf(disc, p, (char *)f, count);
+
+ tty_ldisc_deref(disc);
+
+ return ret;
+}
+
+static void tty_port_default_wakeup(struct tty_port *port)
+{
+ /* tty_port_tty_wakeup already took a reference to the tty */
+ tty_wakeup(port->tty);
+}
+
+static const struct tty_port_client_operations default_client_ops = {
+ .receive_buf = tty_port_default_receive_buf,
+ .write_wakeup = tty_port_default_wakeup,
+};
+
+
void tty_port_init(struct tty_port *port)
{
memset(port, 0, sizeof(*port));
@@ -28,6 +63,7 @@ void tty_port_init(struct tty_port *port)
spin_lock_init(&port->lock);
port->close_delay = (50 * HZ) / 100;
port->closing_wait = (3000 * HZ) / 100;
+ port->client_ops = &default_client_ops;
kref_init(&port->kref);
}
EXPORT_SYMBOL(tty_port_init);
@@ -275,7 +311,8 @@ void tty_port_tty_wakeup(struct tty_port *port)
struct tty_struct *tty = tty_port_tty_get(port);
if (tty) {
- tty_wakeup(tty);
+ if (test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags))
+ port->client_ops->write_wakeup(port);
tty_kref_put(tty);
}
}
diff --git a/include/linux/tty.h b/include/linux/tty.h
index 21c0fabfed60..1017e904c0a3 100644
--- a/include/linux/tty.h
+++ b/include/linux/tty.h
@@ -217,12 +217,18 @@ struct tty_port_operations {
/* Called on the final put of a port */
void (*destruct)(struct tty_port *port);
};
-
+
+struct tty_port_client_operations {
+ int (*receive_buf)(struct tty_port *port, const unsigned char *, const unsigned char *, size_t);
+ void (*write_wakeup)(struct tty_port *port);
+};
+
struct tty_port {
struct tty_bufhead buf; /* Locked internally */
struct tty_struct *tty; /* Back pointer */
struct tty_struct *itty; /* internal back ptr */
const struct tty_port_operations *ops; /* Port operations */
+ const struct tty_port_client_operations *client_ops; /* Port client operations */
spinlock_t lock; /* Lock protecting tty field */
int blocked_open; /* Waiting to open */
int count; /* Usage count */
@@ -241,6 +247,7 @@ struct tty_port {
based drain is needed else
set to size of fifo */
struct kref kref; /* Ref counter */
+ void *client_data;
};
/* tty_port::iflags bits -- use atomic bit ops */
--
2.10.1
next prev parent reply other threads:[~2017-01-06 16:26 UTC|newest]
Thread overview: 42+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-01-06 16:26 [PATCH 0/9] Serial slave device bus Rob Herring
2017-01-06 16:26 ` Rob Herring [this message]
[not found] ` <20170106162635.19677-1-robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
2017-01-06 16:26 ` [PATCH 1/9] tty: move the non-file related parts of tty_release to new tty_release_struct Rob Herring
2017-01-08 22:42 ` Sebastian Reichel
2017-01-06 16:26 ` [PATCH 2/9] tty_port: allow a port to be opened with a tty that has no file handle Rob Herring
2017-01-13 16:46 ` Rob Herring
2017-01-06 16:26 ` [PATCH 3/9] tty_port: make tty_port_register_device wrap tty_port_register_device_attr Rob Herring
2017-01-06 16:26 ` [PATCH 4/9] tty: constify tty_ldisc_receive_buf buffer pointer Rob Herring
2017-01-06 16:26 ` [PATCH 6/9] dt/bindings: Add a serial/UART attached device binding Rob Herring
2017-01-06 19:21 ` Arnd Bergmann
2017-01-06 20:41 ` Rob Herring
[not found] ` <20170106162635.19677-7-robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
2017-01-10 19:50 ` One Thousand Gnomes
2017-01-10 21:41 ` Pavel Machek
2017-01-06 16:26 ` [PATCH 8/9] serdev: add a tty port controller driver Rob Herring
[not found] ` <20170106162635.19677-9-robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
2017-01-07 14:11 ` Andy Shevchenko
2017-01-12 16:01 ` Rob Herring
2017-01-13 15:04 ` Andy Shevchenko
2017-01-13 15:28 ` Rob Herring
[not found] ` <CAL_JsqKjKz2=vWTBmzp9E3HrzJRszpq2hV4gsxcvnkTgRLH1QQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2017-01-13 15:55 ` Andy Shevchenko
2017-01-10 22:04 ` Pavel Machek
2017-01-14 2:54 ` Rob Herring
2017-01-06 16:26 ` [PATCH 9/9] tty_port: register tty ports with serdev bus Rob Herring
2017-01-06 19:25 ` [PATCH 0/9] Serial slave device bus Arnd Bergmann
2017-01-07 11:00 ` Andy Shevchenko
2017-01-10 17:24 ` Rob Herring
2017-01-10 18:32 ` Marcel Holtmann
2017-01-06 16:26 ` [PATCH 7/9] serdev: Introduce new bus for serial attached devices Rob Herring
2017-01-07 14:02 ` Andy Shevchenko
2017-01-12 20:13 ` Rob Herring
2017-01-08 22:41 ` Sebastian Reichel
2017-01-10 21:46 ` Pavel Machek
2017-01-12 19:53 ` Rob Herring
2017-01-08 22:46 ` [PATCH 0/9] Serial slave device bus Sebastian Reichel
2017-01-10 11:44 ` H. Nikolaus Schaller
2017-01-10 12:02 ` Marcel Holtmann
2017-01-10 12:10 ` H. Nikolaus Schaller
2017-01-10 12:20 ` Andy Shevchenko
2017-01-10 12:40 ` H. Nikolaus Schaller
[not found] ` <CAL_JsqL-VMQ+zCTN+4+PPPCY+-askp=H908s8R=EjjytzuC8yw@mail.gmail.com>
[not found] ` <39C27218-E564-4C7D-A8CD-8D7F654EE2B3@goldelico.com>
2017-01-13 14:48 ` Rob Herring
2017-01-16 6:46 ` H. Nikolaus Schaller
2017-01-10 12:05 ` Marcel Holtmann
2017-01-10 22:05 ` Pavel Machek
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20170106162635.19677-6-robh@kernel.org \
--to=robh@kernel.org \
--cc=andriy.shevchenko@linux.intel.com \
--cc=arnd@arndb.de \
--cc=gnomes@lxorguk.ukuu.org.uk \
--cc=gregkh@linuxfoundation.org \
--cc=hns@goldelico.com \
--cc=jslaby@suse.com \
--cc=linus.walleij@linaro.org \
--cc=linux-bluetooth@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-serial@vger.kernel.org \
--cc=loic.poulain@intel.com \
--cc=marcel@holtmann.org \
--cc=neil@brown.name \
--cc=pavel@ucw.cz \
--cc=peter@hurleysoftware.com \
--cc=sre@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).