linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Andrew Morton <akpm@linux-foundation.org>
To: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
Cc: linux-kernel@vger.kernel.org, linux-mips@linux-mips.org,
	Andy Whitcroft <apw@shadowen.org>,
	Alan Cox <alan@lxorguk.ukuu.org.uk>
Subject: Re: [PATCH] SC26XX: New serial driver for SC2681 uarts
Date: Mon, 3 Dec 2007 15:53:17 -0800	[thread overview]
Message-ID: <20071203155317.772231f9.akpm@linux-foundation.org> (raw)
In-Reply-To: <20071202194346.36E3FDE4C4@solo.franken.de>

On Sun,  2 Dec 2007 20:43:46 +0100 (CET)
Thomas Bogendoerfer <tsbogend@alpha.franken.de> 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 (tsbogend@alpha.franken.de)
> + */
> +
> +#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_NR            2
> +
> +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 = 1000000;
> +
> +	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;
> +	int i;
> +
> +	for (i = 0; i < n; i++) {
> +		if (*s == '\n')
> +			sc26xx_console_putchar(port, '\r');
> +		sc26xx_console_putchar(port, *s++);
> +	}
> +}
> +
> +static int __init sc26xx_console_setup(struct console *con, char *options)
> +{
> +	struct uart_port *port = sc26xx_port;
> +	int baud = 9600;
> +	int bits = 8;
> +	int parity = 'n';
> +	int flow = 'n';
> +
> +	if (port->type != PORT_SC26XX)
> +		return -1;
> +
> +	printk(KERN_INFO "Console: ttySC%d (SC26XX)\n", con->index);
> +	if (options)
> +		uart_parse_options(options, &baud, &parity, &bits, &flow);
> +
> +	return uart_set_options(port, con, baud, parity, bits, flow);
> +}
> +
> +static struct uart_driver sc26xx_reg;
> +static struct console sc26xx_console = {
> +	.name	=	"ttySC",
> +	.write	=	sc26xx_console_write,
> +	.device	=	uart_console_device,
> +	.setup  =       sc26xx_console_setup,
> +	.flags	=	CON_PRINTBUFFER,
> +	.index	=	-1,
> +	.data	=	&sc26xx_reg,
> +};
> +#define SC26XX_CONSOLE   &sc26xx_console
> +#else
> +#define SC26XX_CONSOLE   NULL
> +#endif
> +
> +static struct uart_driver sc26xx_reg = {
> +	.owner			= THIS_MODULE,
> +	.driver_name		= "SC26xx",
> +	.dev_name		= "ttySC",
> +	.major			= SC26XX_MAJOR,
> +	.minor			= SC26XX_MINOR_START,
> +	.nr			= SC26XX_NR,
> +	.cons                   = SC26XX_CONSOLE,
> +};
> +
> +static inline u8 sc26xx_flags2mask(unsigned int flags, unsigned int bitpos)
> +{
> +	unsigned int bit = (flags >> bitpos) & 15;
> +
> +	return bit ? (1 << (bit - 1)) : 0;
> +}

This might be too big as well.  It's less of an issue for __devinit text
though.



  reply	other threads:[~2007-12-03 23:54 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-12-02 19:43 [PATCH] SC26XX: New serial driver for SC2681 uarts Thomas Bogendoerfer
2007-12-03 23:53 ` Andrew Morton [this message]
2007-12-03 23:57   ` Arjan van de Ven
2007-12-04  8:25     ` Thomas Bogendoerfer
2007-12-04 11:01       ` Geert Uytterhoeven
2007-12-04 12:45       ` Alan Cox
2007-12-04 23:57         ` Thomas Bogendoerfer
2007-12-04 23:41   ` Thomas Bogendoerfer
2007-12-05  3:27     ` Andrew Morton
2007-12-05  9:25       ` Thomas Bogendoerfer
2007-12-22  9:47         ` Pekka Enberg
2007-12-21 17:36   ` Andy Whitcroft

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20071203155317.772231f9.akpm@linux-foundation.org \
    --to=akpm@linux-foundation.org \
    --cc=alan@lxorguk.ukuu.org.uk \
    --cc=apw@shadowen.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mips@linux-mips.org \
    --cc=tsbogend@alpha.franken.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).