From: Alan Cox <alan@lxorguk.ukuu.org.uk>
To: linux-serial@vger.kernel.org
Subject: [RFC 3/5] 8250: register upio users
Date: Fri, 18 Mar 2011 15:25:38 +0000 [thread overview]
Message-ID: <20110318152529.10657.10613.stgit@bob.linux.org.uk> (raw)
In-Reply-To: <20110318152145.10657.23718.stgit@bob.linux.org.uk>
From: Alan Cox <alan@linux.intel.com>
We need to do this so we can continue to offer the setserial upio interface
while dumping I/O methods back out into the drivers.
Signed-off-by: Alan Cox <alan@linux.intel.com>
---
drivers/tty/serial/8250.c | 103 ++++++++++++++++++++++++++++++-------------
include/linux/serial_8250.h | 4 ++
2 files changed, 77 insertions(+), 30 deletions(-)
diff --git a/drivers/tty/serial/8250.c b/drivers/tty/serial/8250.c
index c3e56a7..89a00d1 100644
--- a/drivers/tty/serial/8250.c
+++ b/drivers/tty/serial/8250.c
@@ -612,46 +612,87 @@ static const struct serial8250_ops rm9k_ops = {
.serial_dl_write = rm9k_serial_dl_write
};
-/* This needs to move to a table where drivers register their ops. Needs
- some thought on the module count side */
+
+static const struct serial8250_ops *upio_ops[UPIO_MAX + 1] = {
+ /* We rely upon pio_ops being built in */
+ &pio_ops, /* UPIO_PORT */
+ &hub6_ops, /* UPIO_HUB6 */
+ &mem_ops, /* UPIO_MEM */
+ &mem32_ops, /* UPIO_MEM32 */
+ &au_ops, /* UPIO_AU */
+ &tsi_ops, /* UPIO_TSI */
+ &dwapb_ops, /* UPIO_DWAPB */
+ &rm9k_ops, /* UPIO_RM9000 */
+ &dwapb32_ops /* UPIO_DWAPB32 */
+};
+
+static DEFINE_MUTEX(upio_mutex);
+
static void set_io_from_upio(struct uart_port *p)
{
struct uart_8250_port *up =
container_of(p, struct uart_8250_port, port);
- switch (p->iotype) {
- case UPIO_HUB6:
- up->ops = &hub6_ops;
- break;
- case UPIO_MEM:
- up->ops = &mem_ops;
- break;
- case UPIO_RM9000:
- up->ops = &rm9k_ops;
- break;
- case UPIO_MEM32:
- up->ops = &mem32_ops;
- break;
- case UPIO_AU:
- up->ops = &au_ops;
- break;
- case UPIO_TSI:
- up->ops = &tsi_ops;
- break;
- case UPIO_DWAPB:
- up->ops = &dwapb_ops;
- break;
- case UPIO_DWAPB32:
- up->ops = &dwapb32_ops;
- break;
- default:
+ mutex_lock(&upio_mutex);
+ if (p->iotype > UPIO_MAX) {
+ WARN_ON(1);
up->ops = &pio_ops;
- break;
+ p->iotype = UPIO_PORT;
+ }
+ /* up->ops may differ from up->cur_iotype ops
+ For now work off cur_iotype, we should address this better later */
+ module_put(upio_ops[up->cur_iotype]->owner);
+ up->ops = upio_ops[p->iotype];
+ if (up->ops == NULL || !try_module_get(up->ops->owner)) {
+ up->ops = &pio_ops;
+ p->iotype = UPIO_PORT;
}
+
/* Remember loaded iotype */
up->cur_iotype = p->iotype;
+ mutex_unlock(&upio_mutex);
}
+/**
+ * serial8250_upio_register - register UPIO methods
+ * @upio: upio number
+ * @ops: operations for this upio
+ *
+ * Registers a set of upio operations and makes them available via
+ * the serial configuration interface for tty devices, and via the
+ * registration interfaces via upio value setting. Unless there are
+ * specific reasons new drivers should pass an ops structure directly
+ * instead.
+ */
+int serial8250_upio_register(int upio, struct serial8250_ops *ops)
+{
+ int ret = 0;
+ mutex_lock(&upio_mutex);
+ if (upio < 1 || upio > UPIO_MAX)
+ ret = -EINVAL;
+ else if (upio_ops[upio])
+ ret = -EBUSY;
+ else
+ upio_ops[upio] = ops;
+ mutex_unlock(&upio_mutex);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(serial8250_upio_register);
+
+int serial8250_upio_unregister(int upio)
+{
+ int ret = 0;
+ mutex_lock(&upio_mutex);
+ if (upio_ops[upio] == NULL) {
+ WARN_ON(1);
+ ret = -EINVAL;
+ }
+ upio_ops[upio] = NULL;
+ mutex_unlock(&upio_mutex);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(serial8250_upio_unregister);
+
static void
serial_out_sync(struct uart_8250_port *up, int offset, int value)
{
@@ -3305,7 +3346,7 @@ int serial8250_register_port(struct uart_port *port,
set_io_from_upio(&uart->port);
if (ops)
- uart->port.ops = ops;
+ uart->ops = ops;
if (serial8250_isa_config != NULL)
serial8250_isa_config(0, &uart->port,
@@ -3337,6 +3378,8 @@ void serial8250_unregister_port(int line)
if (serial8250_isa_devs) {
uart->port.flags &= ~UPF_BOOT_AUTOCONF;
uart->port.type = PORT_UNKNOWN;
+ uart->port.iotype = UPIO_PORT;
+ set_io_from_upio(&uart->port);
uart->port.dev = &serial8250_isa_devs->dev;
uart_add_one_port(&serial8250_reg, &uart->port);
} else {
diff --git a/include/linux/serial_8250.h b/include/linux/serial_8250.h
index 15806bb..30d4f62 100644
--- a/include/linux/serial_8250.h
+++ b/include/linux/serial_8250.h
@@ -24,6 +24,7 @@ struct serial8250_ops {
unsigned old);
unsigned int (*serial_dl_read)(struct uart_port *);
void (*serial_dl_write)(struct uart_port *, unsigned int);
+ struct module *owner;
};
/*
@@ -99,4 +100,7 @@ static inline int __deprecated early_serial_setup(struct uart_port *port)
return serial8250_early_setup(port, NULL);
}
+extern int serial8250_upio_register(int upio, struct serial8250_ops *ops);
+extern int serial8250_upio_unregister(int upio);
+
#endif
next prev parent reply other threads:[~2011-03-18 15:45 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-03-18 15:24 [RFC 0/5] Starting to pull out the I/O operations Alan Cox
2011-03-18 15:24 ` [RFC 1/5] 8250: Make serial_dl_write a port operation Alan Cox
2011-03-18 15:25 ` [RFC 2/5] 8250: introduce the idea of an operations struct for an 8250 port Alan Cox
2011-03-18 15:25 ` Alan Cox [this message]
2011-03-18 15:25 ` [RFC 4/5] 8250: evict the hub6 I/O operations Alan Cox
2011-03-18 15:26 ` [RFC 5/5] 8250: extract out the "odd" port types Alan Cox
2011-03-18 20:04 ` [RFC 0/5] Starting to pull out the I/O operations Greg KH
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=20110318152529.10657.10613.stgit@bob.linux.org.uk \
--to=alan@lxorguk.ukuu.org.uk \
--cc=linux-serial@vger.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).