Re: [PATCH] SC26XX: New serial driver for SC2681 uarts

2007-12-22 Thread Pekka Enberg
Hi Thomas,

On Dec 5, 2007 11:25 AM, Thomas Bogendoerfer <[EMAIL PROTECTED]> wrote:
> > These:
> >
> > > +#define READ_SC(p, r)readb((p)->membase + RD_##r)
> > > +#define WRITE_SC(p, r, v)writeb((v), (p)->membase + WR_##r)
> >
> > and these:
> >
> > > +#define READ_SC_PORT(p, r) read_sc_port(p, RD_PORT_##r)
> > > +#define WRITE_SC_PORT(p, r, v) write_sc_port(p, WR_PORT_##r, v)
> >
> > really don't need to exist.  All they do is make the code harder to read.
>
> but they make the code safer. The chip has common register and port
> registers, which are randomly splattered over the address range. And
> some of them are read only, some write only. Read only and Write
> only register live at the same register offset and their function
> usually doesn't have anything in common. By using these macros I'll
> get compile errors when doing a READ_SC from a write only register
> and vice versa. I will also get compile errors, if I try to access a
> common register via READ_SC_PORT/WRITE_SC_PORT.

You can use grep to make sure there are no reads to a write-only
register. What you have there is not safety but macro obfuscation at
its best. It makes the code harder to read for anyone not intimately
familiar with the driver.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] SC26XX: New serial driver for SC2681 uarts

2007-12-22 Thread Pekka Enberg
Hi Thomas,

On Dec 5, 2007 11:25 AM, Thomas Bogendoerfer [EMAIL PROTECTED] wrote:
  These:
 
   +#define READ_SC(p, r)readb((p)-membase + RD_##r)
   +#define WRITE_SC(p, r, v)writeb((v), (p)-membase + WR_##r)
 
  and these:
 
   +#define READ_SC_PORT(p, r) read_sc_port(p, RD_PORT_##r)
   +#define WRITE_SC_PORT(p, r, v) write_sc_port(p, WR_PORT_##r, v)
 
  really don't need to exist.  All they do is make the code harder to read.

 but they make the code safer. The chip has common register and port
 registers, which are randomly splattered over the address range. And
 some of them are read only, some write only. Read only and Write
 only register live at the same register offset and their function
 usually doesn't have anything in common. By using these macros I'll
 get compile errors when doing a READ_SC from a write only register
 and vice versa. I will also get compile errors, if I try to access a
 common register via READ_SC_PORT/WRITE_SC_PORT.

You can use grep to make sure there are no reads to a write-only
register. What you have there is not safety but macro obfuscation at
its best. It makes the code harder to read for anyone not intimately
familiar with the driver.
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] SC26XX: New serial driver for SC2681 uarts

2007-12-21 Thread Andy Whitcroft
On Mon, Dec 03, 2007 at 03:53:17PM -0800, Andrew Morton wrote:
> > +#define READ_SC(p, r)readb ((p)->membase + RD_##r)
> > +#define WRITE_SC(p, r, v)writeb ((v), (p)->membase + WR_##r)
> 
> No space before the (.  checkpatch misses this.

Yep, over careful in the special case for the parameters for #define
macros, which have different spacing rules.  This will be fixed in 0.13:

WARNING: no space between function name and open parenthesis '('
#1: FILE: Z45.c:1:
+#define WRITE_SC(p, r, v)writeb ((v), (p)->membase + WR_##r)

-apw
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] SC26XX: New serial driver for SC2681 uarts

2007-12-21 Thread Andy Whitcroft
On Mon, Dec 03, 2007 at 03:53:17PM -0800, Andrew Morton wrote:
  +#define READ_SC(p, r)readb ((p)-membase + RD_##r)
  +#define WRITE_SC(p, r, v)writeb ((v), (p)-membase + WR_##r)
 
 No space before the (.  checkpatch misses this.

Yep, over careful in the special case for the parameters for #define
macros, which have different spacing rules.  This will be fixed in 0.13:

WARNING: no space between function name and open parenthesis '('
#1: FILE: Z45.c:1:
+#define WRITE_SC(p, r, v)writeb ((v), (p)-membase + WR_##r)

-apw
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] SC26XX: New serial driver for SC2681 uarts

2007-12-05 Thread Thomas Bogendoerfer
On Tue, Dec 04, 2007 at 07:27:38PM -0800, Andrew Morton wrote:
> grumble.
> 
> These:
> 
> > +#define READ_SC(p, r)readb((p)->membase + RD_##r)
> > +#define WRITE_SC(p, r, v)writeb((v), (p)->membase + WR_##r)
> 
> and these:
> 
> > +#define READ_SC_PORT(p, r) read_sc_port(p, RD_PORT_##r)
> > +#define WRITE_SC_PORT(p, r, v) write_sc_port(p, WR_PORT_##r, v)
> 
> really don't need to exist.  All they do is make the code harder to read.

but they make the code safer. The chip has common register and port
registers, which are randomly splattered over the address range. And
some of them are read only, some write only. Read only and Write
only register live at the same register offset and their function
usually doesn't have anything in common. By using these macros I'll
get compile errors when doing a READ_SC from a write only register
and vice versa. I will also get compile errors, if I try to access a
common register via READ_SC_PORT/WRITE_SC_PORT. 

If there is a better way to get more readable code for you and
the safety I'd like, just tell me.

> Think of the poor reader who sees this:
> 
>   status = READ_SC_PORT(port, SR);
> 
> and then goes madly searching for "SR".

which he then finds by this name in the data sheet. All the register
names are named as close to the datasheet as possible. And I consider
consulting datasheets when looking at drivers a pretty good idea.

> Code is written once and is read a thousand times.  Please optimise for
> reading.

it's no big deal to change that, but is getting bitten by stupid chips
worth it ? I'd prefer to get a compile error than debugging a runtime
error.

Thomas.

-- 
Crap can work. Given enough thrust pigs will fly, but it's not necessary a
good idea.[ RFC1925, 2.3 ]
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] SC26XX: New serial driver for SC2681 uarts

2007-12-05 Thread Thomas Bogendoerfer
On Tue, Dec 04, 2007 at 07:27:38PM -0800, Andrew Morton wrote:
 grumble.
 
 These:
 
  +#define READ_SC(p, r)readb((p)-membase + RD_##r)
  +#define WRITE_SC(p, r, v)writeb((v), (p)-membase + WR_##r)
 
 and these:
 
  +#define READ_SC_PORT(p, r) read_sc_port(p, RD_PORT_##r)
  +#define WRITE_SC_PORT(p, r, v) write_sc_port(p, WR_PORT_##r, v)
 
 really don't need to exist.  All they do is make the code harder to read.

but they make the code safer. The chip has common register and port
registers, which are randomly splattered over the address range. And
some of them are read only, some write only. Read only and Write
only register live at the same register offset and their function
usually doesn't have anything in common. By using these macros I'll
get compile errors when doing a READ_SC from a write only register
and vice versa. I will also get compile errors, if I try to access a
common register via READ_SC_PORT/WRITE_SC_PORT. 

If there is a better way to get more readable code for you and
the safety I'd like, just tell me.

 Think of the poor reader who sees this:
 
   status = READ_SC_PORT(port, SR);
 
 and then goes madly searching for SR.

which he then finds by this name in the data sheet. All the register
names are named as close to the datasheet as possible. And I consider
consulting datasheets when looking at drivers a pretty good idea.

 Code is written once and is read a thousand times.  Please optimise for
 reading.

it's no big deal to change that, but is getting bitten by stupid chips
worth it ? I'd prefer to get a compile error than debugging a runtime
error.

Thomas.

-- 
Crap can work. Given enough thrust pigs will fly, but it's not necessary a
good idea.[ RFC1925, 2.3 ]
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] SC26XX: New serial driver for SC2681 uarts

2007-12-04 Thread Andrew Morton
On Wed, 5 Dec 2007 00:41:12 +0100 [EMAIL PROTECTED] (Thomas Bogendoerfer) wrote:

> On Mon, Dec 03, 2007 at 03:53:17PM -0800, Andrew Morton wrote:
> > On Sun,  2 Dec 2007 20:43:46 +0100 (CET)
> > Thomas Bogendoerfer <[EMAIL PROTECTED]> wrote:
> > 
> > > New serial driver for SC2681/SC2691 uarts. Older SNI RM400 machines are
> > > using these chips for onboard serial ports.
> > > 
> > 
> > Little things...
> 
> here is an updated version.
> 
> Changes:
>- use container_of
>- remove not needed locking
>- remove inlines
>- fix macros with double argument reference
> 
> Thomas.
> --
> 
> New serial driver for SC2681/SC2691 uarts. Older SNI RM400 machines are
> using these chips for onboard serial ports.
> 

grumble.

These:

> +#define READ_SC(p, r)readb((p)->membase + RD_##r)
> +#define WRITE_SC(p, r, v)writeb((v), (p)->membase + WR_##r)

and these:

> +#define READ_SC_PORT(p, r) read_sc_port(p, RD_PORT_##r)
> +#define WRITE_SC_PORT(p, r, v) write_sc_port(p, WR_PORT_##r, v)

really don't need to exist.  All they do is make the code harder to read.

Think of the poor reader who sees this:

status = READ_SC_PORT(port, SR);

and then goes madly searching for "SR".  After a while, our confused reader
might think to go look at the definition of READ_SC_PORT, after which our
reader will emulate a C preprocessor in wetware and will eventually construct
then hunt down RD_PORT_SR and will then hopefully remember what the heck he was
trying to do in the first place.

This sucks.

Code is written once and is read a thousand times.  Please optimise for
reading.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] SC26XX: New serial driver for SC2681 uarts

2007-12-04 Thread Thomas Bogendoerfer
On Tue, Dec 04, 2007 at 12:45:16PM +, Alan Cox wrote:
> > I tried to numbers several months ago and didn't get any response 
> 
> Please raise it with the relevant people. If our LANANA administrator is
> not doing their job then the Linuxfoundation need to find a replacement,
> or hand control of it over to someone outside.

I just sent another request for registration. I'll keep you updated.

Thomas.

-- 
Crap can work. Given enough thrust pigs will fly, but it's not necessary a
good idea.[ RFC1925, 2.3 ]
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] SC26XX: New serial driver for SC2681 uarts

2007-12-04 Thread Thomas Bogendoerfer
On Mon, Dec 03, 2007 at 03:53:17PM -0800, Andrew Morton wrote:
> On Sun,  2 Dec 2007 20:43:46 +0100 (CET)
> Thomas Bogendoerfer <[EMAIL PROTECTED]> wrote:
> 
> > New serial driver for SC2681/SC2691 uarts. Older SNI RM400 machines are
> > using these chips for onboard serial ports.
> > 
> 
> Little things...

here is an updated version.

Changes:
   - use container_of
   - remove not needed locking
   - remove inlines
   - fix macros with double argument reference

Thomas.
--

New serial driver for SC2681/SC2691 uarts. Older SNI RM400 machines are
using these chips for onboard serial ports.

Signed-off-by: Thomas Bogendoerfer <[EMAIL PROTECTED]>
---

 drivers/serial/Kconfig  |   15 +
 drivers/serial/Makefile |1 +
 drivers/serial/sc26xx.c |  755 +++
 3 files changed, 771 insertions(+), 0 deletions(-)

diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index d7e1996..2ea55d0 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -1284,4 +1284,19 @@ config SERIAL_OF_PLATFORM
  Currently, only 8250 compatible ports are supported, but
  others can easily be added.
 
+config SERIAL_SC26XX
+   tristate "SC2681/SC2692 serial port support"
+   depends on SNI_RM
+   select SERIAL_CORE
+   help
+ This is a driver for the onboard serial ports of 
+ older RM400 machines.
+
+config SERIAL_SC26XX_CONSOLE
+   bool "Console on SC2681/SC2692 serial port"
+   depends on SERIAL_SC26XX
+   select SERIAL_CORE_CONSOLE
+   help
+ Support for Console on SC2681/SC2692 serial ports.
+
 endmenu
diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
index af6377d..87d09b6 100644
--- a/drivers/serial/Makefile
+++ b/drivers/serial/Makefile
@@ -64,3 +64,4 @@ obj-$(CONFIG_SERIAL_UARTLITE) += uartlite.o
 obj-$(CONFIG_SERIAL_NETX) += netx-serial.o
 obj-$(CONFIG_SERIAL_OF_PLATFORM) += of_serial.o
 obj-$(CONFIG_SERIAL_KS8695) += serial_ks8695.o
+obj-$(CONFIG_SERIAL_SC26XX) += sc26xx.o
diff --git a/drivers/serial/sc26xx.c b/drivers/serial/sc26xx.c
new file mode 100644
index 000..a350b6d
--- /dev/null
+++ b/drivers/serial/sc26xx.c
@@ -0,0 +1,755 @@
+/*
+ * SC268xx.c: Serial driver for Philiphs SC2681/SC2692 devices.
+ *
+ * Copyright (C) 2006,2007 Thomas Bogendörfer ([EMAIL PROTECTED])
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#if defined(CONFIG_MAGIC_SYSRQ)
+#define SUPPORT_SYSRQ
+#endif
+
+#include 
+
+#define SC26XX_MAJOR 204
+#define SC26XX_MINOR_START   205
+#define SC26XX_NR2
+
+struct uart_sc26xx_port {
+   struct uart_port  port[2];
+   u8 dsr_mask[2];
+   u8 cts_mask[2];
+   u8 dcd_mask[2];
+   u8 ri_mask[2];
+   u8 dtr_mask[2];
+   u8 rts_mask[2];
+   u8 imr;
+};
+
+/* register common to both ports */
+#define RD_ISR  0x14
+#define RD_IPR  0x34
+
+#define WR_ACR  0x10
+#define WR_IMR  0x14
+#define WR_OPCR 0x34
+#define WR_OPR_SET  0x38
+#define WR_OPR_CLR  0x3C
+
+/* access common register */
+#define READ_SC(p, r)readb((p)->membase + RD_##r)
+#define WRITE_SC(p, r, v)writeb((v), (p)->membase + WR_##r)
+
+/* register per port */
+#define RD_PORT_MRx 0x00
+#define RD_PORT_SR  0x04
+#define RD_PORT_RHR 0x0c
+
+#define WR_PORT_MRx 0x00
+#define WR_PORT_CSR 0x04
+#define WR_PORT_CR  0x08
+#define WR_PORT_THR 0x0c
+
+/* SR bits */
+#define SR_BREAK(1 << 7)
+#define SR_FRAME(1 << 6)
+#define SR_PARITY   (1 << 5)
+#define SR_OVERRUN  (1 << 4)
+#define SR_TXRDY(1 << 2)
+#define SR_RXRDY(1 << 0)
+
+#define CR_RES_MR   (1 << 4)
+#define CR_RES_RX   (2 << 4)
+#define CR_RES_TX   (3 << 4)
+#define CR_STRT_BRK (6 << 4)
+#define CR_STOP_BRK (7 << 4)
+#define CR_DIS_TX   (1 << 3)
+#define CR_ENA_TX   (1 << 2)
+#define CR_DIS_RX   (1 << 1)
+#define CR_ENA_RX   (1 << 0)
+
+/* ISR bits */
+#define ISR_RXRDYB  (1 << 5)
+#define ISR_TXRDYB  (1 << 4)
+#define ISR_RXRDYA  (1 << 1)
+#define ISR_TXRDYA  (1 << 0)
+
+/* IMR bits */
+#define IMR_RXRDY   (1 << 1)
+#define IMR_TXRDY   (1 << 0)
+
+/* access port register */
+static inline u8 read_sc_port(struct uart_port *p, u8 reg)
+{
+   return readb(p->membase + p->line * 0x20 + reg);
+}
+
+static inline void write_sc_port(struct uart_port *p, u8 reg, u8 val)
+{
+   writeb(val, p->membase + p->line * 0x20 + reg);
+}
+
+#define READ_SC_PORT(p, r) read_sc_port(p, RD_PORT_##r)
+#define WRITE_SC_PORT(p, r, v) write_sc_port(p, WR_PORT_##r, v)
+
+static void sc26xx_enable_irq(struct uart_port *port, int mask)
+{
+   struct uart_sc26xx_port *up;
+   int line = port->line;
+
+   port -= line;
+   up = container_of(port, struct uart_sc26xx_port, port[0]);
+
+   up->imr |= mask << (line * 4);
+   WRITE_SC(port, IMR, up->imr);
+}
+
+static void 

Re: [PATCH] SC26XX: New serial driver for SC2681 uarts

2007-12-04 Thread Alan Cox
On Tue, 4 Dec 2007 09:25:35 +0100
[EMAIL PROTECTED] (Thomas Bogendoerfer) wrote:

> On Mon, Dec 03, 2007 at 03:57:46PM -0800, Arjan van de Ven wrote:
> > > > +#define SC26XX_MAJOR 204
> > > > +#define SC26XX_MINOR_START   205
> > > > +#define SC26XX_NR2
> > 
> > did lanana assign these numbers officially?
> 
> I tried to numbers several months ago and didn't get any response 

Please raise it with the relevant people. If our LANANA administrator is
not doing their job then the Linuxfoundation need to find a replacement,
or hand control of it over to someone outside.

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] SC26XX: New serial driver for SC2681 uarts

2007-12-04 Thread Geert Uytterhoeven
On Tue, 4 Dec 2007, Thomas Bogendoerfer wrote:
> On Mon, Dec 03, 2007 at 03:57:46PM -0800, Arjan van de Ven wrote:
> > > > +#define SC26XX_MAJOR 204
> > > > +#define SC26XX_MINOR_START   205
> > > > +#define SC26XX_NR2
> > 
> > did lanana assign these numbers officially?
> 
> I tried to numbers several months ago and didn't get any response :-(

What about a dynamic number?

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [EMAIL PROTECTED]

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] SC26XX: New serial driver for SC2681 uarts

2007-12-04 Thread Thomas Bogendoerfer
On Mon, Dec 03, 2007 at 03:57:46PM -0800, Arjan van de Ven wrote:
> > > +#define SC26XX_MAJOR 204
> > > +#define SC26XX_MINOR_START   205
> > > +#define SC26XX_NR2
> 
> did lanana assign these numbers officially?

I tried to numbers several months ago and didn't get any response :-(

Thomas.

-- 
Crap can work. Given enough thrust pigs will fly, but it's not necessary a
good idea.[ RFC1925, 2.3 ]
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] SC26XX: New serial driver for SC2681 uarts

2007-12-04 Thread Thomas Bogendoerfer
On Mon, Dec 03, 2007 at 03:57:46PM -0800, Arjan van de Ven wrote:
   +#define SC26XX_MAJOR 204
   +#define SC26XX_MINOR_START   205
   +#define SC26XX_NR2
 
 did lanana assign these numbers officially?

I tried to numbers several months ago and didn't get any response :-(

Thomas.

-- 
Crap can work. Given enough thrust pigs will fly, but it's not necessary a
good idea.[ RFC1925, 2.3 ]
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] SC26XX: New serial driver for SC2681 uarts

2007-12-04 Thread Geert Uytterhoeven
On Tue, 4 Dec 2007, Thomas Bogendoerfer wrote:
 On Mon, Dec 03, 2007 at 03:57:46PM -0800, Arjan van de Ven wrote:
+#define SC26XX_MAJOR 204
+#define SC26XX_MINOR_START   205
+#define SC26XX_NR2
  
  did lanana assign these numbers officially?
 
 I tried to numbers several months ago and didn't get any response :-(

What about a dynamic number?

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [EMAIL PROTECTED]

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say programmer or something like that.
-- Linus Torvalds
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] SC26XX: New serial driver for SC2681 uarts

2007-12-04 Thread Alan Cox
On Tue, 4 Dec 2007 09:25:35 +0100
[EMAIL PROTECTED] (Thomas Bogendoerfer) wrote:

 On Mon, Dec 03, 2007 at 03:57:46PM -0800, Arjan van de Ven wrote:
+#define SC26XX_MAJOR 204
+#define SC26XX_MINOR_START   205
+#define SC26XX_NR2
  
  did lanana assign these numbers officially?
 
 I tried to numbers several months ago and didn't get any response 

Please raise it with the relevant people. If our LANANA administrator is
not doing their job then the Linuxfoundation need to find a replacement,
or hand control of it over to someone outside.

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] SC26XX: New serial driver for SC2681 uarts

2007-12-04 Thread Thomas Bogendoerfer
On Mon, Dec 03, 2007 at 03:53:17PM -0800, Andrew Morton wrote:
 On Sun,  2 Dec 2007 20:43:46 +0100 (CET)
 Thomas Bogendoerfer [EMAIL PROTECTED] wrote:
 
  New serial driver for SC2681/SC2691 uarts. Older SNI RM400 machines are
  using these chips for onboard serial ports.
  
 
 Little things...

here is an updated version.

Changes:
   - use container_of
   - remove not needed locking
   - remove inlines
   - fix macros with double argument reference

Thomas.
--

New serial driver for SC2681/SC2691 uarts. Older SNI RM400 machines are
using these chips for onboard serial ports.

Signed-off-by: Thomas Bogendoerfer [EMAIL PROTECTED]
---

 drivers/serial/Kconfig  |   15 +
 drivers/serial/Makefile |1 +
 drivers/serial/sc26xx.c |  755 +++
 3 files changed, 771 insertions(+), 0 deletions(-)

diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index d7e1996..2ea55d0 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -1284,4 +1284,19 @@ config SERIAL_OF_PLATFORM
  Currently, only 8250 compatible ports are supported, but
  others can easily be added.
 
+config SERIAL_SC26XX
+   tristate SC2681/SC2692 serial port support
+   depends on SNI_RM
+   select SERIAL_CORE
+   help
+ This is a driver for the onboard serial ports of 
+ older RM400 machines.
+
+config SERIAL_SC26XX_CONSOLE
+   bool Console on SC2681/SC2692 serial port
+   depends on SERIAL_SC26XX
+   select SERIAL_CORE_CONSOLE
+   help
+ Support for Console on SC2681/SC2692 serial ports.
+
 endmenu
diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
index af6377d..87d09b6 100644
--- a/drivers/serial/Makefile
+++ b/drivers/serial/Makefile
@@ -64,3 +64,4 @@ obj-$(CONFIG_SERIAL_UARTLITE) += uartlite.o
 obj-$(CONFIG_SERIAL_NETX) += netx-serial.o
 obj-$(CONFIG_SERIAL_OF_PLATFORM) += of_serial.o
 obj-$(CONFIG_SERIAL_KS8695) += serial_ks8695.o
+obj-$(CONFIG_SERIAL_SC26XX) += sc26xx.o
diff --git a/drivers/serial/sc26xx.c b/drivers/serial/sc26xx.c
new file mode 100644
index 000..a350b6d
--- /dev/null
+++ b/drivers/serial/sc26xx.c
@@ -0,0 +1,755 @@
+/*
+ * SC268xx.c: Serial driver for Philiphs SC2681/SC2692 devices.
+ *
+ * Copyright (C) 2006,2007 Thomas Bogendörfer ([EMAIL PROTECTED])
+ */
+
+#include linux/module.h
+#include linux/kernel.h
+#include linux/errno.h
+#include linux/tty.h
+#include linux/tty_flip.h
+#include linux/major.h
+#include linux/circ_buf.h
+#include linux/serial.h
+#include linux/sysrq.h
+#include linux/console.h
+#include linux/spinlock.h
+#include linux/slab.h
+#include linux/delay.h
+#include linux/init.h
+#include linux/platform_device.h
+#include linux/irq.h
+
+#if defined(CONFIG_MAGIC_SYSRQ)
+#define SUPPORT_SYSRQ
+#endif
+
+#include linux/serial_core.h
+
+#define SC26XX_MAJOR 204
+#define SC26XX_MINOR_START   205
+#define SC26XX_NR2
+
+struct uart_sc26xx_port {
+   struct uart_port  port[2];
+   u8 dsr_mask[2];
+   u8 cts_mask[2];
+   u8 dcd_mask[2];
+   u8 ri_mask[2];
+   u8 dtr_mask[2];
+   u8 rts_mask[2];
+   u8 imr;
+};
+
+/* register common to both ports */
+#define RD_ISR  0x14
+#define RD_IPR  0x34
+
+#define WR_ACR  0x10
+#define WR_IMR  0x14
+#define WR_OPCR 0x34
+#define WR_OPR_SET  0x38
+#define WR_OPR_CLR  0x3C
+
+/* access common register */
+#define READ_SC(p, r)readb((p)-membase + RD_##r)
+#define WRITE_SC(p, r, v)writeb((v), (p)-membase + WR_##r)
+
+/* register per port */
+#define RD_PORT_MRx 0x00
+#define RD_PORT_SR  0x04
+#define RD_PORT_RHR 0x0c
+
+#define WR_PORT_MRx 0x00
+#define WR_PORT_CSR 0x04
+#define WR_PORT_CR  0x08
+#define WR_PORT_THR 0x0c
+
+/* SR bits */
+#define SR_BREAK(1  7)
+#define SR_FRAME(1  6)
+#define SR_PARITY   (1  5)
+#define SR_OVERRUN  (1  4)
+#define SR_TXRDY(1  2)
+#define SR_RXRDY(1  0)
+
+#define CR_RES_MR   (1  4)
+#define CR_RES_RX   (2  4)
+#define CR_RES_TX   (3  4)
+#define CR_STRT_BRK (6  4)
+#define CR_STOP_BRK (7  4)
+#define CR_DIS_TX   (1  3)
+#define CR_ENA_TX   (1  2)
+#define CR_DIS_RX   (1  1)
+#define CR_ENA_RX   (1  0)
+
+/* ISR bits */
+#define ISR_RXRDYB  (1  5)
+#define ISR_TXRDYB  (1  4)
+#define ISR_RXRDYA  (1  1)
+#define ISR_TXRDYA  (1  0)
+
+/* IMR bits */
+#define IMR_RXRDY   (1  1)
+#define IMR_TXRDY   (1  0)
+
+/* access port register */
+static inline u8 read_sc_port(struct uart_port *p, u8 reg)
+{
+   return readb(p-membase + p-line * 0x20 + reg);
+}
+
+static inline void write_sc_port(struct uart_port *p, u8 reg, u8 val)
+{
+   writeb(val, p-membase + p-line * 0x20 + reg);
+}
+
+#define READ_SC_PORT(p, r) read_sc_port(p, RD_PORT_##r)
+#define WRITE_SC_PORT(p, r, v) write_sc_port(p, WR_PORT_##r, v)
+
+static void sc26xx_enable_irq(struct uart_port *port, int mask)
+{
+   struct uart_sc26xx_port *up;
+   int line = port-line;
+
+   port -= line;
+

Re: [PATCH] SC26XX: New serial driver for SC2681 uarts

2007-12-04 Thread Thomas Bogendoerfer
On Tue, Dec 04, 2007 at 12:45:16PM +, Alan Cox wrote:
  I tried to numbers several months ago and didn't get any response 
 
 Please raise it with the relevant people. If our LANANA administrator is
 not doing their job then the Linuxfoundation need to find a replacement,
 or hand control of it over to someone outside.

I just sent another request for registration. I'll keep you updated.

Thomas.

-- 
Crap can work. Given enough thrust pigs will fly, but it's not necessary a
good idea.[ RFC1925, 2.3 ]
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] SC26XX: New serial driver for SC2681 uarts

2007-12-04 Thread Andrew Morton
On Wed, 5 Dec 2007 00:41:12 +0100 [EMAIL PROTECTED] (Thomas Bogendoerfer) wrote:

 On Mon, Dec 03, 2007 at 03:53:17PM -0800, Andrew Morton wrote:
  On Sun,  2 Dec 2007 20:43:46 +0100 (CET)
  Thomas Bogendoerfer [EMAIL PROTECTED] wrote:
  
   New serial driver for SC2681/SC2691 uarts. Older SNI RM400 machines are
   using these chips for onboard serial ports.
   
  
  Little things...
 
 here is an updated version.
 
 Changes:
- use container_of
- remove not needed locking
- remove inlines
- fix macros with double argument reference
 
 Thomas.
 --
 
 New serial driver for SC2681/SC2691 uarts. Older SNI RM400 machines are
 using these chips for onboard serial ports.
 

grumble.

These:

 +#define READ_SC(p, r)readb((p)-membase + RD_##r)
 +#define WRITE_SC(p, r, v)writeb((v), (p)-membase + WR_##r)

and these:

 +#define READ_SC_PORT(p, r) read_sc_port(p, RD_PORT_##r)
 +#define WRITE_SC_PORT(p, r, v) write_sc_port(p, WR_PORT_##r, v)

really don't need to exist.  All they do is make the code harder to read.

Think of the poor reader who sees this:

status = READ_SC_PORT(port, SR);

and then goes madly searching for SR.  After a while, our confused reader
might think to go look at the definition of READ_SC_PORT, after which our
reader will emulate a C preprocessor in wetware and will eventually construct
then hunt down RD_PORT_SR and will then hopefully remember what the heck he was
trying to do in the first place.

This sucks.

Code is written once and is read a thousand times.  Please optimise for
reading.
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] SC26XX: New serial driver for SC2681 uarts

2007-12-03 Thread Arjan van de Ven
On Mon, 3 Dec 2007 15:53:17 -0800
Andrew Morton <[EMAIL PROTECTED]> wrote:

> On Sun,  2 Dec 2007 20:43:46 +0100 (CET)
> Thomas Bogendoerfer <[EMAIL PROTECTED]> wrote:
> 
> > New serial driver for SC2681/SC2691 uarts. Older SNI RM400 machines
> > are using these chips for onboard serial ports.
> > 
> 
> Little things...
> 
> > --- /dev/null
> > +++ b/drivers/serial/sc26xx.c
> > @@ -0,0 +1,757 @@
> > +/*
> > + * SC268xx.c: Serial driver for Philiphs SC2681/SC2692 devices.
> > + *
> > + * Copyright (C) 2006,2007 Thomas Bogend__rfer
> > ([EMAIL PROTECTED])
> > + */
> > +
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +
> > +#if defined(CONFIG_MAGIC_SYSRQ)
> > +#define SUPPORT_SYSRQ
> > +#endif
> > +
> > +#include 
> > +
> > +#define SC26XX_MAJOR 204
> > +#define SC26XX_MINOR_START   205
> > +#define SC26XX_NR2

did lanana assign these numbers officially?

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] SC26XX: New serial driver for SC2681 uarts

2007-12-03 Thread Andrew Morton
On Sun,  2 Dec 2007 20:43:46 +0100 (CET)
Thomas Bogendoerfer <[EMAIL PROTECTED]> wrote:

> New serial driver for SC2681/SC2691 uarts. Older SNI RM400 machines are
> using these chips for onboard serial ports.
> 

Little things...

> --- /dev/null
> +++ b/drivers/serial/sc26xx.c
> @@ -0,0 +1,757 @@
> +/*
> + * SC268xx.c: Serial driver for Philiphs SC2681/SC2692 devices.
> + *
> + * Copyright (C) 2006,2007 Thomas Bogend__rfer ([EMAIL PROTECTED])
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#if defined(CONFIG_MAGIC_SYSRQ)
> +#define SUPPORT_SYSRQ
> +#endif
> +
> +#include 
> +
> +#define SC26XX_MAJOR 204
> +#define SC26XX_MINOR_START   205
> +#define SC26XX_NR2
> +
> +struct uart_sc26xx_port {
> + struct uart_port  port[2];
> + u8 dsr_mask[2];
> + u8 cts_mask[2];
> + u8 dcd_mask[2];
> + u8 ri_mask[2];
> + u8 dtr_mask[2];
> + u8 rts_mask[2];
> + u8 imr;
> +};
> +
> +/* register common to both ports */
> +#define RD_ISR  0x14
> +#define RD_IPR  0x34
> +
> +#define WR_ACR  0x10
> +#define WR_IMR  0x14
> +#define WR_OPCR 0x34
> +#define WR_OPR_SET  0x38
> +#define WR_OPR_CLR  0x3C
> +
> +/* access common register */
> +#define READ_SC(p, r)readb ((p)->membase + RD_##r)
> +#define WRITE_SC(p, r, v)writeb ((v), (p)->membase + WR_##r)

No space before the (.  checkpatch misses this.

> +/* register per port */
> +#define RD_PORT_MRx 0x00
> +#define RD_PORT_SR  0x04
> +#define RD_PORT_RHR 0x0c
> +
> +#define WR_PORT_MRx 0x00
> +#define WR_PORT_CSR 0x04
> +#define WR_PORT_CR  0x08
> +#define WR_PORT_THR 0x0c
> +
> +/* access port register */
> +#define READ_SC_PORT(p, r) \
> + readb((p)->membase + (p)->line * 0x20 + RD_PORT_##r)
> +#define WRITE_SC_PORT(p, r, v) \
> + writeb((v), (p)->membase + (p)->line * 0x20 + WR_PORT_##r)

eww, ugly.  Why not have a nice C function which is passed RD_PORT_SR,
RD_PORT_RHR, etc?

That has the (minor) advantage that it won't malfunction if someone does

WRITE_SC_PORT(foo++, r, v);

(the macro references an arg more than once)

> +/* SR bits */
> +#define SR_BREAK(1 << 7)
> +#define SR_FRAME(1 << 6)
> +#define SR_PARITY   (1 << 5)
> +#define SR_OVERRUN  (1 << 4)
> +#define SR_TXRDY(1 << 2)
> +#define SR_RXRDY(1 << 0)
> +
> +#define CR_RES_MR   (1 << 4)
> +#define CR_RES_RX   (2 << 4)
> +#define CR_RES_TX   (3 << 4)
> +#define CR_STRT_BRK (6 << 4)
> +#define CR_STOP_BRK (7 << 4)
> +#define CR_DIS_TX   (1 << 3)
> +#define CR_ENA_TX   (1 << 2)
> +#define CR_DIS_RX   (1 << 1)
> +#define CR_ENA_RX   (1 << 0)
> +
> +/* ISR bits */
> +#define ISR_RXRDYB  (1 << 5)
> +#define ISR_TXRDYB  (1 << 4)
> +#define ISR_RXRDYA  (1 << 1)
> +#define ISR_TXRDYA  (1 << 0)
> +
> +/* IMR bits */
> +#define IMR_RXRDY   (1 << 1)
> +#define IMR_TXRDY   (1 << 0)
> +
> +static void sc26xx_enable_irq(struct uart_port *port, int mask)
> +{
> + struct uart_sc26xx_port *up;
> + int line = port->line;
> +
> + port -= line;
> + up = (struct uart_sc26xx_port *)port;

Yeah, lots of serial drivers do this and it's old-fashioned.  It would be
clearer to use container_of() rather than the open-coded typecast.  That
way, the uart_port doesn't need to be the first member of uart_sc26xx_port,
too.


> + up->imr |= mask << (line * 4);
> + WRITE_SC(port, IMR, up->imr);
> +}
>
> ...
>
> +
> +/* port->lock is not held.  */
> +static unsigned int sc26xx_tx_empty(struct uart_port *port)
> +{
> + unsigned long flags;
> + unsigned int ret;
> +
> + spin_lock_irqsave(>lock, flags);
> + ret = (READ_SC_PORT(port, SR) & SR_TXRDY) ? TIOCSER_TEMT : 0;
> + spin_unlock_irqrestore(>lock, flags);
> + return ret;
> +}

I suspect the locking here doesn't actually do anything?

> +/* port->lock is not held.  */
> +static void sc26xx_set_termios(struct uart_port *port, struct ktermios 
> *termios,
> +   struct ktermios *old)

hm, termios stuff.  I'll cc Alan on the commit...

> +static struct uart_port *sc26xx_port;
> +
> +#ifdef CONFIG_SERIAL_SC26XX_CONSOLE
> +static inline void sc26xx_console_putchar(struct uart_port *port, char c)
> +{
> + unsigned long flags;
> + int limit = 100;
> +
> + spin_lock_irqsave(>lock, flags);
> +
> + while (limit-- > 0) {
> + if (READ_SC_PORT(port, SR) & SR_TXRDY) {
> + WRITE_SC_PORT(port, THR, c);
> + break;
> + }
> + udelay(2);
> + }
> +
> + spin_unlock_irqrestore(>lock, flags);
> +}

This is far too large to be inlined.

> +static void sc26xx_console_write(struct console *con, const char *s, 
> unsigned n)
> +{
> + struct uart_port *port = sc26xx_port;
> + int i;
> +
> + for (i = 0; i < 

Re: [PATCH] SC26XX: New serial driver for SC2681 uarts

2007-12-03 Thread Arjan van de Ven
On Mon, 3 Dec 2007 15:53:17 -0800
Andrew Morton [EMAIL PROTECTED] wrote:

 On Sun,  2 Dec 2007 20:43:46 +0100 (CET)
 Thomas Bogendoerfer [EMAIL PROTECTED] wrote:
 
  New serial driver for SC2681/SC2691 uarts. Older SNI RM400 machines
  are using these chips for onboard serial ports.
  
 
 Little things...
 
  --- /dev/null
  +++ b/drivers/serial/sc26xx.c
  @@ -0,0 +1,757 @@
  +/*
  + * SC268xx.c: Serial driver for Philiphs SC2681/SC2692 devices.
  + *
  + * Copyright (C) 2006,2007 Thomas Bogend__rfer
  ([EMAIL PROTECTED])
  + */
  +
  +#include linux/module.h
  +#include linux/kernel.h
  +#include linux/errno.h
  +#include linux/tty.h
  +#include linux/tty_flip.h
  +#include linux/major.h
  +#include linux/circ_buf.h
  +#include linux/serial.h
  +#include linux/sysrq.h
  +#include linux/console.h
  +#include linux/spinlock.h
  +#include linux/slab.h
  +#include linux/delay.h
  +#include linux/init.h
  +#include linux/platform_device.h
  +#include linux/irq.h
  +
  +#if defined(CONFIG_MAGIC_SYSRQ)
  +#define SUPPORT_SYSRQ
  +#endif
  +
  +#include linux/serial_core.h
  +
  +#define SC26XX_MAJOR 204
  +#define SC26XX_MINOR_START   205
  +#define SC26XX_NR2

did lanana assign these numbers officially?

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] SC26XX: New serial driver for SC2681 uarts

2007-12-03 Thread Andrew Morton
On Sun,  2 Dec 2007 20:43:46 +0100 (CET)
Thomas Bogendoerfer [EMAIL PROTECTED] wrote:

 New serial driver for SC2681/SC2691 uarts. Older SNI RM400 machines are
 using these chips for onboard serial ports.
 

Little things...

 --- /dev/null
 +++ b/drivers/serial/sc26xx.c
 @@ -0,0 +1,757 @@
 +/*
 + * SC268xx.c: Serial driver for Philiphs SC2681/SC2692 devices.
 + *
 + * Copyright (C) 2006,2007 Thomas Bogend__rfer ([EMAIL PROTECTED])
 + */
 +
 +#include linux/module.h
 +#include linux/kernel.h
 +#include linux/errno.h
 +#include linux/tty.h
 +#include linux/tty_flip.h
 +#include linux/major.h
 +#include linux/circ_buf.h
 +#include linux/serial.h
 +#include linux/sysrq.h
 +#include linux/console.h
 +#include linux/spinlock.h
 +#include linux/slab.h
 +#include linux/delay.h
 +#include linux/init.h
 +#include linux/platform_device.h
 +#include linux/irq.h
 +
 +#if defined(CONFIG_MAGIC_SYSRQ)
 +#define SUPPORT_SYSRQ
 +#endif
 +
 +#include linux/serial_core.h
 +
 +#define SC26XX_MAJOR 204
 +#define SC26XX_MINOR_START   205
 +#define SC26XX_NR2
 +
 +struct uart_sc26xx_port {
 + struct uart_port  port[2];
 + u8 dsr_mask[2];
 + u8 cts_mask[2];
 + u8 dcd_mask[2];
 + u8 ri_mask[2];
 + u8 dtr_mask[2];
 + u8 rts_mask[2];
 + u8 imr;
 +};
 +
 +/* register common to both ports */
 +#define RD_ISR  0x14
 +#define RD_IPR  0x34
 +
 +#define WR_ACR  0x10
 +#define WR_IMR  0x14
 +#define WR_OPCR 0x34
 +#define WR_OPR_SET  0x38
 +#define WR_OPR_CLR  0x3C
 +
 +/* access common register */
 +#define READ_SC(p, r)readb ((p)-membase + RD_##r)
 +#define WRITE_SC(p, r, v)writeb ((v), (p)-membase + WR_##r)

No space before the (.  checkpatch misses this.

 +/* register per port */
 +#define RD_PORT_MRx 0x00
 +#define RD_PORT_SR  0x04
 +#define RD_PORT_RHR 0x0c
 +
 +#define WR_PORT_MRx 0x00
 +#define WR_PORT_CSR 0x04
 +#define WR_PORT_CR  0x08
 +#define WR_PORT_THR 0x0c
 +
 +/* access port register */
 +#define READ_SC_PORT(p, r) \
 + readb((p)-membase + (p)-line * 0x20 + RD_PORT_##r)
 +#define WRITE_SC_PORT(p, r, v) \
 + writeb((v), (p)-membase + (p)-line * 0x20 + WR_PORT_##r)

eww, ugly.  Why not have a nice C function which is passed RD_PORT_SR,
RD_PORT_RHR, etc?

That has the (minor) advantage that it won't malfunction if someone does

WRITE_SC_PORT(foo++, r, v);

(the macro references an arg more than once)

 +/* SR bits */
 +#define SR_BREAK(1  7)
 +#define SR_FRAME(1  6)
 +#define SR_PARITY   (1  5)
 +#define SR_OVERRUN  (1  4)
 +#define SR_TXRDY(1  2)
 +#define SR_RXRDY(1  0)
 +
 +#define CR_RES_MR   (1  4)
 +#define CR_RES_RX   (2  4)
 +#define CR_RES_TX   (3  4)
 +#define CR_STRT_BRK (6  4)
 +#define CR_STOP_BRK (7  4)
 +#define CR_DIS_TX   (1  3)
 +#define CR_ENA_TX   (1  2)
 +#define CR_DIS_RX   (1  1)
 +#define CR_ENA_RX   (1  0)
 +
 +/* ISR bits */
 +#define ISR_RXRDYB  (1  5)
 +#define ISR_TXRDYB  (1  4)
 +#define ISR_RXRDYA  (1  1)
 +#define ISR_TXRDYA  (1  0)
 +
 +/* IMR bits */
 +#define IMR_RXRDY   (1  1)
 +#define IMR_TXRDY   (1  0)
 +
 +static void sc26xx_enable_irq(struct uart_port *port, int mask)
 +{
 + struct uart_sc26xx_port *up;
 + int line = port-line;
 +
 + port -= line;
 + up = (struct uart_sc26xx_port *)port;

Yeah, lots of serial drivers do this and it's old-fashioned.  It would be
clearer to use container_of() rather than the open-coded typecast.  That
way, the uart_port doesn't need to be the first member of uart_sc26xx_port,
too.


 + up-imr |= mask  (line * 4);
 + WRITE_SC(port, IMR, up-imr);
 +}

 ...

 +
 +/* port-lock is not held.  */
 +static unsigned int sc26xx_tx_empty(struct uart_port *port)
 +{
 + unsigned long flags;
 + unsigned int ret;
 +
 + spin_lock_irqsave(port-lock, flags);
 + ret = (READ_SC_PORT(port, SR)  SR_TXRDY) ? TIOCSER_TEMT : 0;
 + spin_unlock_irqrestore(port-lock, flags);
 + return ret;
 +}

I suspect the locking here doesn't actually do anything?

 +/* port-lock is not held.  */
 +static void sc26xx_set_termios(struct uart_port *port, struct ktermios 
 *termios,
 +   struct ktermios *old)

hm, termios stuff.  I'll cc Alan on the commit...

 +static struct uart_port *sc26xx_port;
 +
 +#ifdef CONFIG_SERIAL_SC26XX_CONSOLE
 +static inline void sc26xx_console_putchar(struct uart_port *port, char c)
 +{
 + unsigned long flags;
 + int limit = 100;
 +
 + spin_lock_irqsave(port-lock, flags);
 +
 + while (limit--  0) {
 + if (READ_SC_PORT(port, SR)  SR_TXRDY) {
 + WRITE_SC_PORT(port, THR, c);
 + break;
 + }
 + udelay(2);
 + }
 +
 + spin_unlock_irqrestore(port-lock, flags);
 +}

This is far too large to be inlined.

 +static void sc26xx_console_write(struct console *con, const char *s, 
 unsigned n)
 +{
 + struct uart_port *port = sc26xx_port;
 

[PATCH] SC26XX: New serial driver for SC2681 uarts

2007-12-02 Thread Thomas Bogendoerfer
New serial driver for SC2681/SC2691 uarts. Older SNI RM400 machines are
using these chips for onboard serial ports.

Signed-off-by: Thomas Bogendoerfer <[EMAIL PROTECTED]>
---

Please apply for 2.6.25.

 drivers/serial/Kconfig  |   15 +
 drivers/serial/Makefile |1 +
 drivers/serial/sc26xx.c |  757 +++
 3 files changed, 773 insertions(+), 0 deletions(-)

diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index d7e1996..2ea55d0 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -1284,4 +1284,19 @@ config SERIAL_OF_PLATFORM
  Currently, only 8250 compatible ports are supported, but
  others can easily be added.
 
+config SERIAL_SC26XX
+   tristate "SC2681/SC2692 serial port support"
+   depends on SNI_RM
+   select SERIAL_CORE
+   help
+ This is a driver for the onboard serial ports of 
+ older RM400 machines.
+
+config SERIAL_SC26XX_CONSOLE
+   bool "Console on SC2681/SC2692 serial port"
+   depends on SERIAL_SC26XX
+   select SERIAL_CORE_CONSOLE
+   help
+ Support for Console on SC2681/SC2692 serial ports.
+
 endmenu
diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
index af6377d..87d09b6 100644
--- a/drivers/serial/Makefile
+++ b/drivers/serial/Makefile
@@ -64,3 +64,4 @@ obj-$(CONFIG_SERIAL_UARTLITE) += uartlite.o
 obj-$(CONFIG_SERIAL_NETX) += netx-serial.o
 obj-$(CONFIG_SERIAL_OF_PLATFORM) += of_serial.o
 obj-$(CONFIG_SERIAL_KS8695) += serial_ks8695.o
+obj-$(CONFIG_SERIAL_SC26XX) += sc26xx.o
diff --git a/drivers/serial/sc26xx.c b/drivers/serial/sc26xx.c
new file mode 100644
index 000..be563ad
--- /dev/null
+++ b/drivers/serial/sc26xx.c
@@ -0,0 +1,757 @@
+/*
+ * SC268xx.c: Serial driver for Philiphs SC2681/SC2692 devices.
+ *
+ * Copyright (C) 2006,2007 Thomas Bogendörfer ([EMAIL PROTECTED])
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#if defined(CONFIG_MAGIC_SYSRQ)
+#define SUPPORT_SYSRQ
+#endif
+
+#include 
+
+#define SC26XX_MAJOR 204
+#define SC26XX_MINOR_START   205
+#define SC26XX_NR2
+
+struct uart_sc26xx_port {
+   struct uart_port  port[2];
+   u8 dsr_mask[2];
+   u8 cts_mask[2];
+   u8 dcd_mask[2];
+   u8 ri_mask[2];
+   u8 dtr_mask[2];
+   u8 rts_mask[2];
+   u8 imr;
+};
+
+/* register common to both ports */
+#define RD_ISR  0x14
+#define RD_IPR  0x34
+
+#define WR_ACR  0x10
+#define WR_IMR  0x14
+#define WR_OPCR 0x34
+#define WR_OPR_SET  0x38
+#define WR_OPR_CLR  0x3C
+
+/* access common register */
+#define READ_SC(p, r)readb ((p)->membase + RD_##r)
+#define WRITE_SC(p, r, v)writeb ((v), (p)->membase + WR_##r)
+
+/* register per port */
+#define RD_PORT_MRx 0x00
+#define RD_PORT_SR  0x04
+#define RD_PORT_RHR 0x0c
+
+#define WR_PORT_MRx 0x00
+#define WR_PORT_CSR 0x04
+#define WR_PORT_CR  0x08
+#define WR_PORT_THR 0x0c
+
+/* access port register */
+#define READ_SC_PORT(p, r) \
+   readb((p)->membase + (p)->line * 0x20 + RD_PORT_##r)
+#define WRITE_SC_PORT(p, r, v) \
+   writeb((v), (p)->membase + (p)->line * 0x20 + WR_PORT_##r)
+
+/* SR bits */
+#define SR_BREAK(1 << 7)
+#define SR_FRAME(1 << 6)
+#define SR_PARITY   (1 << 5)
+#define SR_OVERRUN  (1 << 4)
+#define SR_TXRDY(1 << 2)
+#define SR_RXRDY(1 << 0)
+
+#define CR_RES_MR   (1 << 4)
+#define CR_RES_RX   (2 << 4)
+#define CR_RES_TX   (3 << 4)
+#define CR_STRT_BRK (6 << 4)
+#define CR_STOP_BRK (7 << 4)
+#define CR_DIS_TX   (1 << 3)
+#define CR_ENA_TX   (1 << 2)
+#define CR_DIS_RX   (1 << 1)
+#define CR_ENA_RX   (1 << 0)
+
+/* ISR bits */
+#define ISR_RXRDYB  (1 << 5)
+#define ISR_TXRDYB  (1 << 4)
+#define ISR_RXRDYA  (1 << 1)
+#define ISR_TXRDYA  (1 << 0)
+
+/* IMR bits */
+#define IMR_RXRDY   (1 << 1)
+#define IMR_TXRDY   (1 << 0)
+
+static void sc26xx_enable_irq(struct uart_port *port, int mask)
+{
+   struct uart_sc26xx_port *up;
+   int line = port->line;
+
+   port -= line;
+   up = (struct uart_sc26xx_port *)port;
+
+   up->imr |= mask << (line * 4);
+   WRITE_SC(port, IMR, up->imr);
+}
+
+static void sc26xx_disable_irq(struct uart_port *port, int mask)
+{
+   struct uart_sc26xx_port *up;
+   int line = port->line;
+
+   port -= line;
+   up = (struct uart_sc26xx_port *)port;
+
+   up->imr &= ~(mask << (line * 4));
+   WRITE_SC(port, IMR, up->imr);
+}
+
+static struct tty_struct *receive_chars(struct uart_port *port)
+{
+   struct tty_struct *tty = NULL;
+   int limit = 1;
+   unsigned char ch;
+   char flag;
+   u8 status;
+
+   if (port->info != NULL) /* Unopened serial console */
+   tty = port->info->tty;
+
+   while (limit-- > 0) {
+   status = READ_SC_PORT(port, 

[PATCH] SC26XX: New serial driver for SC2681 uarts

2007-12-02 Thread Thomas Bogendoerfer
New serial driver for SC2681/SC2691 uarts. Older SNI RM400 machines are
using these chips for onboard serial ports.

Signed-off-by: Thomas Bogendoerfer [EMAIL PROTECTED]
---

Please apply for 2.6.25.

 drivers/serial/Kconfig  |   15 +
 drivers/serial/Makefile |1 +
 drivers/serial/sc26xx.c |  757 +++
 3 files changed, 773 insertions(+), 0 deletions(-)

diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index d7e1996..2ea55d0 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -1284,4 +1284,19 @@ config SERIAL_OF_PLATFORM
  Currently, only 8250 compatible ports are supported, but
  others can easily be added.
 
+config SERIAL_SC26XX
+   tristate SC2681/SC2692 serial port support
+   depends on SNI_RM
+   select SERIAL_CORE
+   help
+ This is a driver for the onboard serial ports of 
+ older RM400 machines.
+
+config SERIAL_SC26XX_CONSOLE
+   bool Console on SC2681/SC2692 serial port
+   depends on SERIAL_SC26XX
+   select SERIAL_CORE_CONSOLE
+   help
+ Support for Console on SC2681/SC2692 serial ports.
+
 endmenu
diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
index af6377d..87d09b6 100644
--- a/drivers/serial/Makefile
+++ b/drivers/serial/Makefile
@@ -64,3 +64,4 @@ obj-$(CONFIG_SERIAL_UARTLITE) += uartlite.o
 obj-$(CONFIG_SERIAL_NETX) += netx-serial.o
 obj-$(CONFIG_SERIAL_OF_PLATFORM) += of_serial.o
 obj-$(CONFIG_SERIAL_KS8695) += serial_ks8695.o
+obj-$(CONFIG_SERIAL_SC26XX) += sc26xx.o
diff --git a/drivers/serial/sc26xx.c b/drivers/serial/sc26xx.c
new file mode 100644
index 000..be563ad
--- /dev/null
+++ b/drivers/serial/sc26xx.c
@@ -0,0 +1,757 @@
+/*
+ * SC268xx.c: Serial driver for Philiphs SC2681/SC2692 devices.
+ *
+ * Copyright (C) 2006,2007 Thomas Bogendörfer ([EMAIL PROTECTED])
+ */
+
+#include linux/module.h
+#include linux/kernel.h
+#include linux/errno.h
+#include linux/tty.h
+#include linux/tty_flip.h
+#include linux/major.h
+#include linux/circ_buf.h
+#include linux/serial.h
+#include linux/sysrq.h
+#include linux/console.h
+#include linux/spinlock.h
+#include linux/slab.h
+#include linux/delay.h
+#include linux/init.h
+#include linux/platform_device.h
+#include linux/irq.h
+
+#if defined(CONFIG_MAGIC_SYSRQ)
+#define SUPPORT_SYSRQ
+#endif
+
+#include linux/serial_core.h
+
+#define SC26XX_MAJOR 204
+#define SC26XX_MINOR_START   205
+#define SC26XX_NR2
+
+struct uart_sc26xx_port {
+   struct uart_port  port[2];
+   u8 dsr_mask[2];
+   u8 cts_mask[2];
+   u8 dcd_mask[2];
+   u8 ri_mask[2];
+   u8 dtr_mask[2];
+   u8 rts_mask[2];
+   u8 imr;
+};
+
+/* register common to both ports */
+#define RD_ISR  0x14
+#define RD_IPR  0x34
+
+#define WR_ACR  0x10
+#define WR_IMR  0x14
+#define WR_OPCR 0x34
+#define WR_OPR_SET  0x38
+#define WR_OPR_CLR  0x3C
+
+/* access common register */
+#define READ_SC(p, r)readb ((p)-membase + RD_##r)
+#define WRITE_SC(p, r, v)writeb ((v), (p)-membase + WR_##r)
+
+/* register per port */
+#define RD_PORT_MRx 0x00
+#define RD_PORT_SR  0x04
+#define RD_PORT_RHR 0x0c
+
+#define WR_PORT_MRx 0x00
+#define WR_PORT_CSR 0x04
+#define WR_PORT_CR  0x08
+#define WR_PORT_THR 0x0c
+
+/* access port register */
+#define READ_SC_PORT(p, r) \
+   readb((p)-membase + (p)-line * 0x20 + RD_PORT_##r)
+#define WRITE_SC_PORT(p, r, v) \
+   writeb((v), (p)-membase + (p)-line * 0x20 + WR_PORT_##r)
+
+/* SR bits */
+#define SR_BREAK(1  7)
+#define SR_FRAME(1  6)
+#define SR_PARITY   (1  5)
+#define SR_OVERRUN  (1  4)
+#define SR_TXRDY(1  2)
+#define SR_RXRDY(1  0)
+
+#define CR_RES_MR   (1  4)
+#define CR_RES_RX   (2  4)
+#define CR_RES_TX   (3  4)
+#define CR_STRT_BRK (6  4)
+#define CR_STOP_BRK (7  4)
+#define CR_DIS_TX   (1  3)
+#define CR_ENA_TX   (1  2)
+#define CR_DIS_RX   (1  1)
+#define CR_ENA_RX   (1  0)
+
+/* ISR bits */
+#define ISR_RXRDYB  (1  5)
+#define ISR_TXRDYB  (1  4)
+#define ISR_RXRDYA  (1  1)
+#define ISR_TXRDYA  (1  0)
+
+/* IMR bits */
+#define IMR_RXRDY   (1  1)
+#define IMR_TXRDY   (1  0)
+
+static void sc26xx_enable_irq(struct uart_port *port, int mask)
+{
+   struct uart_sc26xx_port *up;
+   int line = port-line;
+
+   port -= line;
+   up = (struct uart_sc26xx_port *)port;
+
+   up-imr |= mask  (line * 4);
+   WRITE_SC(port, IMR, up-imr);
+}
+
+static void sc26xx_disable_irq(struct uart_port *port, int mask)
+{
+   struct uart_sc26xx_port *up;
+   int line = port-line;
+
+   port -= line;
+   up = (struct uart_sc26xx_port *)port;
+
+   up-imr = ~(mask  (line * 4));
+   WRITE_SC(port, IMR, up-imr);
+}
+
+static struct tty_struct *receive_chars(struct uart_port *port)
+{
+   struct tty_struct *tty = NULL;
+   int limit = 1;
+   unsigned char ch;
+   char flag;
+   u8 status;
+
+