* [RFC 0/5] Starting to pull out the I/O operations
@ 2011-03-18 15:24 Alan Cox
2011-03-18 15:24 ` [RFC 1/5] 8250: Make serial_dl_write a port operation Alan Cox
` (5 more replies)
0 siblings, 6 replies; 7+ messages in thread
From: Alan Cox @ 2011-03-18 15:24 UTC (permalink / raw)
To: linux-serial
This is an untested WIP but as it was coming in discussion about device-tree
as well I figured it will be useful to post the prototype code at this point.
There is lots left to do - in particular resource claim/release should be an
ops method, and it's going to need people to update various embedded 8250
drivers when we finally go for a version of it.
On the bright side once we have an ops structure we have the basis for avoiding
further mayhem in the arch code.
---
Alan Cox (5):
8250: extract out the "odd" port types
8250: evict the hub6 I/O operations
8250: register upio users
8250: introduce the idea of an operations struct for an 8250 port
8250: Make serial_dl_write a port operation
drivers/char/mwave/mwavedd.c | 2
drivers/tty/serial/8250.c | 450 ++++++++++++++-------------------------
drivers/tty/serial/8250.h | 27 ++
drivers/tty/serial/8250_au.c | 90 ++++++++
drivers/tty/serial/8250_dwapb.c | 120 ++++++++++
drivers/tty/serial/8250_hub6.c | 39 +++
drivers/tty/serial/8250_pci.c | 2
drivers/tty/serial/8250_pnp.c | 2
drivers/tty/serial/8250_rm9k.c | 95 ++++++++
drivers/tty/serial/Kconfig | 9 +
drivers/tty/serial/Makefile | 3
drivers/tty/serial/of_serial.c | 2
drivers/tty/serial/serial_cs.c | 2
include/linux/serial_8250.h | 36 ++-
include/linux/serial_core.h | 5
15 files changed, 579 insertions(+), 305 deletions(-)
create mode 100644 drivers/tty/serial/8250_au.c
create mode 100644 drivers/tty/serial/8250_dwapb.c
create mode 100644 drivers/tty/serial/8250_rm9k.c
--
Words without body bare winter barren trees much unspoken
^ permalink raw reply [flat|nested] 7+ messages in thread
* [RFC 1/5] 8250: Make serial_dl_write a port operation
2011-03-18 15:24 [RFC 0/5] Starting to pull out the I/O operations Alan Cox
@ 2011-03-18 15:24 ` Alan Cox
2011-03-18 15:25 ` [RFC 2/5] 8250: introduce the idea of an operations struct for an 8250 port Alan Cox
` (4 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Alan Cox @ 2011-03-18 15:24 UTC (permalink / raw)
To: linux-serial
From: Alan Cox <alan@linux.intel.com>
This is pre-requisite to splitting out some of the platform specific stuff
Signed-off-by: Alan Cox <alan@linux.intel.com>
---
drivers/tty/serial/8250.c | 122 +++++++++++++++++++++++++------------------
include/linux/serial_8250.h | 2 +
include/linux/serial_core.h | 2 +
3 files changed, 74 insertions(+), 52 deletions(-)
diff --git a/drivers/tty/serial/8250.c b/drivers/tty/serial/8250.c
index b3b881b..a8e43fd 100644
--- a/drivers/tty/serial/8250.c
+++ b/drivers/tty/serial/8250.c
@@ -503,10 +503,50 @@ static void io_serial_out(struct uart_port *p, int offset, int value)
outb(value, p->iobase + offset);
}
+/* Uart divisor latch read */
+static unsigned int _serial_dl_read(struct uart_port *p)
+{
+ return p->serial_in(p, UART_DLL) | p->serial_in(p, UART_DLM) << 8;
+}
+
+/* Uart divisor latch write */
+static void _serial_dl_write(struct uart_port *p, unsigned int value)
+{
+ p->serial_out(p, UART_DLL, value & 0xff);
+ p->serial_out(p, UART_DLM, value >> 8 & 0xff);
+}
+
+/* Au1x00 haven't got a standard divisor latch */
+static unsigned int au_serial_dl_read(struct uart_port *p)
+{
+ return __raw_readl(p->membase + 0x28);
+}
+
+static void au_serial_dl_write(struct uart_port *p, unsigned int value)
+{
+ __raw_writel(value, p->membase + 0x28);
+}
+
+static unsigned int rm9k_serial_dl_read(struct uart_port *p)
+{
+ return (((__raw_readl(p->membase + 0x10) << 8) |
+ (__raw_readl(p->membase + 0x08) & 0xff)) & 0xffff);
+}
+
+static void rm9k_serial_dl_write(struct uart_port *p, unsigned int value)
+{
+ __raw_writel(value, p->membase + 0x08);
+ __raw_writel(value >> 8, p->membase + 0x10);
+}
+
static void set_io_from_upio(struct uart_port *p)
{
struct uart_8250_port *up =
container_of(p, struct uart_8250_port, port);
+
+ p->serial_dl_read = _serial_dl_read;
+ p->serial_dl_write = _serial_dl_write;
+
switch (p->iotype) {
case UPIO_HUB6:
p->serial_in = hub6_serial_in;
@@ -519,6 +559,8 @@ static void set_io_from_upio(struct uart_port *p)
break;
case UPIO_RM9000:
+ p->serial_dl_read = rm9k_serial_dl_read;
+ p->serial_dl_write = rm9k_serial_dl_write;
case UPIO_MEM32:
p->serial_in = mem32_serial_in;
p->serial_out = mem32_serial_out;
@@ -527,6 +569,8 @@ static void set_io_from_upio(struct uart_port *p)
case UPIO_AU:
p->serial_in = au_serial_in;
p->serial_out = au_serial_out;
+ p->serial_dl_read = au_serial_dl_read;
+ p->serial_dl_write = au_serial_dl_write;
break;
case UPIO_TSI:
@@ -575,6 +619,17 @@ serial_out_sync(struct uart_8250_port *up, int offset, int value)
(up->port.serial_in(&(up)->port, (offset)))
#define serial_out(up, offset, value) \
(up->port.serial_out(&(up)->port, (offset), (value)))
+
+static unsigned int serial_dl_read(struct uart_8250_port *up)
+{
+ return up->port.serial_dl_read(&up->port);
+}
+
+static void serial_dl_write(struct uart_8250_port *up, unsigned int value)
+{
+ up->port.serial_dl_write(&up->port, value);
+}
+
/*
* We used to support using pause I/O for certain machines. We
* haven't supported this for a while, but just in case it's badly
@@ -584,58 +639,6 @@ serial_out_sync(struct uart_8250_port *up, int offset, int value)
#define serial_inp(up, offset) serial_in(up, offset)
#define serial_outp(up, offset, value) serial_out(up, offset, value)
-/* Uart divisor latch read */
-static inline int _serial_dl_read(struct uart_8250_port *up)
-{
- return serial_inp(up, UART_DLL) | serial_inp(up, UART_DLM) << 8;
-}
-
-/* Uart divisor latch write */
-static inline void _serial_dl_write(struct uart_8250_port *up, int value)
-{
- serial_outp(up, UART_DLL, value & 0xff);
- serial_outp(up, UART_DLM, value >> 8 & 0xff);
-}
-
-#if defined(CONFIG_MIPS_ALCHEMY)
-/* Au1x00 haven't got a standard divisor latch */
-static int serial_dl_read(struct uart_8250_port *up)
-{
- if (up->port.iotype == UPIO_AU)
- return __raw_readl(up->port.membase + 0x28);
- else
- return _serial_dl_read(up);
-}
-
-static void serial_dl_write(struct uart_8250_port *up, int value)
-{
- if (up->port.iotype == UPIO_AU)
- __raw_writel(value, up->port.membase + 0x28);
- else
- _serial_dl_write(up, value);
-}
-#elif defined(CONFIG_SERIAL_8250_RM9K)
-static int serial_dl_read(struct uart_8250_port *up)
-{
- return (up->port.iotype == UPIO_RM9000) ?
- (((__raw_readl(up->port.membase + 0x10) << 8) |
- (__raw_readl(up->port.membase + 0x08) & 0xff)) & 0xffff) :
- _serial_dl_read(up);
-}
-
-static void serial_dl_write(struct uart_8250_port *up, int value)
-{
- if (up->port.iotype == UPIO_RM9000) {
- __raw_writel(value, up->port.membase + 0x08);
- __raw_writel(value >> 8, up->port.membase + 0x10);
- } else {
- _serial_dl_write(up, value);
- }
-}
-#else
-#define serial_dl_read(up) _serial_dl_read(up)
-#define serial_dl_write(up, value) _serial_dl_write(up, value)
-#endif
/*
* For the 16C950
@@ -3008,10 +3011,15 @@ int __init early_serial_setup(struct uart_port *port)
p->line = port->line;
set_io_from_upio(p);
+
if (port->serial_in)
p->serial_in = port->serial_in;
if (port->serial_out)
p->serial_out = port->serial_out;
+ if (port->serial_dl_read)
+ p->serial_dl_read = port->serial_dl_read;
+ if (port->serial_dl_write)
+ p->serial_dl_write = port->serial_dl_write;
return 0;
}
@@ -3080,6 +3088,16 @@ static int __devinit serial8250_probe(struct platform_device *dev)
port.type = p->type;
port.serial_in = p->serial_in;
port.serial_out = p->serial_out;
+ port.serial_dl_read = p->serial_dl_read;
+ port.serial_dl_write = p->serial_dl_write;
+ /* Temporary to help people transferring */
+ if (port.serial_dl_read == NULL ||
+ port.serial_dl_write == NULL) {
+ dev_warn(&dev->dev,
+ "needs updating to set dl_read/write.\n");
+ port.serial_dl_read = _serial_dl_read;
+ port.serial_dl_write = _serial_dl_write;
+ }
port.set_termios = p->set_termios;
port.pm = p->pm;
port.dev = &dev->dev;
diff --git a/include/linux/serial_8250.h b/include/linux/serial_8250.h
index 97f5b45..9e42ff7 100644
--- a/include/linux/serial_8250.h
+++ b/include/linux/serial_8250.h
@@ -37,6 +37,8 @@ struct plat_serial8250_port {
struct ktermios *old);
void (*pm)(struct uart_port *, unsigned int state,
unsigned old);
+ unsigned int (*serial_dl_read)(struct uart_port *);
+ void (*serial_dl_write)(struct uart_port *, unsigned int);
};
/*
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
index 758c5b0..f47f95c 100644
--- a/include/linux/serial_core.h
+++ b/include/linux/serial_core.h
@@ -291,6 +291,8 @@ struct uart_port {
spinlock_t lock; /* port lock */
unsigned long iobase; /* in/out[bwl] */
unsigned char __iomem *membase; /* read/write[bwl] */
+ unsigned int (*serial_dl_read)(struct uart_port *);
+ void (*serial_dl_write)(struct uart_port *, unsigned int);
unsigned int (*serial_in)(struct uart_port *, int);
void (*serial_out)(struct uart_port *, int, int);
void (*set_termios)(struct uart_port *,
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [RFC 2/5] 8250: introduce the idea of an operations struct for an 8250 port
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 ` Alan Cox
2011-03-18 15:25 ` [RFC 3/5] 8250: register upio users Alan Cox
` (3 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Alan Cox @ 2011-03-18 15:25 UTC (permalink / raw)
To: linux-serial
From: Alan Cox <alan@linux.intel.com>
We can then round up all the port specific bits and push them into the
drivers or standard library code where they belong. This will need all the
embedded driver people to tweak their board code - sorry but there's not a
nice way to do this. Once it is done however then it should be easy to keep
sane as we can add new ops for new hardware insanity without disturbance.
Signed-off-by: Alan Cox <alan@linux.intel.com>
---
drivers/char/mwave/mwavedd.c | 2
drivers/tty/serial/8250.c | 230 +++++++++++++++++++++++-----------------
drivers/tty/serial/8250_pci.c | 2
drivers/tty/serial/8250_pnp.c | 2
drivers/tty/serial/of_serial.c | 2
drivers/tty/serial/serial_cs.c | 2
include/linux/serial_8250.h | 34 ++++--
include/linux/serial_core.h | 3 +
8 files changed, 165 insertions(+), 112 deletions(-)
diff --git a/drivers/char/mwave/mwavedd.c b/drivers/char/mwave/mwavedd.c
index 1d82d58..4bbe677 100644
--- a/drivers/char/mwave/mwavedd.c
+++ b/drivers/char/mwave/mwavedd.c
@@ -469,7 +469,7 @@ static int register_serial_portandirq(unsigned int port, int irq)
uart.irq = irq;
uart.iotype = UPIO_PORT;
uart.flags = UPF_SHARE_IRQ;
- return serial8250_register_port(&uart);
+ return serial8250_register_port(&uart, NULL);
}
diff --git a/drivers/tty/serial/8250.c b/drivers/tty/serial/8250.c
index a8e43fd..c3e56a7 100644
--- a/drivers/tty/serial/8250.c
+++ b/drivers/tty/serial/8250.c
@@ -133,6 +133,7 @@ static unsigned int probe_rsa_count;
struct uart_8250_port {
struct uart_port port;
+ const struct serial8250_ops *ops; /* I/O access methods */
struct timer_list timer; /* "no irq" timer */
struct list_head list; /* ports on this IRQ */
unsigned short capabilities; /* port capabilities */
@@ -387,6 +388,25 @@ static inline int map_8250_out_reg(struct uart_port *p, int offset)
#endif
+/* Uart divisor latch read */
+static unsigned int std_serial_dl_read(struct uart_port *p)
+{
+ struct uart_8250_port *up =
+ container_of(p, struct uart_8250_port, port);
+ return up->ops->serial_in(p, UART_DLL) |
+ up->ops->serial_in(p, UART_DLM) << 8;
+}
+
+/* Uart divisor latch write */
+static void std_serial_dl_write(struct uart_port *p, unsigned int value)
+{
+ struct uart_8250_port *up =
+ container_of(p, struct uart_8250_port, port);
+ up->ops->serial_out(p, UART_DLL, value & 0xff);
+ up->ops->serial_out(p, UART_DLM, value >> 8 & 0xff);
+}
+
+
static unsigned int hub6_serial_in(struct uart_port *p, int offset)
{
offset = map_8250_in_reg(p, offset) << p->regshift;
@@ -401,6 +421,13 @@ static void hub6_serial_out(struct uart_port *p, int offset, int value)
outb(value, p->iobase + 1);
}
+static const struct serial8250_ops hub6_ops = {
+ .serial_in = hub6_serial_in,
+ .serial_out = hub6_serial_out,
+ .serial_dl_read = std_serial_dl_read,
+ .serial_dl_write = std_serial_dl_write
+};
+
static unsigned int mem_serial_in(struct uart_port *p, int offset)
{
offset = map_8250_in_reg(p, offset) << p->regshift;
@@ -413,6 +440,13 @@ static void mem_serial_out(struct uart_port *p, int offset, int value)
writeb(value, p->membase + offset);
}
+static const struct serial8250_ops mem_ops = {
+ .serial_in = mem_serial_in,
+ .serial_out = mem_serial_out,
+ .serial_dl_read = std_serial_dl_read,
+ .serial_dl_write = std_serial_dl_write
+};
+
static void mem32_serial_out(struct uart_port *p, int offset, int value)
{
offset = map_8250_out_reg(p, offset) << p->regshift;
@@ -425,17 +459,12 @@ static unsigned int mem32_serial_in(struct uart_port *p, int offset)
return readl(p->membase + offset);
}
-static unsigned int au_serial_in(struct uart_port *p, int offset)
-{
- offset = map_8250_in_reg(p, offset) << p->regshift;
- return __raw_readl(p->membase + offset);
-}
-
-static void au_serial_out(struct uart_port *p, int offset, int value)
-{
- offset = map_8250_out_reg(p, offset) << p->regshift;
- __raw_writel(value, p->membase + offset);
-}
+static const struct serial8250_ops mem32_ops = {
+ .serial_in = mem32_serial_in,
+ .serial_out = mem32_serial_out,
+ .serial_dl_read = std_serial_dl_read,
+ .serial_dl_write = std_serial_dl_write
+};
static unsigned int tsi_serial_in(struct uart_port *p, int offset)
{
@@ -455,6 +484,13 @@ static void tsi_serial_out(struct uart_port *p, int offset, int value)
writeb(value, p->membase + offset);
}
+static const struct serial8250_ops tsi_ops = {
+ .serial_in = tsi_serial_in,
+ .serial_out = tsi_serial_out,
+ .serial_dl_read = std_serial_dl_read,
+ .serial_dl_write = std_serial_dl_write
+};
+
/* Save the LCR value so it can be re-written when a Busy Detect IRQ occurs. */
static inline void dwapb_save_out_value(struct uart_port *p, int offset,
int value)
@@ -469,8 +505,10 @@ static inline void dwapb_save_out_value(struct uart_port *p, int offset,
/* Read the IER to ensure any interrupt is cleared before returning from ISR. */
static inline void dwapb_check_clear_ier(struct uart_port *p, int offset)
{
+ struct uart_8250_port *up =
+ container_of(p, struct uart_8250_port, port);
if (offset == UART_TX || offset == UART_IER)
- p->serial_in(p, UART_IER);
+ up->ops->serial_in(p, UART_IER);
}
static void dwapb_serial_out(struct uart_port *p, int offset, int value)
@@ -482,6 +520,13 @@ static void dwapb_serial_out(struct uart_port *p, int offset, int value)
dwapb_check_clear_ier(p, save_offset);
}
+static const struct serial8250_ops dwapb_ops = {
+ .serial_in = mem_serial_in,
+ .serial_out = dwapb_serial_out,
+ .serial_dl_read = std_serial_dl_read,
+ .serial_dl_write = std_serial_dl_write
+};
+
static void dwapb32_serial_out(struct uart_port *p, int offset, int value)
{
int save_offset = offset;
@@ -491,6 +536,13 @@ static void dwapb32_serial_out(struct uart_port *p, int offset, int value)
dwapb_check_clear_ier(p, save_offset);
}
+static const struct serial8250_ops dwapb32_ops = {
+ .serial_in = mem32_serial_in,
+ .serial_out = dwapb32_serial_out,
+ .serial_dl_read = std_serial_dl_read,
+ .serial_dl_write = std_serial_dl_write
+};
+
static unsigned int io_serial_in(struct uart_port *p, int offset)
{
offset = map_8250_in_reg(p, offset) << p->regshift;
@@ -503,17 +555,24 @@ static void io_serial_out(struct uart_port *p, int offset, int value)
outb(value, p->iobase + offset);
}
-/* Uart divisor latch read */
-static unsigned int _serial_dl_read(struct uart_port *p)
+
+static const struct serial8250_ops pio_ops = {
+ .serial_in = io_serial_in,
+ .serial_out = io_serial_out,
+ .serial_dl_read = std_serial_dl_read,
+ .serial_dl_write = std_serial_dl_write
+};
+
+static unsigned int au_serial_in(struct uart_port *p, int offset)
{
- return p->serial_in(p, UART_DLL) | p->serial_in(p, UART_DLM) << 8;
+ offset = map_8250_in_reg(p, offset) << p->regshift;
+ return __raw_readl(p->membase + offset);
}
-/* Uart divisor latch write */
-static void _serial_dl_write(struct uart_port *p, unsigned int value)
+static void au_serial_out(struct uart_port *p, int offset, int value)
{
- p->serial_out(p, UART_DLL, value & 0xff);
- p->serial_out(p, UART_DLM, value >> 8 & 0xff);
+ offset = map_8250_out_reg(p, offset) << p->regshift;
+ __raw_writel(value, p->membase + offset);
}
/* Au1x00 haven't got a standard divisor latch */
@@ -527,6 +586,13 @@ static void au_serial_dl_write(struct uart_port *p, unsigned int value)
__raw_writel(value, p->membase + 0x28);
}
+static const struct serial8250_ops au_ops = {
+ .serial_in = au_serial_in,
+ .serial_out = au_serial_out,
+ .serial_dl_read = au_serial_dl_read,
+ .serial_dl_write = au_serial_dl_write
+};
+
static unsigned int rm9k_serial_dl_read(struct uart_port *p)
{
return (((__raw_readl(p->membase + 0x10) << 8) |
@@ -539,58 +605,47 @@ static void rm9k_serial_dl_write(struct uart_port *p, unsigned int value)
__raw_writel(value >> 8, p->membase + 0x10);
}
+static const struct serial8250_ops rm9k_ops = {
+ .serial_in = mem32_serial_in,
+ .serial_out = mem32_serial_out,
+ .serial_dl_read = rm9k_serial_dl_read,
+ .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 void set_io_from_upio(struct uart_port *p)
{
struct uart_8250_port *up =
container_of(p, struct uart_8250_port, port);
- p->serial_dl_read = _serial_dl_read;
- p->serial_dl_write = _serial_dl_write;
-
switch (p->iotype) {
case UPIO_HUB6:
- p->serial_in = hub6_serial_in;
- p->serial_out = hub6_serial_out;
+ up->ops = &hub6_ops;
break;
-
case UPIO_MEM:
- p->serial_in = mem_serial_in;
- p->serial_out = mem_serial_out;
+ up->ops = &mem_ops;
break;
-
case UPIO_RM9000:
- p->serial_dl_read = rm9k_serial_dl_read;
- p->serial_dl_write = rm9k_serial_dl_write;
+ up->ops = &rm9k_ops;
+ break;
case UPIO_MEM32:
- p->serial_in = mem32_serial_in;
- p->serial_out = mem32_serial_out;
+ up->ops = &mem32_ops;
break;
-
case UPIO_AU:
- p->serial_in = au_serial_in;
- p->serial_out = au_serial_out;
- p->serial_dl_read = au_serial_dl_read;
- p->serial_dl_write = au_serial_dl_write;
+ up->ops = &au_ops;
break;
-
case UPIO_TSI:
- p->serial_in = tsi_serial_in;
- p->serial_out = tsi_serial_out;
+ up->ops = &tsi_ops;
break;
-
case UPIO_DWAPB:
- p->serial_in = mem_serial_in;
- p->serial_out = dwapb_serial_out;
+ up->ops = &dwapb_ops;
break;
-
case UPIO_DWAPB32:
- p->serial_in = mem32_serial_in;
- p->serial_out = dwapb32_serial_out;
+ up->ops = &dwapb32_ops;
break;
-
default:
- p->serial_in = io_serial_in;
- p->serial_out = io_serial_out;
+ up->ops = &pio_ops;
break;
}
/* Remember loaded iotype */
@@ -607,27 +662,27 @@ serial_out_sync(struct uart_8250_port *up, int offset, int value)
case UPIO_AU:
case UPIO_DWAPB:
case UPIO_DWAPB32:
- p->serial_out(p, offset, value);
- p->serial_in(p, UART_LCR); /* safe, no side-effects */
+ up->ops->serial_out(p, offset, value);
+ up->ops->serial_in(p, UART_LCR); /* safe, no side-effects */
break;
default:
- p->serial_out(p, offset, value);
+ up->ops->serial_out(p, offset, value);
}
}
#define serial_in(up, offset) \
- (up->port.serial_in(&(up)->port, (offset)))
+ (up->ops->serial_in(&(up)->port, (offset)))
#define serial_out(up, offset, value) \
- (up->port.serial_out(&(up)->port, (offset), (value)))
+ (up->ops->serial_out(&(up)->port, (offset), (value)))
static unsigned int serial_dl_read(struct uart_8250_port *up)
{
- return up->port.serial_dl_read(&up->port);
+ return up->ops->serial_dl_read(&up->port);
}
static void serial_dl_write(struct uart_8250_port *up, unsigned int value)
{
- up->port.serial_dl_write(&up->port, value);
+ up->ops->serial_dl_write(&up->port, value);
}
/*
@@ -2474,8 +2529,10 @@ static void
serial8250_set_termios(struct uart_port *port, struct ktermios *termios,
struct ktermios *old)
{
- if (port->set_termios)
- port->set_termios(port, termios, old);
+ struct uart_8250_port *up =
+ container_of(port, struct uart_8250_port, port);
+ if (up->ops->set_termios)
+ up->ops->set_termios(port, termios, old);
else
serial8250_do_set_termios(port, termios, old);
}
@@ -2505,8 +2562,11 @@ static void
serial8250_pm(struct uart_port *port, unsigned int state,
unsigned int oldstate)
{
- if (port->pm)
- port->pm(port, state, oldstate);
+ struct uart_8250_port *up =
+ container_of(port, struct uart_8250_port, port);
+
+ if (up->ops->pm)
+ up->ops->pm(port, state, oldstate);
else
serial8250_do_pm(port, state, oldstate);
}
@@ -2982,20 +3042,24 @@ static struct uart_driver serial8250_reg = {
};
/*
- * early_serial_setup - early registration for 8250 ports
+ * serial8250_early_setup - early registration for 8250 ports
*
* Setup an 8250 port structure prior to console initialisation. Use
* after console initialisation will cause undefined behaviour.
*/
-int __init early_serial_setup(struct uart_port *port)
+int __init serial8250_early_setup(struct uart_port *port, struct serial8250_ops *ops)
{
struct uart_port *p;
+ struct uart_8250_port *up;
if (port->line >= ARRAY_SIZE(serial8250_ports))
return -ENODEV;
serial8250_isa_init_ports();
+
p = &serial8250_ports[port->line].port;
+ up = container_of(p, struct uart_8250_port, port);
+
p->iobase = port->iobase;
p->membase = port->membase;
p->irq = port->irq;
@@ -3012,14 +3076,8 @@ int __init early_serial_setup(struct uart_port *port)
set_io_from_upio(p);
- if (port->serial_in)
- p->serial_in = port->serial_in;
- if (port->serial_out)
- p->serial_out = port->serial_out;
- if (port->serial_dl_read)
- p->serial_dl_read = port->serial_dl_read;
- if (port->serial_dl_write)
- p->serial_dl_write = port->serial_dl_write;
+ if (ops)
+ up->ops = ops;
return 0;
}
@@ -3086,23 +3144,9 @@ static int __devinit serial8250_probe(struct platform_device *dev)
port.hub6 = p->hub6;
port.private_data = p->private_data;
port.type = p->type;
- port.serial_in = p->serial_in;
- port.serial_out = p->serial_out;
- port.serial_dl_read = p->serial_dl_read;
- port.serial_dl_write = p->serial_dl_write;
- /* Temporary to help people transferring */
- if (port.serial_dl_read == NULL ||
- port.serial_dl_write == NULL) {
- dev_warn(&dev->dev,
- "needs updating to set dl_read/write.\n");
- port.serial_dl_read = _serial_dl_read;
- port.serial_dl_write = _serial_dl_write;
- }
- port.set_termios = p->set_termios;
- port.pm = p->pm;
port.dev = &dev->dev;
port.irqflags |= irqflag;
- ret = serial8250_register_port(&port);
+ ret = serial8250_register_port(&port, p->ops);
if (ret < 0) {
dev_err(&dev->dev, "unable to register port at index %d "
"(IO%lx MEM%llx IRQ%d): %d\n", i,
@@ -3216,6 +3260,7 @@ static struct uart_8250_port *serial8250_find_match_or_unused(struct uart_port *
/**
* serial8250_register_port - register a serial port
* @port: serial port template
+ * @ops: optional I/O operations and low level ops to use
*
* Configure the serial port specified by the request. If the
* port exists and is in use, it is hung up and unregistered
@@ -3226,7 +3271,8 @@ static struct uart_8250_port *serial8250_find_match_or_unused(struct uart_port *
*
* On success the port is ready to use and the line number is returned.
*/
-int serial8250_register_port(struct uart_port *port)
+int serial8250_register_port(struct uart_port *port,
+ const struct serial8250_ops *ops)
{
struct uart_8250_port *uart;
int ret = -ENOSPC;
@@ -3258,16 +3304,8 @@ int serial8250_register_port(struct uart_port *port)
serial8250_init_fixed_type_port(uart, port->type);
set_io_from_upio(&uart->port);
- /* Possibly override default I/O functions. */
- if (port->serial_in)
- uart->port.serial_in = port->serial_in;
- if (port->serial_out)
- uart->port.serial_out = port->serial_out;
- /* Possibly override set_termios call */
- if (port->set_termios)
- uart->port.set_termios = port->set_termios;
- if (port->pm)
- uart->port.pm = port->pm;
+ if (ops)
+ uart->port.ops = ops;
if (serial8250_isa_config != NULL)
serial8250_isa_config(0, &uart->port,
diff --git a/drivers/tty/serial/8250_pci.c b/drivers/tty/serial/8250_pci.c
index 8b8930f..851e9a6 100644
--- a/drivers/tty/serial/8250_pci.c
+++ b/drivers/tty/serial/8250_pci.c
@@ -2473,7 +2473,7 @@ pciserial_init_ports(struct pci_dev *dev, const struct pciserial_board *board)
serial_port.iobase, serial_port.irq, serial_port.iotype);
#endif
- priv->line[i] = serial8250_register_port(&serial_port);
+ priv->line[i] = serial8250_register_port(&serial_port, NULL);
if (priv->line[i] < 0) {
printk(KERN_WARNING "Couldn't register serial port %s: %d\n", pci_name(dev), priv->line[i]);
break;
diff --git a/drivers/tty/serial/8250_pnp.c b/drivers/tty/serial/8250_pnp.c
index 4822cb5..95126e2 100644
--- a/drivers/tty/serial/8250_pnp.c
+++ b/drivers/tty/serial/8250_pnp.c
@@ -457,7 +457,7 @@ serial_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id)
port.uartclk = 1843200;
port.dev = &dev->dev;
- line = serial8250_register_port(&port);
+ line = serial8250_register_port(&port, NULL);
if (line < 0)
return -ENODEV;
diff --git a/drivers/tty/serial/of_serial.c b/drivers/tty/serial/of_serial.c
index 0e8eec5..2b834e9 100644
--- a/drivers/tty/serial/of_serial.c
+++ b/drivers/tty/serial/of_serial.c
@@ -105,7 +105,7 @@ static int __devinit of_platform_serial_probe(struct platform_device *ofdev)
switch (port_type) {
#ifdef CONFIG_SERIAL_8250
case PORT_8250 ... PORT_MAX_8250:
- ret = serial8250_register_port(&port);
+ ret = serial8250_register_port(&port, NULL);
break;
#endif
#ifdef CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL
diff --git a/drivers/tty/serial/serial_cs.c b/drivers/tty/serial/serial_cs.c
index 1ef4df9..fc3b441 100644
--- a/drivers/tty/serial/serial_cs.c
+++ b/drivers/tty/serial/serial_cs.c
@@ -359,7 +359,7 @@ static int setup_serial(struct pcmcia_device *handle, struct serial_info * info,
if (info->quirk && info->quirk->setup)
info->quirk->setup(handle, &port);
- line = serial8250_register_port(&port);
+ line = serial8250_register_port(&port, NULL);
if (line < 0) {
printk(KERN_NOTICE "serial_cs: serial8250_register_port() at "
"0x%04lx, irq %d failed\n", (u_long)iobase, irq);
diff --git a/include/linux/serial_8250.h b/include/linux/serial_8250.h
index 9e42ff7..15806bb 100644
--- a/include/linux/serial_8250.h
+++ b/include/linux/serial_8250.h
@@ -14,6 +14,18 @@
#include <linux/serial_core.h>
#include <linux/platform_device.h>
+struct serial8250_ops {
+ unsigned int (*serial_in)(struct uart_port *, int);
+ void (*serial_out)(struct uart_port *, int, int);
+ void (*set_termios)(struct uart_port *,
+ struct ktermios *new,
+ struct ktermios *old);
+ void (*pm)(struct uart_port *, unsigned int state,
+ unsigned old);
+ unsigned int (*serial_dl_read)(struct uart_port *);
+ void (*serial_dl_write)(struct uart_port *, unsigned int);
+};
+
/*
* This is the platform device platform_data structure
*/
@@ -30,15 +42,8 @@ struct plat_serial8250_port {
unsigned char hub6;
upf_t flags; /* UPF_* flags */
unsigned int type; /* If UPF_FIXED_TYPE */
- unsigned int (*serial_in)(struct uart_port *, int);
- void (*serial_out)(struct uart_port *, int, int);
- void (*set_termios)(struct uart_port *,
- struct ktermios *new,
- struct ktermios *old);
- void (*pm)(struct uart_port *, unsigned int state,
- unsigned old);
- unsigned int (*serial_dl_read)(struct uart_port *);
- void (*serial_dl_write)(struct uart_port *, unsigned int);
+ struct serial8250_ops *ops; /* Optional ops (UPIO defaults are
+ applied otherwise */
};
/*
@@ -68,13 +73,14 @@ enum {
*/
struct uart_port;
-int serial8250_register_port(struct uart_port *);
+int serial8250_register_port(struct uart_port *, const struct serial8250_ops *ops);
void serial8250_unregister_port(int line);
void serial8250_suspend_port(int line);
void serial8250_resume_port(int line);
-extern int early_serial_setup(struct uart_port *port);
+extern int serial8250_early_setup(struct uart_port *port,
+ struct serial8250_ops *ops);
extern int serial8250_find_port(struct uart_port *p);
extern int serial8250_find_port_for_earlycon(void);
extern int setup_early_serial8250_console(char *cmdline);
@@ -87,4 +93,10 @@ extern void serial8250_set_isa_configurator(void (*v)
(int port, struct uart_port *up,
unsigned short *capabilities));
+
+static inline int __deprecated early_serial_setup(struct uart_port *port)
+{
+ return serial8250_early_setup(port, NULL);
+}
+
#endif
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
index f47f95c..84e0b01 100644
--- a/include/linux/serial_core.h
+++ b/include/linux/serial_core.h
@@ -291,10 +291,12 @@ struct uart_port {
spinlock_t lock; /* port lock */
unsigned long iobase; /* in/out[bwl] */
unsigned char __iomem *membase; /* read/write[bwl] */
+#if 0
unsigned int (*serial_dl_read)(struct uart_port *);
void (*serial_dl_write)(struct uart_port *, unsigned int);
unsigned int (*serial_in)(struct uart_port *, int);
void (*serial_out)(struct uart_port *, int, int);
+#endif
void (*set_termios)(struct uart_port *,
struct ktermios *new,
struct ktermios *old);
@@ -318,6 +320,7 @@ struct uart_port {
#define UPIO_DWAPB (6) /* DesignWare APB UART */
#define UPIO_RM9000 (7) /* RM9000 type IO */
#define UPIO_DWAPB32 (8) /* DesignWare APB UART (32 bit accesses) */
+#define UPIO_MAX (8)
unsigned int read_status_mask; /* driver specific */
unsigned int ignore_status_mask; /* driver specific */
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [RFC 3/5] 8250: register upio users
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
2011-03-18 15:25 ` [RFC 4/5] 8250: evict the hub6 I/O operations Alan Cox
` (2 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Alan Cox @ 2011-03-18 15:25 UTC (permalink / raw)
To: linux-serial
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
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [RFC 4/5] 8250: evict the hub6 I/O operations
2011-03-18 15:24 [RFC 0/5] Starting to pull out the I/O operations Alan Cox
` (2 preceding siblings ...)
2011-03-18 15:25 ` [RFC 3/5] 8250: register upio users Alan Cox
@ 2011-03-18 15:25 ` 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
5 siblings, 0 replies; 7+ messages in thread
From: Alan Cox @ 2011-03-18 15:25 UTC (permalink / raw)
To: linux-serial
From: Alan Cox <alan@linux.intel.com>
This is a test to see how the split looks when we do this, there is other
hub6 code buried in the core because of the way the 8250 and serial core
manage resources. That needs addressing.
Signed-off-by: Alan Cox <alan@linux.intel.com>
---
drivers/tty/serial/8250.c | 52 ++--------------------------------------
drivers/tty/serial/8250.h | 27 +++++++++++++++++++++
drivers/tty/serial/8250_hub6.c | 39 ++++++++++++++++++++++++++++++
include/linux/serial_8250.h | 2 +-
4 files changed, 69 insertions(+), 51 deletions(-)
diff --git a/drivers/tty/serial/8250.c b/drivers/tty/serial/8250.c
index 89a00d1..a5867da 100644
--- a/drivers/tty/serial/8250.c
+++ b/drivers/tty/serial/8250.c
@@ -131,32 +131,6 @@ static unsigned long probe_rsa[PORT_RSA_MAX];
static unsigned int probe_rsa_count;
#endif /* CONFIG_SERIAL_8250_RSA */
-struct uart_8250_port {
- struct uart_port port;
- const struct serial8250_ops *ops; /* I/O access methods */
- struct timer_list timer; /* "no irq" timer */
- struct list_head list; /* ports on this IRQ */
- unsigned short capabilities; /* port capabilities */
- unsigned short bugs; /* port bugs */
- unsigned int tx_loadsz; /* transmit fifo load size */
- unsigned char acr;
- unsigned char ier;
- unsigned char lcr;
- unsigned char mcr;
- unsigned char mcr_mask; /* mask of user bits */
- unsigned char mcr_force; /* mask of forced bits */
- unsigned char cur_iotype; /* Running I/O type */
-
- /*
- * Some bits in registers are cleared on a read, so they must
- * be saved whenever the register is read but the bits will not
- * be immediately processed.
- */
-#define LSR_SAVE_FLAGS UART_LSR_BRK_ERROR_BITS
- unsigned char lsr_saved_flags;
-#define MSR_SAVE_FLAGS UART_MSR_ANY_DELTA
- unsigned char msr_saved_flags;
-};
struct irq_info {
struct hlist_node node;
@@ -406,28 +380,6 @@ static void std_serial_dl_write(struct uart_port *p, unsigned int value)
up->ops->serial_out(p, UART_DLM, value >> 8 & 0xff);
}
-
-static unsigned int hub6_serial_in(struct uart_port *p, int offset)
-{
- offset = map_8250_in_reg(p, offset) << p->regshift;
- outb(p->hub6 - 1 + offset, p->iobase);
- return inb(p->iobase + 1);
-}
-
-static void hub6_serial_out(struct uart_port *p, int offset, int value)
-{
- offset = map_8250_out_reg(p, offset) << p->regshift;
- outb(p->hub6 - 1 + offset, p->iobase);
- outb(value, p->iobase + 1);
-}
-
-static const struct serial8250_ops hub6_ops = {
- .serial_in = hub6_serial_in,
- .serial_out = hub6_serial_out,
- .serial_dl_read = std_serial_dl_read,
- .serial_dl_write = std_serial_dl_write
-};
-
static unsigned int mem_serial_in(struct uart_port *p, int offset)
{
offset = map_8250_in_reg(p, offset) << p->regshift;
@@ -616,7 +568,7 @@ static const struct serial8250_ops rm9k_ops = {
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 */
+ NULL, /* UPIO_HUB6 */
&mem_ops, /* UPIO_MEM */
&mem32_ops, /* UPIO_MEM32 */
&au_ops, /* UPIO_AU */
@@ -664,7 +616,7 @@ static void set_io_from_upio(struct uart_port *p)
* specific reasons new drivers should pass an ops structure directly
* instead.
*/
-int serial8250_upio_register(int upio, struct serial8250_ops *ops)
+int serial8250_upio_register(int upio, const struct serial8250_ops *ops)
{
int ret = 0;
mutex_lock(&upio_mutex);
diff --git a/drivers/tty/serial/8250.h b/drivers/tty/serial/8250.h
index 6e19ea3..3b3c282 100644
--- a/drivers/tty/serial/8250.h
+++ b/drivers/tty/serial/8250.h
@@ -28,6 +28,33 @@ struct old_serial_port {
unsigned long irqflags;
};
+struct uart_8250_port {
+ struct uart_port port;
+ const struct serial8250_ops *ops; /* I/O access methods */
+ struct timer_list timer; /* "no irq" timer */
+ struct list_head list; /* ports on this IRQ */
+ unsigned short capabilities; /* port capabilities */
+ unsigned short bugs; /* port bugs */
+ unsigned int tx_loadsz; /* transmit fifo load size */
+ unsigned char acr;
+ unsigned char ier;
+ unsigned char lcr;
+ unsigned char mcr;
+ unsigned char mcr_mask; /* mask of user bits */
+ unsigned char mcr_force; /* mask of forced bits */
+ unsigned char cur_iotype; /* Running I/O type */
+
+ /*
+ * Some bits in registers are cleared on a read, so they must
+ * be saved whenever the register is read but the bits will not
+ * be immediately processed.
+ */
+#define LSR_SAVE_FLAGS UART_LSR_BRK_ERROR_BITS
+ unsigned char lsr_saved_flags;
+#define MSR_SAVE_FLAGS UART_MSR_ANY_DELTA
+ unsigned char msr_saved_flags;
+};
+
/*
* This replaces serial_uart_config in include/linux/serial.h
*/
diff --git a/drivers/tty/serial/8250_hub6.c b/drivers/tty/serial/8250_hub6.c
index 7609150..4f34201 100644
--- a/drivers/tty/serial/8250_hub6.c
+++ b/drivers/tty/serial/8250_hub6.c
@@ -11,6 +11,8 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/serial_8250.h>
+#include <linux/serial_reg.h>
+#include "8250.h"
#define HUB6(card,port) \
{ \
@@ -38,6 +40,42 @@ static struct plat_serial8250_port hub6_data[] = {
{ },
};
+
+static unsigned int hub6_serial_in(struct uart_port *p, int offset)
+{
+ outb(p->hub6 - 1 + offset, p->iobase);
+ return inb(p->iobase + 1);
+}
+
+static void hub6_serial_out(struct uart_port *p, int offset, int value)
+{
+ outb(p->hub6 - 1 + offset, p->iobase);
+ outb(value, p->iobase + 1);
+}
+
+/* Uart divisor latch read */
+static unsigned hub6_serial_dl_read(struct uart_port *p)
+{
+ return hub6_serial_in(p, UART_DLL) |
+ hub6_serial_in(p, UART_DLM) << 8;
+}
+
+/* Uart divisor latch write */
+static void hub6_serial_dl_write(struct uart_port *p, unsigned int value)
+{
+ hub6_serial_out(p, UART_DLL, value & 0xff);
+ hub6_serial_out(p, UART_DLM, value >> 8 & 0xff);
+}
+
+static const struct serial8250_ops hub6_ops = {
+ .owner = THIS_MODULE,
+
+ .serial_in = hub6_serial_in,
+ .serial_out = hub6_serial_out,
+ .serial_dl_read = hub6_serial_dl_read,
+ .serial_dl_write = hub6_serial_dl_write
+};
+
static struct platform_device hub6_device = {
.name = "serial8250",
.id = PLAT8250_DEV_HUB6,
@@ -48,6 +86,7 @@ static struct platform_device hub6_device = {
static int __init hub6_init(void)
{
+ serial8250_upio_register(UPIO_HUB6, &hub6_ops);
return platform_device_register(&hub6_device);
}
diff --git a/include/linux/serial_8250.h b/include/linux/serial_8250.h
index 30d4f62..e36495e 100644
--- a/include/linux/serial_8250.h
+++ b/include/linux/serial_8250.h
@@ -100,7 +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_register(int upio, const struct serial8250_ops *ops);
extern int serial8250_upio_unregister(int upio);
#endif
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [RFC 5/5] 8250: extract out the "odd" port types
2011-03-18 15:24 [RFC 0/5] Starting to pull out the I/O operations Alan Cox
` (3 preceding siblings ...)
2011-03-18 15:25 ` [RFC 4/5] 8250: evict the hub6 I/O operations Alan Cox
@ 2011-03-18 15:26 ` Alan Cox
2011-03-18 20:04 ` [RFC 0/5] Starting to pull out the I/O operations Greg KH
5 siblings, 0 replies; 7+ messages in thread
From: Alan Cox @ 2011-03-18 15:26 UTC (permalink / raw)
To: linux-serial
From: Alan Cox <alan@linux.intel.com>
Possibly these want to end up in arch code but for the moment make them
little separate files in the serial layer
Signed-off-by: Alan Cox <alan@linux.intel.com>
---
drivers/tty/serial/8250.c | 207 ++-------------------------------------
drivers/tty/serial/8250_au.c | 90 +++++++++++++++++
drivers/tty/serial/8250_dwapb.c | 120 +++++++++++++++++++++++
drivers/tty/serial/8250_rm9k.c | 95 ++++++++++++++++++
drivers/tty/serial/Kconfig | 9 ++
drivers/tty/serial/Makefile | 3 +
6 files changed, 329 insertions(+), 195 deletions(-)
create mode 100644 drivers/tty/serial/8250_au.c
create mode 100644 drivers/tty/serial/8250_dwapb.c
create mode 100644 drivers/tty/serial/8250_rm9k.c
diff --git a/drivers/tty/serial/8250.c b/drivers/tty/serial/8250.c
index a5867da..21cfa66 100644
--- a/drivers/tty/serial/8250.c
+++ b/drivers/tty/serial/8250.c
@@ -280,88 +280,6 @@ static const struct serial8250_config uart_config[] = {
},
};
-#if defined(CONFIG_MIPS_ALCHEMY)
-
-/* Au1x00 UART hardware has a weird register layout */
-static const u8 au_io_in_map[] = {
- [UART_RX] = 0,
- [UART_IER] = 2,
- [UART_IIR] = 3,
- [UART_LCR] = 5,
- [UART_MCR] = 6,
- [UART_LSR] = 7,
- [UART_MSR] = 8,
-};
-
-static const u8 au_io_out_map[] = {
- [UART_TX] = 1,
- [UART_IER] = 2,
- [UART_FCR] = 4,
- [UART_LCR] = 5,
- [UART_MCR] = 6,
-};
-
-/* sane hardware needs no mapping */
-static inline int map_8250_in_reg(struct uart_port *p, int offset)
-{
- if (p->iotype != UPIO_AU)
- return offset;
- return au_io_in_map[offset];
-}
-
-static inline int map_8250_out_reg(struct uart_port *p, int offset)
-{
- if (p->iotype != UPIO_AU)
- return offset;
- return au_io_out_map[offset];
-}
-
-#elif defined(CONFIG_SERIAL_8250_RM9K)
-
-static const u8
- regmap_in[8] = {
- [UART_RX] = 0x00,
- [UART_IER] = 0x0c,
- [UART_IIR] = 0x14,
- [UART_LCR] = 0x1c,
- [UART_MCR] = 0x20,
- [UART_LSR] = 0x24,
- [UART_MSR] = 0x28,
- [UART_SCR] = 0x2c
- },
- regmap_out[8] = {
- [UART_TX] = 0x04,
- [UART_IER] = 0x0c,
- [UART_FCR] = 0x18,
- [UART_LCR] = 0x1c,
- [UART_MCR] = 0x20,
- [UART_LSR] = 0x24,
- [UART_MSR] = 0x28,
- [UART_SCR] = 0x2c
- };
-
-static inline int map_8250_in_reg(struct uart_port *p, int offset)
-{
- if (p->iotype != UPIO_RM9000)
- return offset;
- return regmap_in[offset];
-}
-
-static inline int map_8250_out_reg(struct uart_port *p, int offset)
-{
- if (p->iotype != UPIO_RM9000)
- return offset;
- return regmap_out[offset];
-}
-
-#else
-
-/* sane hardware needs no mapping */
-#define map_8250_in_reg(up, offset) (offset)
-#define map_8250_out_reg(up, offset) (offset)
-
-#endif
-
/* Uart divisor latch read */
static unsigned int std_serial_dl_read(struct uart_port *p)
{
@@ -382,13 +300,13 @@ static void std_serial_dl_write(struct uart_port *p, unsigned int value)
static unsigned int mem_serial_in(struct uart_port *p, int offset)
{
- offset = map_8250_in_reg(p, offset) << p->regshift;
+ offset <<= p->regshift;
return readb(p->membase + offset);
}
static void mem_serial_out(struct uart_port *p, int offset, int value)
{
- offset = map_8250_out_reg(p, offset) << p->regshift;
+ offset <<= p->regshift;
writeb(value, p->membase + offset);
}
@@ -401,13 +319,13 @@ static const struct serial8250_ops mem_ops = {
static void mem32_serial_out(struct uart_port *p, int offset, int value)
{
- offset = map_8250_out_reg(p, offset) << p->regshift;
+ offset <<= p->regshift;
writel(value, p->membase + offset);
}
static unsigned int mem32_serial_in(struct uart_port *p, int offset)
{
- offset = map_8250_in_reg(p, offset) << p->regshift;
+ offset <<= p->regshift;
return readl(p->membase + offset);
}
@@ -421,7 +339,7 @@ static const struct serial8250_ops mem32_ops = {
static unsigned int tsi_serial_in(struct uart_port *p, int offset)
{
unsigned int tmp;
- offset = map_8250_in_reg(p, offset) << p->regshift;
+ offset <<= p->regshift;
if (offset == UART_IIR) {
tmp = readl(p->membase + (UART_IIR & ~3));
return (tmp >> 16) & 0xff; /* UART_IIR % 4 == 2 */
@@ -431,7 +349,7 @@ static unsigned int tsi_serial_in(struct uart_port *p, int offset)
static void tsi_serial_out(struct uart_port *p, int offset, int value)
{
- offset = map_8250_out_reg(p, offset) << p->regshift;
+ offset <<= p->regshift;
if (!((offset == UART_IER) && (value & UART_IER_UUE)))
writeb(value, p->membase + offset);
}
@@ -443,67 +361,16 @@ static const struct serial8250_ops tsi_ops = {
.serial_dl_write = std_serial_dl_write
};
-/* Save the LCR value so it can be re-written when a Busy Detect IRQ occurs. */
-static inline void dwapb_save_out_value(struct uart_port *p, int offset,
- int value)
-{
- struct uart_8250_port *up =
- container_of(p, struct uart_8250_port, port);
-
- if (offset == UART_LCR)
- up->lcr = value;
-}
-
-/* Read the IER to ensure any interrupt is cleared before returning from ISR. */
-static inline void dwapb_check_clear_ier(struct uart_port *p, int offset)
-{
- struct uart_8250_port *up =
- container_of(p, struct uart_8250_port, port);
- if (offset == UART_TX || offset == UART_IER)
- up->ops->serial_in(p, UART_IER);
-}
-
-static void dwapb_serial_out(struct uart_port *p, int offset, int value)
-{
- int save_offset = offset;
- offset = map_8250_out_reg(p, offset) << p->regshift;
- dwapb_save_out_value(p, save_offset, value);
- writeb(value, p->membase + offset);
- dwapb_check_clear_ier(p, save_offset);
-}
-
-static const struct serial8250_ops dwapb_ops = {
- .serial_in = mem_serial_in,
- .serial_out = dwapb_serial_out,
- .serial_dl_read = std_serial_dl_read,
- .serial_dl_write = std_serial_dl_write
-};
-
-static void dwapb32_serial_out(struct uart_port *p, int offset, int value)
-{
- int save_offset = offset;
- offset = map_8250_out_reg(p, offset) << p->regshift;
- dwapb_save_out_value(p, save_offset, value);
- writel(value, p->membase + offset);
- dwapb_check_clear_ier(p, save_offset);
-}
-
-static const struct serial8250_ops dwapb32_ops = {
- .serial_in = mem32_serial_in,
- .serial_out = dwapb32_serial_out,
- .serial_dl_read = std_serial_dl_read,
- .serial_dl_write = std_serial_dl_write
-};
static unsigned int io_serial_in(struct uart_port *p, int offset)
{
- offset = map_8250_in_reg(p, offset) << p->regshift;
+ offset <<= p->regshift;
return inb(p->iobase + offset);
}
static void io_serial_out(struct uart_port *p, int offset, int value)
{
- offset = map_8250_out_reg(p, offset) << p->regshift;
+ offset <<= p->regshift;
outb(value, p->iobase + offset);
}
@@ -515,67 +382,17 @@ static const struct serial8250_ops pio_ops = {
.serial_dl_write = std_serial_dl_write
};
-static unsigned int au_serial_in(struct uart_port *p, int offset)
-{
- offset = map_8250_in_reg(p, offset) << p->regshift;
- return __raw_readl(p->membase + offset);
-}
-
-static void au_serial_out(struct uart_port *p, int offset, int value)
-{
- offset = map_8250_out_reg(p, offset) << p->regshift;
- __raw_writel(value, p->membase + offset);
-}
-
-/* Au1x00 haven't got a standard divisor latch */
-static unsigned int au_serial_dl_read(struct uart_port *p)
-{
- return __raw_readl(p->membase + 0x28);
-}
-
-static void au_serial_dl_write(struct uart_port *p, unsigned int value)
-{
- __raw_writel(value, p->membase + 0x28);
-}
-
-static const struct serial8250_ops au_ops = {
- .serial_in = au_serial_in,
- .serial_out = au_serial_out,
- .serial_dl_read = au_serial_dl_read,
- .serial_dl_write = au_serial_dl_write
-};
-
-static unsigned int rm9k_serial_dl_read(struct uart_port *p)
-{
- return (((__raw_readl(p->membase + 0x10) << 8) |
- (__raw_readl(p->membase + 0x08) & 0xff)) & 0xffff);
-}
-
-static void rm9k_serial_dl_write(struct uart_port *p, unsigned int value)
-{
- __raw_writel(value, p->membase + 0x08);
- __raw_writel(value >> 8, p->membase + 0x10);
-}
-
-static const struct serial8250_ops rm9k_ops = {
- .serial_in = mem32_serial_in,
- .serial_out = mem32_serial_out,
- .serial_dl_read = rm9k_serial_dl_read,
- .serial_dl_write = rm9k_serial_dl_write
-};
-
-
static const struct serial8250_ops *upio_ops[UPIO_MAX + 1] = {
/* We rely upon pio_ops being built in */
&pio_ops, /* UPIO_PORT */
NULL, /* UPIO_HUB6 */
&mem_ops, /* UPIO_MEM */
&mem32_ops, /* UPIO_MEM32 */
- &au_ops, /* UPIO_AU */
+ NULL, /* UPIO_AU */
&tsi_ops, /* UPIO_TSI */
- &dwapb_ops, /* UPIO_DWAPB */
- &rm9k_ops, /* UPIO_RM9000 */
- &dwapb32_ops /* UPIO_DWAPB32 */
+ NULL, /* UPIO_DWAPB */
+ NULL, /* UPIO_RM9000 */
+ NULL, /* UPIO_DWAPB32 */
};
static DEFINE_MUTEX(upio_mutex);
diff --git a/drivers/tty/serial/8250_au.c b/drivers/tty/serial/8250_au.c
new file mode 100644
index 0000000..bb5b2b2
--- /dev/null
+++ b/drivers/tty/serial/8250_au.c
@@ -0,0 +1,90 @@
+/*
+ * linux/drivers/serial/8250_au.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/serial_8250.h>
+#include <linux/serial_reg.h>
+#include "8250.h"
+
+static const u8 au_io_in_map[] = {
+ [UART_RX] = 0,
+ [UART_IER] = 2,
+ [UART_IIR] = 3,
+ [UART_LCR] = 5,
+ [UART_MCR] = 6,
+ [UART_LSR] = 7,
+ [UART_MSR] = 8,
+};
+
+static const u8 au_io_out_map[] = {
+ [UART_TX] = 1,
+ [UART_IER] = 2,
+ [UART_FCR] = 4,
+ [UART_LCR] = 5,
+ [UART_MCR] = 6,
+};
+
+static inline int map_8250_in_reg(struct uart_port *p, int offset)
+{
+ return au_io_in_map[offset];
+}
+
+static inline int map_8250_out_reg(struct uart_port *p, int offset)
+{
+ return au_io_out_map[offset];
+}
+
+static unsigned int au_serial_in(struct uart_port *p, int offset)
+{
+ offset = map_8250_in_reg(p, offset) << p->regshift;
+ return __raw_readl(p->membase + offset);
+}
+
+static void au_serial_out(struct uart_port *p, int offset, int value)
+{
+ offset = map_8250_out_reg(p, offset) << p->regshift;
+ __raw_writel(value, p->membase + offset);
+}
+
+/* Au1x00 hasn't got a standard divisor latch */
+static unsigned int au_serial_dl_read(struct uart_port *p)
+{
+ return __raw_readl(p->membase + 0x28);
+}
+
+static void au_serial_dl_write(struct uart_port *p, unsigned int value)
+{
+ __raw_writel(value, p->membase + 0x28);
+}
+
+static const struct serial8250_ops au_ops = {
+ .serial_in = au_serial_in,
+ .serial_out = au_serial_out,
+ .serial_dl_read = au_serial_dl_read,
+ .serial_dl_write = au_serial_dl_write,
+ .owner = THIS_MODULE
+};
+
+static int __init au8250_init(void)
+{
+ return serial8250_upio_register(UPIO_AU, &au_ops);
+}
+
+static void __exit au8250_exit(void)
+{
+ serial8250_upio_unregister(UPIO_AU);
+}
+
+module_init(au8250_init);
+module_exit(au8250_exit);
+
+
+MODULE_DESCRIPTION("8250 serial I/O methods for Au1x00 UART");
+MODULE_LICENSE("GPL");
diff --git a/drivers/tty/serial/8250_dwapb.c b/drivers/tty/serial/8250_dwapb.c
new file mode 100644
index 0000000..8863baa
--- /dev/null
+++ b/drivers/tty/serial/8250_dwapb.c
@@ -0,0 +1,120 @@
+/*
+ * linux/drivers/serial/8250_dwapb.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/serial_8250.h>
+#include <linux/serial_reg.h>
+#include "8250.h"
+
+/* Save the LCR value so it can be re-written when a Busy Detect IRQ occurs. */
+static inline void dwapb_save_out_value(struct uart_port *p, int offset,
+ int value)
+{
+ struct uart_8250_port *up =
+ container_of(p, struct uart_8250_port, port);
+
+ if (offset == UART_LCR)
+ up->lcr = value;
+}
+
+/* Read the IER to ensure any interrupt is cleared before returning from ISR. */
+static inline void dwapb_check_clear_ier(struct uart_port *p, int offset)
+{
+ struct uart_8250_port *up =
+ container_of(p, struct uart_8250_port, port);
+ if (offset == UART_TX || offset == UART_IER)
+ up->ops->serial_in(p, UART_IER);
+}
+
+static void dwapb_serial_out(struct uart_port *p, int offset, int value)
+{
+ int save_offset = offset;
+ offset <<= p->regshift;
+ dwapb_save_out_value(p, save_offset, value);
+ writeb(value, p->membase + offset);
+ dwapb_check_clear_ier(p, save_offset);
+}
+
+static unsigned int dwapb_serial_in(struct uart_port *p, int offset)
+{
+ offset <<= p->regshift;
+ return readb(p->membase + offset);
+}
+
+static unsigned int dwapb32_serial_in(struct uart_port *p, int offset)
+{
+ offset <<= p->regshift;
+ return readl(p->membase + offset);
+}
+
+/* Uart divisor latch read */
+static unsigned int dwapb_serial_dl_read(struct uart_port *p)
+{
+ struct uart_8250_port *up =
+ container_of(p, struct uart_8250_port, port);
+ return up->ops->serial_in(p, UART_DLL) |
+ up->ops->serial_in(p, UART_DLM) << 8;
+}
+
+/* Uart divisor latch write */
+static void dwapb_serial_dl_write(struct uart_port *p, unsigned int value)
+{
+ struct uart_8250_port *up =
+ container_of(p, struct uart_8250_port, port);
+ up->ops->serial_out(p, UART_DLL, value & 0xff);
+ up->ops->serial_out(p, UART_DLM, value >> 8 & 0xff);
+}
+
+static const struct serial8250_ops dwapb_ops = {
+ .serial_in = dwapb_serial_in,
+ .serial_out = dwapb_serial_out,
+ .serial_dl_read = dwapb_serial_dl_read,
+ .serial_dl_write = dwapb_serial_dl_write
+};
+
+static void dwapb32_serial_out(struct uart_port *p, int offset, int value)
+{
+ int save_offset = offset;
+ offset <<= p->regshift;
+ dwapb_save_out_value(p, save_offset, value);
+ writel(value, p->membase + offset);
+ dwapb_check_clear_ier(p, save_offset);
+}
+
+static const struct serial8250_ops dwapb32_ops = {
+ .serial_in = dwapb32_serial_in,
+ .serial_out = dwapb32_serial_out,
+ .serial_dl_read = dwapb_serial_dl_read,
+ .serial_dl_write = dwapb_serial_dl_write
+};
+
+static int __init dwapb8250_init(void)
+{
+ int ret = serial8250_upio_register(UPIO_DWAPB, &dwapb_ops);
+ if (ret == 0) {
+ ret = serial8250_upio_register(UPIO_DWAPB32, &dwapb32_ops);
+ if (ret)
+ serial8250_upio_unregister(UPIO_DWAPB);
+ }
+ return ret;
+}
+
+static void __exit dwapb8250_exit(void)
+{
+ serial8250_upio_unregister(UPIO_DWAPB);
+ serial8250_upio_unregister(UPIO_DWAPB32);
+}
+
+module_init(dwapb8250_init);
+module_exit(dwapb8250_exit);
+
+
+MODULE_DESCRIPTION("8250 serial I/O methods for DWAPB UARTs");
+MODULE_LICENSE("GPL");
diff --git a/drivers/tty/serial/8250_rm9k.c b/drivers/tty/serial/8250_rm9k.c
new file mode 100644
index 0000000..91cf97e
--- /dev/null
+++ b/drivers/tty/serial/8250_rm9k.c
@@ -0,0 +1,95 @@
+/*
+ * linux/drivers/serial/8250_rm9k.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/serial_8250.h>
+#include <linux/serial_reg.h>
+#include "8250.h"
+
+static const u8
+ regmap_in[8] = {
+ [UART_RX] = 0x00,
+ [UART_IER] = 0x0c,
+ [UART_IIR] = 0x14,
+ [UART_LCR] = 0x1c,
+ [UART_MCR] = 0x20,
+ [UART_LSR] = 0x24,
+ [UART_MSR] = 0x28,
+ [UART_SCR] = 0x2c
+ },
+ regmap_out[8] = {
+ [UART_TX] = 0x04,
+ [UART_IER] = 0x0c,
+ [UART_FCR] = 0x18,
+ [UART_LCR] = 0x1c,
+ [UART_MCR] = 0x20,
+ [UART_LSR] = 0x24,
+ [UART_MSR] = 0x28,
+ [UART_SCR] = 0x2c
+ };
+
+static inline int map_8250_in_reg(struct uart_port *p, int offset)
+{
+ return regmap_in[offset];
+}
+
+static inline int map_8250_out_reg(struct uart_port *p, int offset)
+{
+ return regmap_out[offset];
+}
+
+static void rm9k_serial_out(struct uart_port *p, int offset, int value)
+{
+ offset = map_8250_out_reg(p, offset) << p->regshift;
+ writel(value, p->membase + offset);
+}
+
+static unsigned int rm9k_serial_in(struct uart_port *p, int offset)
+{
+ offset = map_8250_in_reg(p, offset) << p->regshift;
+ return readl(p->membase + offset);
+}
+
+static unsigned int rm9k_serial_dl_read(struct uart_port *p)
+{
+ return (((__raw_readl(p->membase + 0x10) << 8) |
+ (__raw_readl(p->membase + 0x08) & 0xff)) & 0xffff);
+}
+
+static void rm9k_serial_dl_write(struct uart_port *p, unsigned int value)
+{
+ __raw_writel(value, p->membase + 0x08);
+ __raw_writel(value >> 8, p->membase + 0x10);
+}
+
+static const struct serial8250_ops rm9k_ops = {
+ .serial_in = rm9k_serial_in,
+ .serial_out = rm9k_serial_out,
+ .serial_dl_read = rm9k_serial_dl_read,
+ .serial_dl_write = rm9k_serial_dl_write,
+ .owner = THIS_MODULE,
+};
+
+static int __init rm9k8250_init(void)
+{
+ return serial8250_upio_register(UPIO_RM9000, &rm9k_ops);
+}
+
+static void __exit rm9k8250_exit(void)
+{
+ serial8250_upio_unregister(UPIO_RM9000);
+}
+
+module_init(rm9k8250_init);
+module_exit(rm9k8250_exit);
+
+
+MODULE_DESCRIPTION("8250 serial I/O methods for the RM9000 UART");
+MODULE_LICENSE("GPL");
diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig
index e1aee37..fc8d7a8 100644
--- a/drivers/tty/serial/Kconfig
+++ b/drivers/tty/serial/Kconfig
@@ -80,6 +80,12 @@ config SERIAL_8250_GSC
depends on SERIAL_8250 && GSC
default SERIAL_8250
+config SERIAL_8250_AU
+ tristate "8250 support for AU1000 serial I/O methods"
+
+config SERIAL_8250_DWAPB
+ tristate "8250 support for DWAPB serial I/O methods"
+
config SERIAL_8250_PCI
tristate "8250/16550 PCI device support" if EXPERT
depends on SERIAL_8250 && PCI
@@ -267,6 +273,9 @@ config SERIAL_8250_RM9K
port hardware found on MIPS RM9122 and similar processors.
If unsure, say N.
+config SERIAL_8250_RM9K_OPS
+ tristate "8250 support for RM9000 serial I/O methods"
+
comment "Non-8250 serial port support"
config SERIAL_AMBA_PL010
diff --git a/drivers/tty/serial/Makefile b/drivers/tty/serial/Makefile
index fee0690..af96402 100644
--- a/drivers/tty/serial/Makefile
+++ b/drivers/tty/serial/Makefile
@@ -15,6 +15,9 @@ obj-$(CONFIG_SERIAL_SUNSU) += sunsu.o
obj-$(CONFIG_SERIAL_SUNSAB) += sunsab.o
obj-$(CONFIG_SERIAL_8250) += 8250.o
+obj-$(CONFIG_SERIAL_8250_AU) += 8250_au.o
+obj-$(CONFIG_SERIAL_8250_RM9K_OPS) += 8250_rm9k.o
+obj-$(CONFIG_SERIAL_8250_DWAPB) += 8250_dwapb.o
obj-$(CONFIG_SERIAL_8250_PNP) += 8250_pnp.o
obj-$(CONFIG_SERIAL_8250_GSC) += 8250_gsc.o
obj-$(CONFIG_SERIAL_8250_PCI) += 8250_pci.o
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [RFC 0/5] Starting to pull out the I/O operations
2011-03-18 15:24 [RFC 0/5] Starting to pull out the I/O operations Alan Cox
` (4 preceding siblings ...)
2011-03-18 15:26 ` [RFC 5/5] 8250: extract out the "odd" port types Alan Cox
@ 2011-03-18 20:04 ` Greg KH
5 siblings, 0 replies; 7+ messages in thread
From: Greg KH @ 2011-03-18 20:04 UTC (permalink / raw)
To: Alan Cox; +Cc: linux-serial
On Fri, Mar 18, 2011 at 03:24:29PM +0000, Alan Cox wrote:
> This is an untested WIP but as it was coming in discussion about device-tree
> as well I figured it will be useful to post the prototype code at this point.
>
> There is lots left to do - in particular resource claim/release should be an
> ops method, and it's going to need people to update various embedded 8250
> drivers when we finally go for a version of it.
>
> On the bright side once we have an ops structure we have the basis for avoiding
> further mayhem in the arch code.
This looks great to me, nice job.
Feel free to resend it when you want me to queue it up for .40.
thanks,
greg k-h
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2011-03-18 20:04 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
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 ` [RFC 3/5] 8250: register upio users Alan Cox
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
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).