[spi-devel-general] [RFC][PATCH v2] serial: spi: add spi-uart driver for Maxim 3110

2010-02-08 Thread Feng Tang
Hi All,

Here is a driver for Maxim 3110 SPI-UART device, please help to review.

It has been validated with Designware SPI controller (drivers/spi: dw_spi.c &
dw_spi_pci.c). It supports polling and IRQ mode, supports batch read, and
provides a console.

change since v1:
* Address comments from Alan Cox
* Use a "use_irq" module parameter to runtime check whether
  to use IRQ mode
* Add the suspend/resume implementation

Thanks!
Feng

>From 6d14c5d68cdae8d48b6d8a00b6653022f2b100d0 Mon Sep 17 00:00:00 2001
From: Feng Tang 
Date: Mon, 8 Feb 2010 16:02:59 +0800
Subject: [PATCH] serial: spi: add spi-uart driver for Maxim 3110

This is the driver for Max3110 SPI-UART device, which connect
to host with SPI interface. It supports baud rates from 300 to
230400, and supports both polling and IRQ mode, as well as
providing a console for system use

Its datasheet could be found here:
http://datasheets.maxim-ic.com/en/ds/MAX3110E-MAX3111E.pdf

Signed-off-by: Feng Tang 
---
 drivers/serial/Kconfig  |   12 +
 drivers/serial/max3110.c|  848 +++
 drivers/serial/max3110.h|   59 +++
 include/linux/serial_core.h |3 +
 4 files changed, 922 insertions(+), 0 deletions(-)
 create mode 100644 drivers/serial/max3110.c
 create mode 100644 drivers/serial/max3110.h

diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index 9ff47db..f7daf2f 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -688,6 +688,18 @@ config SERIAL_SA1100_CONSOLE
  your boot loader (lilo or loadlin) about how to pass options to the
  kernel at boot time.)
 
+config SERIAL_MAX3110
+   tristate "SPI UART driver for Max3110"
+   select SERIAL_CORE
+   select SERIAL_CORE_CONSOLE
+   help
+ This is the UART protocol driver for MAX3110 device
+
+config MAX3110_DESIGNWARE
+   boolean "Enable Max3110 to work with Designware controller"
+   default y
+   depends on SERIAL_MAX3110
+
 config SERIAL_BFIN
tristate "Blackfin serial port support"
depends on BLACKFIN
diff --git a/drivers/serial/max3110.c b/drivers/serial/max3110.c
new file mode 100644
index 000..c7c012b
--- /dev/null
+++ b/drivers/serial/max3110.c
@@ -0,0 +1,848 @@
+/*
+ * max3110.c - spi uart protocol driver for Maxim 3110
+ *
+ * Copyright (c) 2009, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+/*
+ * Note:
+ * * From Max3110 spec, the Rx FIFO has 8 words, while the Tx FIFO only has
+ *   1 word. If SPI master controller doesn't support sclk frequency change,
+ *   then the char need be sent out one by one with some delay
+ *
+ * * Currently only RX availabe interrrupt is used
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "max3110.h"
+
+#define PR_FMT "max3110: "
+
+struct uart_max3110 {
+   struct uart_port port;
+   struct spi_device *spi;
+   char *name;
+
+   wait_queue_head_t wq;
+   struct task_struct *main_thread;
+   struct task_struct *read_thread;
+   int mthread_up;
+   spinlock_t lock;
+
+   u32 baud;
+   u16 cur_conf;
+   u8 clock;
+   u8 parity, word_7bits;
+
+   atomic_t uart_tx_need;
+
+   /* console related */
+   struct circ_buf con_xmit;
+   atomic_t con_tx_need;
+
+   /* irq related */
+   u16 irq;
+   atomic_t irq_pending;
+};
+
+static struct uart_max3110 *pmax;
+
+static int use_irq = 1;
+module_param(use_irq, int, 0444);
+MODULE_PARM_DESC(use_irq, "Whether using Max3110's IRQ capability");
+
+static void receive_chars(struct uart_max3110 *max,
+   unsigned char *str, int len);
+static int max3110_read_multi(struct uart_max3110 *max, int len, u8 *buf);
+static void max3110_con_receive(struct uart_max3110 *max);
+
+int max3110_write_then_read(struct uart_max3110 *max,
+   const u8 *txbuf, u8 *rxbuf, unsigned len, int always_fast)
+{
+   struct spi_device *spi = max->spi;
+   struct spi_message  message;
+   struct spi_transfer x;
+   int ret;
+
+   spi_message_init(&message);
+   memset(&x, 0, sizeof x);
+   x.len = len;
+   x.tx_buf = txbuf;
+   x.rx_buf = rxbuf;
+   spi_

Re: [spi-devel-general] [RFC][PATCH v2] serial: spi: add spi-uart driver for Maxim 3110

2010-02-08 Thread Andrew Morton
On Mon, 8 Feb 2010 16:59:46 +0800
Feng Tang  wrote:

> Hi All,
> 
> Here is a driver for Maxim 3110 SPI-UART device, please help to review.
> 
> It has been validated with Designware SPI controller (drivers/spi: dw_spi.c &
> dw_spi_pci.c). It supports polling and IRQ mode, supports batch read, and
> provides a console.
> 
> change since v1:
>   * Address comments from Alan Cox
>   * Use a "use_irq" module parameter to runtime check whether
> to use IRQ mode
>   * Add the suspend/resume implementation
> 
> Thanks!
> Feng
> 
> >From 6d14c5d68cdae8d48b6d8a00b6653022f2b100d0 Mon Sep 17 00:00:00 2001
> From: Feng Tang 
> Date: Mon, 8 Feb 2010 16:02:59 +0800
> Subject: [PATCH] serial: spi: add spi-uart driver for Maxim 3110
> 
> This is the driver for Max3110 SPI-UART device, which connect
> to host with SPI interface. It supports baud rates from 300 to
> 230400, and supports both polling and IRQ mode, as well as
> providing a console for system use
> 
> Its datasheet could be found here:
> http://datasheets.maxim-ic.com/en/ds/MAX3110E-MAX3111E.pdf
> 

I wonder if this is an "spi" subsystem thing or a "serial" subsystem
thing.  It looks more like a serial driver to me.

> ---
>  drivers/serial/Kconfig  |   12 +
>  drivers/serial/max3110.c|  848 
> +++
>  drivers/serial/max3110.h|   59 +++
>  include/linux/serial_core.h |3 +


> diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
> index 9ff47db..f7daf2f 100644
> --- a/drivers/serial/Kconfig
> +++ b/drivers/serial/Kconfig
>
> ...
>
> +static int use_irq = 1;
> +module_param(use_irq, int, 0444);
> +MODULE_PARM_DESC(use_irq, "Whether using Max3110's IRQ capability");
> +
> +static void receive_chars(struct uart_max3110 *max,
> + unsigned char *str, int len);
> +static int max3110_read_multi(struct uart_max3110 *max, int len, u8 *buf);
> +static void max3110_con_receive(struct uart_max3110 *max);
> +
> +int max3110_write_then_read(struct uart_max3110 *max,
> + const u8 *txbuf, u8 *rxbuf, unsigned len, int always_fast)

The driver has a number of identifiers which have global scope,
apparently unnecessarily.  Please review all such identifiers, see if
they can be made static.

> +{
> + struct spi_device *spi = max->spi;
> + struct spi_message  message;
> + struct spi_transfer x;
> + int ret;
> +
> + spi_message_init(&message);
> + memset(&x, 0, sizeof x);
> + x.len = len;
> + x.tx_buf = txbuf;
> + x.rx_buf = rxbuf;
> + spi_message_add_tail(&x, &message);
> +
> + if (always_fast)
> + x.speed_hz = spi->max_speed_hz;
> + else if (max->baud)
> + x.speed_hz = max->baud;
> +
> + /* Do the i/o */
> + ret = spi_sync(spi, &message);
> + return ret;
> +}
> +
> +/* Write a u16 to the device, and return one u16 read back */
> +int max3110_out(struct uart_max3110 *max, const u16 out)

Another.

> +{
> + u16 tmp;
> + int ret;
> +
> + ret = max3110_write_then_read(max, (u8 *)&out, (u8 *)&tmp, 2, 1);

Something nasty is happening here.  Modifying a u16 via a u8* is to
assume a certain endianness, surely.  Will the driver break when used
on other-endian architectures?

> + if (ret)
> + return ret;
> +
> + /* If some valid data is read back */
> + if (tmp & MAX3110_READ_DATA_AVAILABLE) {
> + tmp &= 0xff;
> + receive_chars(max, (unsigned char *)&tmp, 1);
> + }
> +
> + return ret;
> +}
> +
> +#define MAX_READ_LEN 20
> +/*
> + * This is usually used to read data from SPIC RX FIFO, which doesn't
> + * need any delay like flushing character out.
> + * Returns how many valide bytes are read back
> + */
> +static int max3110_read_multi(struct uart_max3110 *max, int len, u8 *buf)
> +{
> + u16 out[MAX_READ_LEN], in[MAX_READ_LEN];
> + u8 *pbuf, valid_str[MAX_READ_LEN];
> + int i, j, bytelen;
> +
> + bytelen = len * 2;
> + memset(out, 0, bytelen);
> + memset(in, 0, bytelen);
> +
> + if (max3110_write_then_read(max, (u8 *)out, (u8 *)in, bytelen, 1))
> + return 0;
>

max3110_write_then_read() can return an error code (from spi_async()). 
But here that error code simply gets lost.  It should be reported to
higher-level code somehow?

> + /* If caller doesn't provide a buffer, then handle received char */
> + pbuf = buf ? buf : valid_str;
> +
> + for (i = 0, j = 0; i < len; i++) {
> + if (in[i] & MAX3110_READ_DATA_AVAILABLE)
> + pbuf[j++] = (u8)(in[i] & 0xff);
> + }
> +
> + if (j && (pbuf == valid_str))
> + receive_chars(max, valid_str, j);
> +
> + return j;
> +}
> +
> +static void serial_m3110_con_putchar(struct uart_port *port, int ch)
> +{
> + struct uart_max3110 *max =
> + container_of(port, struct uart_max3110, port);
> + struct circ_buf *xmit = &max->con_xmit;
> +
> + if (uart_circ_ch

Re: [spi-devel-general] [RFC][PATCH v2] serial: spi: add spi-uart driver for Maxim 3110

2010-02-08 Thread Feng Tang
On Tue, 9 Feb 2010 08:26:35 +0800
Grant Likely  wrote:

> On Mon, Feb 8, 2010 at 5:20 PM, Andrew Morton
>  wrote:
> > On Mon, 8 Feb 2010 16:59:46 +0800
> > Feng Tang  wrote:
> >
> >> Hi All,
> >>
> >> Here is a driver for Maxim 3110 SPI-UART device, please help to
> >> review.
> >>
> >> It has been validated with Designware SPI controller (drivers/spi:
> >> dw_spi.c & dw_spi_pci.c). It supports polling and IRQ mode,
> >> supports batch read, and provides a console.
> >>

> > I wonder if this is an "spi" subsystem thing or a "serial" subsystem
> > thing.  It looks more like a serial driver to me.
> 
> I'm assuming serial; and hence I haven't picked it up into my tree.
> 
> g.

Yes, it's more related to serial stuff, and thus I put them into
drivers/serial

Thanks,
Feng

--
The Planet: dedicated and managed hosting, cloud storage, colocation
Stay online with enterprise data centers and the best network in the business
Choose flexible plans and management services without long-term contracts
Personal 24x7 support from experience hosting pros just a phone call away.
http://p.sf.net/sfu/theplanet-com
___
spi-devel-general mailing list
spi-devel-general@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/spi-devel-general


Re: [spi-devel-general] [RFC][PATCH v2] serial: spi: add spi-uart driver for Maxim 3110

2010-02-08 Thread Grant Likely
On Mon, Feb 8, 2010 at 5:20 PM, Andrew Morton  wrote:
> On Mon, 8 Feb 2010 16:59:46 +0800
> Feng Tang  wrote:
>
>> Hi All,
>>
>> Here is a driver for Maxim 3110 SPI-UART device, please help to review.
>>
>> It has been validated with Designware SPI controller (drivers/spi: dw_spi.c &
>> dw_spi_pci.c). It supports polling and IRQ mode, supports batch read, and
>> provides a console.
>>
>> change since v1:
>>       * Address comments from Alan Cox
>>       * Use a "use_irq" module parameter to runtime check whether
>>         to use IRQ mode
>>       * Add the suspend/resume implementation
>>
>> Thanks!
>> Feng
>>
>> >From 6d14c5d68cdae8d48b6d8a00b6653022f2b100d0 Mon Sep 17 00:00:00 2001
>> From: Feng Tang 
>> Date: Mon, 8 Feb 2010 16:02:59 +0800
>> Subject: [PATCH] serial: spi: add spi-uart driver for Maxim 3110
>>
>> This is the driver for Max3110 SPI-UART device, which connect
>> to host with SPI interface. It supports baud rates from 300 to
>> 230400, and supports both polling and IRQ mode, as well as
>> providing a console for system use
>>
>> Its datasheet could be found here:
>> http://datasheets.maxim-ic.com/en/ds/MAX3110E-MAX3111E.pdf
>>
>
> I wonder if this is an "spi" subsystem thing or a "serial" subsystem
> thing.  It looks more like a serial driver to me.

I'm assuming serial; and hence I haven't picked it up into my tree.

g.

--
The Planet: dedicated and managed hosting, cloud storage, colocation
Stay online with enterprise data centers and the best network in the business
Choose flexible plans and management services without long-term contracts
Personal 24x7 support from experience hosting pros just a phone call away.
http://p.sf.net/sfu/theplanet-com
___
spi-devel-general mailing list
spi-devel-general@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/spi-devel-general