summaryrefslogtreecommitdiff
path: root/meta-moblin/packages/linux/linux-moblin-2.6.33.2/linux-2.6.34-moorestown-ifxgps-driver.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-moblin/packages/linux/linux-moblin-2.6.33.2/linux-2.6.34-moorestown-ifxgps-driver.patch')
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.33.2/linux-2.6.34-moorestown-ifxgps-driver.patch1648
1 files changed, 0 insertions, 1648 deletions
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.33.2/linux-2.6.34-moorestown-ifxgps-driver.patch b/meta-moblin/packages/linux/linux-moblin-2.6.33.2/linux-2.6.34-moorestown-ifxgps-driver.patch
deleted file mode 100644
index f23aec3c6..000000000
--- a/meta-moblin/packages/linux/linux-moblin-2.6.33.2/linux-2.6.34-moorestown-ifxgps-driver.patch
+++ /dev/null
@@ -1,1648 +0,0 @@
-Index: linux-2.6.33/drivers/spi/Kconfig
-===================================================================
---- linux-2.6.33.orig/drivers/spi/Kconfig
-+++ linux-2.6.33/drivers/spi/Kconfig
-@@ -339,6 +339,10 @@ config SPI_MRST_GTM501
- tristate "SPI protocol driver for GTM501l"
- depends on SPI_MRST
-
-+config SPI_IFX_GPS
-+ tristate "SPI protocol driver for IFX HH2 GPS"
-+ depends on SPI_MRST
-+
- config SPI_SPIDEV
- tristate "User mode SPI device driver support"
- depends on EXPERIMENTAL
-Index: linux-2.6.33/drivers/spi/Makefile
-===================================================================
---- linux-2.6.33.orig/drivers/spi/Makefile
-+++ linux-2.6.33/drivers/spi/Makefile
-@@ -44,6 +44,7 @@ obj-$(CONFIG_SPI_STMP3XXX) += spi_stmp.
- obj-$(CONFIG_SPI_NUC900) += spi_nuc900.o
- obj-$(CONFIG_SPI_MRST) += mrst_spi.o
- obj-$(CONFIG_SPI_MRST_GTM501) += gtm501l_spi.o
-+obj-$(CONFIG_SPI_IFX_GPS) += hh2serial.o
-
- # special build for s3c24xx spi driver with fiq support
- spi_s3c24xx_hw-y := spi_s3c24xx.o
-Index: linux-2.6.33/drivers/spi/hh2serial.c
-===================================================================
---- /dev/null
-+++ linux-2.6.33/drivers/spi/hh2serial.c
-@@ -0,0 +1,1572 @@
-+/*
-+ * HH2 SPI Serial driver
-+ *
-+ * Copyright (C) 2009 Markus Burvall (Markus.Burvall@swedenconnectivity.com)
-+ *
-+ * 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, version 2 of the License.
-+ *
-+ */
-+
-+
-+#define DEBUG 1
-+
-+//#define HH2_TTY_ECHO
-+//#define HH2_TTY_SEND_POLL
-+//#define HH2_NO_SPI
-+#define HH2SERIAL_SPI_16BIT
-+//#define HH2SERIAL_ENABLE_DEBUG
-+#define HH2SERIAL_SPI_POLL
-+
-+
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/init.h>
-+
-+#include <linux/serial.h>
-+#include <linux/serial_core.h>
-+
-+#include <linux/kthread.h>
-+#include <linux/delay.h>
-+#include <asm/atomic.h>
-+
-+#ifndef HH2_NO_SPI
-+#include <linux/spi/spi.h>
-+#include <linux/spi/mrst_spi.h>
-+#endif
-+
-+MODULE_AUTHOR("Markus Burvall <Markus.Burvall@swedenconnectivity.com>");
-+MODULE_DESCRIPTION("HH2 Serial Driver");
-+MODULE_LICENSE("GPL");
-+MODULE_ALIAS("hh2serial");
-+
-+#ifdef HH2SERIAL_ENABLE_DEBUG
-+
-+#define FUNC_ENTER() do { printk("ENTER: %s\n", __func__); } while (0)
-+
-+#else
-+
-+#define FUNC_ENTER()
-+
-+#endif
-+
-+
-+struct hh2serial_dev {
-+ struct uart_port port;
-+ bool tx_enabled;
-+ bool rx_enabled;
-+ struct spi_device *spi;
-+
-+ struct task_struct *main_thread;
-+ struct task_struct *poll_thread;
-+
-+ wait_queue_head_t wq;
-+ atomic_t spi_need_read;
-+ atomic_t tty_need_read;
-+ atomic_t spi_irq_pending;
-+ int mthread_up;
-+};
-+
-+static const char driver_name[] = "hh2serial";
-+static const char tty_dev_name[] = "ttyHH2";
-+static struct hh2serial_dev priv0;
-+
-+
-+/* max len for a spi transfer is 18B */
-+#define HH2SERIAL_SPI_MAX_BYTES 18
-+/* 16 bits / byte + read and write gives 4*18 = 72 */
-+#define HH2SERIAL_BUFSIZE 72
-+
-+
-+#ifdef HH2SERIAL_SPI_POLL
-+#define HH2SERIAL_POLL_TIMEOUT 100
-+#endif
-+
-+/* HH2 DATA OPERATIONS */
-+#define GPSD_SRREAD 0x80 /* bit 7 */
-+#define GPSD_DWRITE 0x40 /* bit 6 */
-+#define GPSD_DREAD 0xC0 /* bit 7 and 6 */
-+#define GPSD_CRWRITE 0x00 /* All zero */
-+
-+#ifdef HH2SERIAL_SPI_16BIT
-+/* HH2 DATA OPERATIONS */
-+#define GPSD_16BIT_SRREAD 0x8000 /* bit 7 */
-+#define GPSD_16BIT_DWRITE 0x4000 /* bit 6 */
-+#define GPSD_16BIT_DREAD 0xC000 /* bit 7 and 6 */
-+#define GPSD_16BIT_CRWRITE 0x0000 /* All zero */
-+#endif
-+
-+/* HH2 STATUS REGISTER */
-+#define GPSS_TCNT 0x1F /* bits [4..0] */
-+#define GPSS_REMPTY 0x20 /* bit 5 */
-+#define GPSS_TERR 0x40 /* bit 6 */
-+#define GPSS_RERR 0x80 /* bit 7 */
-+
-+/* HH2 CONTROL REGISTER */
-+#define GPSC_ENABLE_TCNT_INTR 0x10 /* Enable Rx interrupt */
-+#define GPSC_ENABLE_REMPTY_INTR 0x20 /* Enable Tx interrupt */
-+#define GPSC_CLEAR_TERR 0x40 /* Clear TERR */
-+#define GPSC_CLEAR_RERR 0x80 /* Clear RERR */
-+#define GPSC_ENABLE_INTERRUPTS 0x30 /* Enable Interrupts through control register */
-+#define GPSC_DISABLE_INTERRUPTS 0x00 /* Disable Interrupts through control register */
-+
-+
-+/* ************************* */
-+
-+/*******************************************************************************
-+ * FUNCTION: hh2serial_stop_tx
-+ *
-+ * DESCRIPTION:
-+ *
-+ * PARAMETERS:
-+ *
-+ * RETURN:
-+ *
-+ ******************************************************************************/
-+static void hh2serial_stop_tx(struct uart_port *port)
-+{
-+ struct hh2serial_dev *priv = container_of(port, struct hh2serial_dev, port);
-+ FUNC_ENTER();
-+ priv->tx_enabled = false;
-+}
-+
-+
-+/*******************************************************************************
-+ * FUNCTION: hh2serial_spi_get_rx_len
-+ *
-+ * DESCRIPTION:
-+ *
-+ * PARAMETERS:
-+ *
-+ * RETURN:
-+ *
-+ ******************************************************************************/
-+#ifndef HH2_NO_SPI
-+/* Reads status register from HH2 */
-+/* Negative for error */
-+int hh2serial_spi_get_rx_len(struct hh2serial_dev *hh2serial)
-+{
-+ struct spi_device *spi = hh2serial->spi;
-+ int ret;
-+ struct spi_message message;
-+ struct spi_transfer x;
-+ u8 *local_buf;
-+ u8 *buf_ptr;
-+
-+ FUNC_ENTER();
-+
-+ spi_message_init(&message);
-+ memset(&x, 0, sizeof x);
-+#ifndef HH2SERIAL_SPI_16BIT
-+ x.len = 1;
-+#else
-+ x.len = 2;
-+#endif
-+ spi_message_add_tail(&x, &message);
-+
-+ local_buf = kzalloc((x.len * 2), GFP_KERNEL);
-+ if (!local_buf)
-+ return -ENOMEM;
-+
-+
-+#ifndef HH2SERIAL_SPI_16BIT
-+ local_buf[0] = GPSD_SRREAD;
-+#else /* if 16 bit, write control to get status */
-+ local_buf[1] = GPSD_CRWRITE;
-+ local_buf[0] = GPSC_CLEAR_TERR | GPSC_CLEAR_RERR;
-+ /*FIXME if not clearing errors */
-+ //local_buf[0] = 0;
-+#endif
-+ x.tx_buf = local_buf;
-+ x.rx_buf = local_buf + x.len;
-+
-+ x.cs_change = 0;
-+ x.speed_hz = 1562500;
-+
-+ /* do the i/o */
-+ ret = spi_sync(spi, &message);
-+ if (ret == 0)
-+ {
-+
-+ buf_ptr = x.rx_buf;
-+
-+#ifdef HH2SERIAL_ENABLE_DEBUG
-+ printk(KERN_INFO "hh2serial RD:%02X, %02X\n",
-+ *buf_ptr,
-+ buf_ptr[1]);
-+#endif
-+
-+#ifndef HH2SERIAL_SPI_16BIT
-+ /* 8 bit First byte is status register */
-+ /* Available bytes */
-+ ret = *buf_ptr & GPSS_TCNT;
-+
-+ /* Check buffer overrun or underrun errors */
-+ if (*buf_ptr & GPSS_TERR)
-+ printk(KERN_INFO "hh2serial HH2 transmitter underrun!\n");
-+
-+ if (*buf_ptr & GPSS_RERR)
-+ printk(KERN_INFO "hh2serial HH2 receiver overrun!\n");
-+
-+#else
-+ /* 16 bit second byte is status register */
-+ /* Available bytes */
-+ ret = buf_ptr[1] & GPSS_TCNT;
-+
-+ /* Check buffer overrun or underrun errors */
-+ if (buf_ptr[1] & GPSS_TERR)
-+ printk(KERN_INFO "hh2serial HH2 transmitter underrun!\n");
-+
-+ if (buf_ptr[1] & GPSS_RERR)
-+ printk(KERN_INFO "hh2serial HH2 receiver overrun!\n");
-+#endif
-+ /* Take care of errors */
-+ /* FIX ME */
-+
-+#ifdef HH2SERIAL_ENABLE_DEBUG
-+ printk(KERN_INFO "hh2serial SR:%02X, rx len %d\n",
-+ buf_ptr[1],
-+ ret);
-+#endif
-+ }
-+
-+ kfree(local_buf);
-+ return ret;
-+
-+}
-+#endif
-+
-+/*******************************************************************************
-+ * FUNCTION: hh2serial_spi_read
-+ *
-+ * DESCRIPTION:
-+ *
-+ * PARAMETERS:
-+ *
-+ * RETURN:
-+ *
-+ ******************************************************************************/
-+#ifndef HH2_NO_SPI
-+/* Reads maximum 18 bytes of data from SPI buffer */
-+int hh2serial_spi_read(struct hh2serial_dev *hh2serial,
-+ u8 *rxbuf, u8 *spiAvailData, unsigned len)
-+{
-+ struct spi_device *spi = hh2serial->spi;
-+ int status, available_rd;
-+ struct spi_message message;
-+ struct spi_transfer x;
-+ u8 *local_buf;
-+ u8 *buf_ptr;
-+ unsigned len_inc_hdr;
-+
-+ FUNC_ENTER();
-+ /* FIXME check header */
-+ if ((len * 2) > HH2SERIAL_BUFSIZE || !rxbuf)
-+ return -EINVAL;
-+
-+ spi_message_init(&message);
-+ memset(&x, 0, sizeof x);
-+
-+ /* Add header length */
-+#ifndef HH2SERIAL_SPI_16BIT
-+ len_inc_hdr = len+1;
-+#else
-+ len_inc_hdr = len;
-+#endif
-+
-+ x.len = len_inc_hdr;
-+ spi_message_add_tail(&x, &message);
-+
-+ local_buf = kzalloc(HH2SERIAL_BUFSIZE, GFP_KERNEL);
-+ if (!local_buf)
-+ return -ENOMEM;
-+
-+ /* Add DATA READ as every second byte */
-+ local_buf[1] = GPSD_DREAD;
-+#ifdef HH2SERIAL_SPI_16BIT
-+ if (len_inc_hdr > 2)
-+ {
-+ int byte_index = 1;
-+ while (byte_index < len_inc_hdr)
-+ {
-+ local_buf[byte_index] = GPSD_DREAD;
-+ byte_index = byte_index + 2;
-+ }
-+ }
-+
-+#endif
-+
-+ x.tx_buf = local_buf;
-+ x.rx_buf = local_buf + len_inc_hdr;
-+
-+
-+ x.cs_change = 0;
-+ x.speed_hz = 1562500;
-+
-+#ifdef HH2SERIAL_ENABLE_DEBUG
-+ if (len > 0)
-+ {
-+ int byte_index = 0;
-+ printk(KERN_INFO "hh2serial_spi_read:\n:wr data");
-+ while (byte_index < len_inc_hdr)
-+ {
-+ printk(KERN_INFO "%02X", (local_buf[byte_index++]));
-+ }
-+
-+ printk(KERN_INFO "\n");
-+
-+
-+ }
-+#endif
-+ /* do the i/o */
-+ status = spi_sync(spi, &message);
-+ if (status == 0)
-+ {
-+ /* First byte of read data */
-+ buf_ptr = x.rx_buf;
-+
-+#ifndef HH2SERIAL_SPI_16BIT
-+ /* 8 bit First byte is status register */
-+ /* Available bytes */
-+ available_rd = *buf_ptr & GPSS_TCNT;
-+
-+ /* Check buffer overrun or underrun errors */
-+ if (*buf_ptr & GPSS_TERR)
-+ printk(KERN_INFO "hh2serial HH2 transmitter underrun!\n");
-+
-+ if (*buf_ptr & GPSS_RERR)
-+ printk(KERN_INFO "hh2serial HH2 receiver overrun!\n");
-+#else
-+ /* 16 bit second byte is status register */
-+ /* Every other byte is status register */
-+ /* Last status register contains Available bytes at end of op*/
-+ /* This is status before the last byte is read, so -1 */
-+ available_rd = (buf_ptr[len_inc_hdr-1] & GPSS_TCNT) - 1;
-+
-+ /* Check buffer overrun or underrun errors */
-+ if (buf_ptr[len_inc_hdr-1] & GPSS_TERR)
-+ printk(KERN_INFO "hh2serial HH2 transmitter underrun!\n");
-+
-+ if (buf_ptr[len_inc_hdr-1] & GPSS_RERR)
-+ printk(KERN_INFO "hh2serial HH2 receiver overrun!\n");
-+#endif
-+
-+
-+#ifdef HH2SERIAL_ENABLE_DEBUG
-+ printk(KERN_INFO "hh2serial_spi_read len inc hdr wr:%d, avail rd %d, cs_change:%d\n",
-+ len_inc_hdr,
-+ available_rd,
-+ x.cs_change);
-+ printk(KERN_INFO "hh2serial_spi_read:%02X, %02X\n",
-+ *buf_ptr,
-+ buf_ptr[1]);
-+
-+#endif
-+
-+ /* Don't copy status byte */
-+#ifndef HH2SERIAL_SPI_16BIT
-+ buf_ptr++;
-+#endif
-+
-+ *spiAvailData = available_rd;
-+ memcpy(rxbuf, buf_ptr, len);
-+
-+ /* Print incoming message */
-+#ifdef HH2SERIAL_ENABLE_DEBUG
-+ if (len > 0)
-+ {
-+ int byte_index = 0;
-+ printk(KERN_INFO "hh2serial_spi_read:\n:rd data");
-+ while (byte_index < len)
-+ {
-+ printk(KERN_INFO "%02X", (rxbuf[byte_index++]));
-+ }
-+ printk(KERN_INFO "\n");
-+
-+ }
-+#endif
-+
-+ }
-+
-+ kfree(local_buf);
-+ return status;
-+}
-+#endif
-+
-+/*******************************************************************************
-+ * FUNCTION: hh2serial_spi_write
-+ *
-+ * DESCRIPTION:
-+ *
-+ * PARAMETERS:
-+ *
-+ * RETURN:
-+ *
-+ ******************************************************************************/
-+#ifndef HH2_NO_SPI
-+int hh2serial_spi_write(struct hh2serial_dev *hh2serial,
-+ const u8 *txbuf, u8 *spiAvailData, unsigned len)
-+{
-+ struct spi_device *spi = hh2serial->spi;
-+ int status, available_rd;
-+ struct spi_message message;
-+ struct spi_transfer x;
-+ u8 *local_buf;
-+ u8 *buf_ptr;
-+ unsigned len_inc_hdr;
-+
-+ FUNC_ENTER();
-+
-+ if ((len * 2) > HH2SERIAL_BUFSIZE )
-+ return -EINVAL;
-+
-+
-+ spi_message_init(&message);
-+ memset(&x, 0, sizeof x);
-+
-+ /* Add header length */
-+#ifndef HH2SERIAL_SPI_16BIT
-+ len_inc_hdr = len+1;
-+#else
-+ len_inc_hdr = len;
-+#endif
-+
-+ x.len = len_inc_hdr;
-+ spi_message_add_tail(&x, &message);
-+
-+ /* Allocate and make room for 1 byte header */
-+ local_buf = kzalloc(HH2SERIAL_BUFSIZE+1, GFP_KERNEL);
-+ if (!local_buf)
-+ return -ENOMEM;
-+
-+ /* Add write header */
-+ local_buf[1] = GPSD_DWRITE;
-+ local_buf[0] = txbuf[0];
-+
-+
-+#ifndef HH2SERIAL_SPI_16BIT
-+ memcpy(&(local_buf[1]), txbuf, len);
-+#else
-+ if (len_inc_hdr > 2)
-+ {
-+ int byte_index = 2;
-+ while (byte_index < len_inc_hdr)
-+ {
-+
-+ local_buf[byte_index] = txbuf[byte_index];
-+ local_buf[byte_index+1] = GPSD_DWRITE;
-+ byte_index = byte_index + 2;
-+ }
-+ }
-+#endif
-+
-+ x.tx_buf = local_buf;
-+ x.rx_buf = local_buf +(len_inc_hdr);
-+
-+ x.cs_change = 0;
-+ x.speed_hz = 1562500;
-+
-+#ifdef HH2SERIAL_ENABLE_DEBUG
-+ if (len > 0)
-+ {
-+ int byte_index = 0;
-+ printk(KERN_INFO "hh2serial_spi_write:\n:wr data");
-+ while (byte_index < len_inc_hdr)
-+ {
-+ printk(KERN_INFO "%02X", (local_buf[byte_index++]));
-+ }
-+ printk(KERN_INFO "\n");
-+
-+
-+ }
-+#endif
-+
-+ /* do the i/o */
-+ status = spi_sync(spi, &message);
-+ if (status == 0)
-+ {
-+ /* read data */
-+ buf_ptr = x.rx_buf;
-+
-+#ifndef HH2SERIAL_SPI_16BIT
-+ /* 8 bit First byte is status register */
-+ /* Available bytes */
-+ available_rd = *buf_ptr & GPSS_TCNT;
-+
-+ /* Check buffer overrun or underrun errors */
-+ if (*buf_ptr & GPSS_TERR)
-+ printk(KERN_INFO "hh2serial HH2 transmitter underrun!\n");
-+
-+ if (*buf_ptr & GPSS_RERR)
-+ printk(KERN_INFO "hh2serial HH2 receiver overrun!\n");
-+#else
-+ /* 16 bit second byte is status register */
-+ /* Available bytes */
-+ available_rd = buf_ptr[1] & GPSS_TCNT;
-+
-+ /* Check buffer overrun or underrun errors */
-+ if (buf_ptr[1] & GPSS_TERR)
-+ printk(KERN_INFO "hh2serial HH2 transmitter underrun!\n");
-+
-+ if (buf_ptr[1] & GPSS_RERR)
-+ printk(KERN_INFO "hh2serial HH2 receiver overrun!\n");
-+#endif
-+
-+
-+#ifdef HH2SERIAL_ENABLE_DEBUG
-+ printk(KERN_INFO "hh2serial_spi_write:%02X, %02X\n",
-+ *buf_ptr,
-+ buf_ptr[1]);
-+
-+ printk(KERN_INFO "hh2serial_spi_write: wr:%d, avail rd %d\n",
-+ len,
-+ available_rd);
-+#endif
-+
-+ *spiAvailData = available_rd;
-+
-+
-+ }
-+
-+
-+
-+ kfree(local_buf);
-+ return status;
-+}
-+#endif
-+
-+/*******************************************************************************
-+ * FUNCTION: hh2serial_write2tty
-+ *
-+ * DESCRIPTION:
-+ *
-+ * PARAMETERS:
-+ *
-+ * RETURN:
-+ *
-+ ******************************************************************************/
-+static void hh2serial_write2tty(
-+ struct hh2serial_dev *priv, unsigned char *str, int len)
-+{
-+ struct uart_port *port = &priv->port;
-+ struct tty_struct *tty;
-+ int usable;
-+
-+ FUNC_ENTER();
-+
-+ /* if uart is not opened, will just return */
-+ if (!port->state)
-+ return;
-+
-+ tty = port->state->port.tty;
-+ if (!tty)
-+ return; /* receive some char before the tty is opened */
-+
-+ /* MRB could lock forever if no space in tty buffer */
-+ while (len) {
-+ usable = tty_buffer_request_room(tty, len);
-+ if (usable) {
-+#ifdef HH2SERIAL_ENABLE_DEBUG
-+ printk(KERN_INFO "hh2serial_output_tty buf space: %d\n", usable);
-+#endif
-+ tty_insert_flip_string(tty, str, usable);
-+ str += usable;
-+ port->icount.rx += usable;
-+ tty_flip_buffer_push(tty);
-+ }
-+ len -= usable;
-+ }
-+}
-+
-+/*******************************************************************************
-+ * FUNCTION: hh2serial_write_circ_buf2spi
-+ *
-+ * DESCRIPTION:
-+ *
-+ * PARAMETERS:
-+ *
-+ * RETURN:
-+ *
-+ ******************************************************************************/
-+#ifndef HH2_NO_SPI
-+static inline void hh2serial_write_circ_buf2spi(struct hh2serial_dev *priv,
-+ struct circ_buf *xmit)
-+{
-+ int len, left = 0;
-+#ifndef HH2SERIAL_SPI_16BIT
-+ u8 obuf[HH2SERIAL_SPI_MAX_BYTES], ibuf[HH2SERIAL_SPI_MAX_BYTES];
-+#else
-+ u16 obuf[HH2SERIAL_SPI_MAX_BYTES], ibuf[HH2SERIAL_SPI_MAX_BYTES];
-+#endif
-+ u8 rxlen;
-+ u8 valid_str[HH2SERIAL_SPI_MAX_BYTES];
-+
-+ int i, j;
-+
-+ FUNC_ENTER();
-+
-+ while (!uart_circ_empty(xmit)) {
-+ /*
-+ printk(KERN_INFO "MrB set CR get SR: %d\n",
-+ hh2serial_spi_get_rx_len(priv));
-+ */
-+
-+ left = uart_circ_chars_pending(xmit);
-+#ifdef HH2SERIAL_ENABLE_DEBUG
-+ printk(KERN_INFO "Bytes in circ buffer: %d\n", left);
-+#endif
-+ while (left) {
-+ /* MrB Change below to 1 and word length to 16 to write 16 bit
-+ word by word */
-+#ifndef HH2SERIAL_SPI_16BIT
-+ len = (left >= HH2SERIAL_SPI_MAX_BYTES) ? HH2SERIAL_SPI_MAX_BYTES : left;
-+#else
-+ len = (left >= HH2SERIAL_SPI_MAX_BYTES) ? HH2SERIAL_SPI_MAX_BYTES : left;
-+#endif
-+
-+ memset(obuf, 0, len);
-+ memset(ibuf, 0, len);
-+ for (i = 0; i < len; i++) {
-+
-+ obuf[i] = (u8)xmit->buf[xmit->tail];
-+
-+ xmit->tail = (xmit->tail + 1) &
-+ (UART_XMIT_SIZE - 1);
-+ }
-+#ifndef HH2SERIAL_SPI_16BIT
-+
-+ hh2serial_spi_write(priv, (u8 *)obuf,
-+ &rxlen, len);
-+
-+#else
-+ /* len * 2 since 16 bits instead of 8 bits */
-+ hh2serial_spi_write(priv, (u8 *)obuf,
-+ &rxlen, len*2);
-+
-+#endif
-+ left -= len;
-+ }
-+#ifdef HH2SERIAL_ENABLE_DEBUG
-+ printk(KERN_INFO "hh2serial: Bytes avail to read: %d\n", rxlen);
-+#endif
-+ /* Read if available bytes */
-+ /* FIXME: Could add a maximum read loop here */
-+ while (rxlen > 0)
-+ {
-+
-+ len = rxlen;
-+#ifndef HH2SERIAL_SPI_16BIT
-+ hh2serial_spi_read(priv, (u8 *)ibuf, &rxlen, len);
-+#else
-+ hh2serial_spi_read(priv, (u8 *)ibuf, &rxlen, len*2);
-+#endif
-+
-+ for (i = 0, j = 0; i < len; i++) {
-+ valid_str[j++] = (u8)(ibuf[i]);
-+ }
-+
-+ if (j)
-+ hh2serial_write2tty(priv, valid_str, j);
-+
-+ priv->port.icount.tx += len;
-+ }
-+ }
-+}
-+#endif
-+
-+
-+/*******************************************************************************
-+ * FUNCTION: hh2serial_handle_tty_input
-+ *
-+ * DESCRIPTION:
-+ *
-+ * PARAMETERS:
-+ *
-+ * RETURN:
-+ *
-+ ******************************************************************************/
-+static void hh2serial_handle_tty_input(struct hh2serial_dev *priv)
-+{
-+ struct uart_port *port = &priv->port;
-+ struct circ_buf *xmit = &port->state->xmit;
-+
-+ FUNC_ENTER();
-+
-+ if (uart_circ_empty(xmit) || uart_tx_stopped(port))
-+ return;
-+#ifndef HH2_NO_SPI
-+ hh2serial_write_circ_buf2spi(priv, xmit);
-+#endif
-+ if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
-+ uart_write_wakeup(port);
-+
-+ if (uart_circ_empty(xmit))
-+ hh2serial_stop_tx(port);
-+}
-+
-+/*******************************************************************************
-+ * FUNCTION: hh2serial_transfer_spi2tty
-+ *
-+ * DESCRIPTION:
-+ *
-+ * PARAMETERS:
-+ *
-+ * RETURN:
-+ *
-+ ******************************************************************************/
-+static void hh2serial_transfer_spi2tty(struct hh2serial_dev *priv)
-+{
-+ int loop = 10, len;
-+ int i, j;
-+ u8 valid_str[HH2SERIAL_SPI_MAX_BYTES], rxlen = 0;
-+#ifndef HH2SERIAL_SPI_16BIT
-+ u8 ibuf[HH2SERIAL_SPI_MAX_BYTES];
-+#else
-+ u16 ibuf[HH2SERIAL_SPI_MAX_BYTES];
-+#endif
-+
-+ FUNC_ENTER();
-+
-+ rxlen = hh2serial_spi_get_rx_len(priv);
-+
-+ /* FIXME No of loops to be investigated */
-+ while (rxlen > 0 && loop > 0)
-+ {
-+
-+ len = rxlen;
-+#ifndef HH2SERIAL_SPI_16BIT
-+ hh2serial_spi_read(priv, (u8 *)ibuf, &rxlen, len);
-+#else
-+ hh2serial_spi_read(priv, (u8 *)ibuf, &rxlen, len*2);
-+#endif
-+
-+ for (i = 0, j = 0; i < len; i++) {
-+ valid_str[j++] = (u8)(ibuf[i]);
-+ }
-+
-+ if (j)
-+ hh2serial_write2tty(priv, valid_str, j);
-+
-+ priv->port.icount.tx += len;
-+
-+ loop--;
-+ }
-+
-+}
-+
-+
-+/*******************************************************************************
-+ * FUNCTION: hh2serial_main_thread
-+ *
-+ * DESCRIPTION:
-+ *
-+ * PARAMETERS:
-+ *
-+ * RETURN:
-+ *
-+ ******************************************************************************/
-+static int hh2serial_main_thread(void *_priv)
-+{
-+ struct hh2serial_dev *priv = _priv;
-+ wait_queue_head_t *wq = &priv->wq;
-+
-+ int ret = 0;
-+
-+#ifdef HH2SERIAL_ENABLE_DEBUG
-+ printk(KERN_INFO "hh2serial: start main thread\n");
-+#endif
-+ init_waitqueue_head(wq);
-+
-+ do {
-+ //udelay(delay);
-+ wait_event_interruptible(*wq, (atomic_read(&priv->spi_irq_pending) ||
-+ atomic_read(&priv->spi_need_read) ||
-+ atomic_read(&priv->tty_need_read) ||
-+ kthread_should_stop()));
-+
-+ priv->mthread_up = 1;
-+
-+ /* tty has data to be read */
-+ if (atomic_read(&priv->tty_need_read)) {
-+ atomic_set(&priv->tty_need_read, 0);
-+ /* Read from tty send to spi */
-+#ifdef HH2SERIAL_ENABLE_DEBUG
-+ printk(KERN_INFO "hh2serial: Read from tty send to spi\n");
-+#endif
-+ /* Read from tty send to spi */
-+ /* Receive data from spi send to UART */
-+
-+ hh2serial_handle_tty_input(priv);
-+
-+ }
-+
-+#ifdef HH2SERIAL_SPI_POLL
-+ if (atomic_read(&priv->spi_need_read)) {
-+ atomic_set(&priv->spi_need_read, 0);
-+ /* Read from SPI send to UART */
-+#ifdef HH2SERIAL_ENABLE_DEBUG
-+ printk(KERN_INFO "hh2serial: Read from SPI send to UART\n");
-+#endif
-+#ifndef HH2_TTY_SEND_POLL
-+ hh2serial_transfer_spi2tty(priv);
-+#else
-+ if (priv->tx_enabled) {
-+ struct uart_port *port = &priv->port;
-+#ifdef HH2SERIAL_ENABLE_DEBUG
-+ printk("TX enabled!\n");
-+#endif
-+ spin_lock_irqsave(&port->lock, flags);
-+
-+
-+ if (priv->rx_enabled) {
-+#ifdef HH2SERIAL_ENABLE_DEBUG
-+ printk(KERN_INFO "RX enabled!\n");
-+#endif
-+ hh2serial_write2tty(priv, "testar", 6);
-+ }
-+
-+
-+ spin_unlock_irqrestore(&port->lock, flags);
-+ }
-+#endif /* HH2_TTY_SEND_POLL */
-+
-+ }
-+#endif
-+
-+
-+
-+ if (atomic_read(&priv->spi_irq_pending)) {
-+ atomic_set(&priv->spi_irq_pending, 0);
-+ /* Read from SPI send to UART */
-+#ifdef HH2SERIAL_ENABLE_DEBUG
-+ printk(KERN_INFO "hh2serial: Read from SPI send to UART\n");
-+#endif
-+ }
-+
-+
-+ priv->mthread_up = 0;
-+ } while (!kthread_should_stop());
-+#ifdef HH2SERIAL_ENABLE_DEBUG
-+ printk(KERN_INFO "hh2serial: stopped main thread\n");
-+#endif
-+ return ret;
-+}
-+
-+/*******************************************************************************
-+ * FUNCTION: hh2serial_poll_thread
-+ *
-+ * DESCRIPTION:
-+ *
-+ * PARAMETERS:
-+ *
-+ * RETURN:
-+ *
-+ ******************************************************************************/
-+#ifdef HH2SERIAL_SPI_POLL
-+static int hh2serial_poll_thread(void *_priv)
-+{
-+
-+ int ret = 0;
-+ struct hh2serial_dev *priv = _priv;
-+
-+#ifdef HH2SERIAL_ENABLE_DEBUG
-+ printk(KERN_INFO "hh2serial: start poll thread\n");
-+#endif
-+ do {
-+ //udelay(delay);
-+
-+ if (HH2SERIAL_POLL_TIMEOUT > 999)
-+ ssleep(HH2SERIAL_POLL_TIMEOUT/1000);
-+ else
-+ msleep(HH2SERIAL_POLL_TIMEOUT);
-+#ifdef HH2SERIAL_ENABLE_DEBUG
-+ printk(KERN_INFO "hh2serial: poll\n");
-+#endif
-+ if (!priv->mthread_up)
-+ {
-+ /* Send poll event to main */
-+ if (!atomic_read(&priv->spi_need_read)) {
-+ atomic_set(&priv->spi_need_read, 1);
-+ wake_up_process(priv->main_thread);
-+ }
-+ }
-+
-+ } while (!kthread_should_stop());
-+#ifdef HH2SERIAL_ENABLE_DEBUG
-+ printk(KERN_INFO "hh2serial: stopped poll thread\n");
-+#endif
-+ return ret;
-+}
-+#endif /* #ifdef HH2SERIAL_SPI_POLL */
-+
-+/*******************************************************************************
-+ * FUNCTION: hh2serial_tx_empty
-+ *
-+ * DESCRIPTION:
-+ *
-+ * PARAMETERS:
-+ *
-+ * RETURN:
-+ *
-+ ******************************************************************************/
-+static unsigned int hh2serial_tx_empty(struct uart_port *port)
-+{
-+ FUNC_ENTER();
-+ return TIOCSER_TEMT;
-+}
-+
-+/*******************************************************************************
-+ * FUNCTION: hh2serial_set_mctrl
-+ *
-+ * DESCRIPTION:
-+ *
-+ * PARAMETERS:
-+ *
-+ * RETURN:
-+ *
-+ ******************************************************************************/
-+static void hh2serial_set_mctrl(struct uart_port *port, unsigned int mctrl)
-+{
-+ FUNC_ENTER();
-+
-+#ifdef HH2SERIAL_ENABLE_DEBUG
-+ printk("MCTRL RTS: %d\n", mctrl & TIOCM_RTS);
-+ printk("MCTRL DTR: %d\n", mctrl & TIOCM_DTR);
-+ printk("MCTRL OUT1: %d\n", mctrl & TIOCM_OUT1);
-+ printk("MCTRL OUT2: %d\n", mctrl & TIOCM_OUT2);
-+ printk("MCTRL LOOP: %d\n", mctrl & TIOCM_LOOP);
-+#endif
-+}
-+
-+/*******************************************************************************
-+ * FUNCTION: hh2serial_get_mctrl
-+ *
-+ * DESCRIPTION:
-+ *
-+ * PARAMETERS:
-+ *
-+ * RETURN:
-+ *
-+ ******************************************************************************/
-+static unsigned int hh2serial_get_mctrl(struct uart_port *port)
-+{
-+ FUNC_ENTER();
-+ return TIOCM_CAR | TIOCM_DSR | TIOCM_CTS;
-+}
-+
-+
-+/*******************************************************************************
-+ * FUNCTION: hh2serial_tx_chars
-+ *
-+ * DESCRIPTION:
-+ *
-+ * PARAMETERS:
-+ *
-+ * RETURN:
-+ *
-+ ******************************************************************************/
-+static void hh2serial_tx_chars(struct uart_port *port)
-+{
-+#ifndef HH2_TTY_ECHO
-+ struct hh2serial_dev *priv = container_of(port, struct hh2serial_dev, port);
-+
-+ FUNC_ENTER();
-+
-+ if (priv->tx_enabled) {
-+
-+ /* if writing to SPI enabled */
-+
-+ /* Send message to main thread to read from tty send to SPI */
-+ /* Send poll event to main */
-+ if (!atomic_read(&priv->tty_need_read)) {
-+ atomic_set(&priv->tty_need_read, 1);
-+ wake_up_process(priv->main_thread);
-+ }
-+
-+
-+ }
-+
-+#else
-+ struct hh2serial_dev *priv = container_of(port, struct hh2serial_dev, port);
-+ struct circ_buf *xmit = &port->state->xmit;
-+
-+
-+
-+ struct uart_port *recv_port = &priv->port;
-+ struct tty_struct *recv_tty;
-+
-+ unsigned long flags;
-+ char ch;
-+
-+ FUNC_ENTER();
-+
-+ if (priv->tx_enabled) {
-+#ifdef HH2SERIAL_ENABLE_DEBUG
-+ printk("TX enabled!\n");
-+#endif
-+ //spin_lock_irqsave(&other_port->lock, flags);
-+ if (priv->rx_enabled) {
-+#ifdef HH2SERIAL_ENABLE_DEBUG
-+ printk("RX enabled!\n");
-+#endif
-+
-+ recv_tty = recv_port->state->port.tty;
-+
-+ if (port->x_char) {
-+#ifdef HH2SERIAL_ENABLE_DEBUG
-+ printk("One char %c!\n", port->x_char);
-+#endif
-+ tty_insert_flip_char(recv_tty, port->x_char, TTY_NORMAL);
-+ tty_flip_buffer_push(recv_tty);
-+ port->icount.tx++;
-+ port->x_char = 0;
-+ return;
-+ }
-+
-+ if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
-+#ifdef HH2SERIAL_ENABLE_DEBUG
-+ pr_debug("STOP TX_CHARS 1\n");
-+#endif
-+ hh2serial_stop_tx(port);
-+ return;
-+ }
-+
-+ while (!uart_circ_empty(xmit)) {
-+
-+ ch = xmit->buf[xmit->tail];
-+ xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
-+#ifdef HH2SERIAL_ENABLE_DEBUG
-+ printk("Loop one char %c!\n", ch);
-+#endif
-+ tty_insert_flip_char(recv_tty, ch, TTY_NORMAL);
-+ tty_flip_buffer_push(recv_tty);
-+ port->icount.tx++;
-+ }
-+
-+ if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
-+ {
-+#ifdef HH2SERIAL_ENABLE_DEBUG
-+ printk("Uart wakeup!\n");
-+#endif
-+ uart_write_wakeup(port);
-+ }
-+
-+ if (uart_circ_empty(xmit)) {
-+#ifdef HH2SERIAL_ENABLE_DEBUG
-+ pr_debug("STOP TX_CHARS 2\n");
-+#endif
-+ hh2serial_stop_tx(port);
-+ }
-+ }
-+ else
-+ {
-+#ifdef HH2SERIAL_ENABLE_DEBUG
-+ printk("Other port disabled!\n");
-+#endif
-+ }
-+ //spin_unlock_irqrestore(&priv->other_priv->port.lock, flags);
-+ }
-+
-+#endif
-+
-+}
-+
-+/*******************************************************************************
-+ * FUNCTION: hh2serial_start_tx
-+ *
-+ * DESCRIPTION:
-+ *
-+ * PARAMETERS:
-+ *
-+ * RETURN:
-+ *
-+ ******************************************************************************/
-+static void hh2serial_start_tx(struct uart_port *port)
-+{
-+ struct hh2serial_dev *priv = container_of(port, struct hh2serial_dev, port);
-+ FUNC_ENTER();
-+ priv->tx_enabled = true;
-+
-+ hh2serial_tx_chars(port);
-+}
-+
-+/*******************************************************************************
-+ * FUNCTION: hh2serial_stop_rx
-+ *
-+ * DESCRIPTION:
-+ *
-+ * PARAMETERS:
-+ *
-+ * RETURN:
-+ *
-+ ******************************************************************************/
-+static void hh2serial_stop_rx(struct uart_port *port)
-+{
-+ struct hh2serial_dev *priv = container_of(port, struct hh2serial_dev, port);
-+ FUNC_ENTER();
-+ priv->rx_enabled = false;
-+}
-+
-+/*******************************************************************************
-+ * FUNCTION: hh2serial_enable_ms
-+ *
-+ * DESCRIPTION:
-+ *
-+ * PARAMETERS:
-+ *
-+ * RETURN:
-+ *
-+ ******************************************************************************/
-+static void hh2serial_enable_ms(struct uart_port *port)
-+{
-+ FUNC_ENTER();
-+}
-+
-+/*******************************************************************************
-+ * FUNCTION: hh2serial_break_ctl
-+ *
-+ * DESCRIPTION:
-+ *
-+ * PARAMETERS:
-+ *
-+ * RETURN:
-+ *
-+ ******************************************************************************/
-+static void hh2serial_break_ctl(struct uart_port *port, int break_state)
-+{
-+ FUNC_ENTER();
-+}
-+
-+/*******************************************************************************
-+ * FUNCTION: hh2serial_startup
-+ *
-+ * DESCRIPTION:
-+ *
-+ * PARAMETERS:
-+ *
-+ * RETURN:
-+ *
-+ ******************************************************************************/
-+static int hh2serial_startup(struct uart_port *port)
-+{
-+ struct hh2serial_dev *priv = container_of(port, struct hh2serial_dev, port);
-+ FUNC_ENTER();
-+
-+#ifdef HH2SERIAL_SPI_POLL
-+ priv->poll_thread = kthread_run(hh2serial_poll_thread,
-+ priv, "hh2serial_poll");
-+ if (IS_ERR(priv->poll_thread)) {
-+ printk(KERN_INFO "hh2serial Failed to start poll thread: %ld",
-+ PTR_ERR(priv->poll_thread));
-+ }
-+#endif
-+
-+ spin_lock(&port->lock);
-+ priv->rx_enabled = true;
-+ spin_unlock(&port->lock);
-+ return 0;
-+}
-+
-+/*******************************************************************************
-+ * FUNCTION: hh2serial_shutdown
-+ *
-+ * DESCRIPTION:
-+ *
-+ * PARAMETERS:
-+ *
-+ * RETURN:
-+ *
-+ ******************************************************************************/
-+static void hh2serial_shutdown(struct uart_port *port)
-+{
-+#ifdef HH2SERIAL_SPI_POLL
-+ struct hh2serial_dev *priv = container_of(port, struct hh2serial_dev, port);
-+#endif
-+ FUNC_ENTER();
-+#ifdef HH2SERIAL_SPI_POLL
-+ if (priv->poll_thread)
-+ kthread_stop(priv->poll_thread);
-+#endif
-+}
-+
-+/*******************************************************************************
-+ * FUNCTION: hh2serial_set_termios
-+ *
-+ * DESCRIPTION:
-+ *
-+ * PARAMETERS:
-+ *
-+ * RETURN:
-+ *
-+ ******************************************************************************/
-+static void hh2serial_set_termios(struct uart_port *port,
-+ struct ktermios *termios,
-+ struct ktermios *old)
-+{
-+ FUNC_ENTER();
-+
-+ switch (termios->c_cflag & CSIZE) {
-+ case CS5:
-+ pr_debug("CS5: data bits 5\n");
-+ break;
-+ case CS6:
-+ pr_debug("CS6: data bits 6\n");
-+ break;
-+ case CS7:
-+ pr_debug("CS7: data bits 7\n");
-+ break;
-+ case CS8:
-+ pr_debug("CS8: data bits 8\n");
-+ break;
-+ default:
-+ pr_debug("CS: Unknown\n");
-+ break;
-+ }
-+
-+ if (termios->c_cflag & PARENB) {
-+ if (termios->c_cflag & PARODD)
-+ pr_debug("PARITY ODD\n");
-+ else
-+ pr_debug("PARITY EVEN\n");
-+ } else {
-+ pr_debug("PARITY NONE\n");
-+ }
-+
-+ if (termios->c_cflag & CSTOPB)
-+ pr_debug("STOP BITS 2\n");
-+ else
-+ pr_debug("STOP BITS 1\n");
-+
-+ if (termios->c_cflag & CRTSCTS)
-+ pr_debug("RTS CTS ENABLED\n");
-+ else
-+ pr_debug("RTS CTS DISABLED\n");
-+}
-+
-+/*******************************************************************************
-+ * FUNCTION: hh2serial_type
-+ *
-+ * DESCRIPTION:
-+ *
-+ * PARAMETERS:
-+ *
-+ * RETURN:
-+ *
-+ ******************************************************************************/
-+static const char *hh2serial_type(struct uart_port *port)
-+{
-+ FUNC_ENTER();
-+ return "VUART";
-+}
-+
-+/*******************************************************************************
-+ * FUNCTION: hh2serial_request_port
-+ *
-+ * DESCRIPTION:
-+ *
-+ * PARAMETERS:
-+ *
-+ * RETURN:
-+ *
-+ ******************************************************************************/
-+static int hh2serial_request_port(struct uart_port *port)
-+{
-+ FUNC_ENTER();
-+ return 0;
-+}
-+
-+/*******************************************************************************
-+ * FUNCTION: hh2serial_config_port
-+ *
-+ * DESCRIPTION:
-+ *
-+ * PARAMETERS:
-+ *
-+ * RETURN:
-+ *
-+ ******************************************************************************/
-+static void hh2serial_config_port(struct uart_port *port, int flags)
-+{
-+ FUNC_ENTER();
-+
-+ if (flags & UART_CONFIG_TYPE)
-+ port->type = PORT_16550A;
-+}
-+
-+/*******************************************************************************
-+ * FUNCTION: hh2serial_release_port
-+ *
-+ * DESCRIPTION:
-+ *
-+ * PARAMETERS:
-+ *
-+ * RETURN:
-+ *
-+ ******************************************************************************/
-+static void hh2serial_release_port(struct uart_port *port)
-+{
-+ FUNC_ENTER();
-+}
-+
-+/*******************************************************************************
-+ * FUNCTION: hh2serial_verify_port
-+ *
-+ * DESCRIPTION:
-+ *
-+ * PARAMETERS:
-+ *
-+ * RETURN:
-+ *
-+ ******************************************************************************/
-+static int hh2serial_verify_port(struct uart_port *port, struct serial_struct *ser)
-+{
-+ FUNC_ENTER();
-+ return 0;
-+}
-+
-+static struct uart_ops hh2serial_uart_ops = {
-+ .tx_empty = hh2serial_tx_empty,
-+ .set_mctrl = hh2serial_set_mctrl,
-+ .get_mctrl = hh2serial_get_mctrl,
-+ .stop_tx = hh2serial_stop_tx,
-+ .start_tx = hh2serial_start_tx,
-+ .stop_rx = hh2serial_stop_rx,
-+ .enable_ms = hh2serial_enable_ms,
-+ .break_ctl = hh2serial_break_ctl,
-+ .startup = hh2serial_startup,
-+ .shutdown = hh2serial_shutdown,
-+ .set_termios = hh2serial_set_termios,
-+ .type = hh2serial_type,
-+ .release_port = hh2serial_release_port,
-+ .request_port = hh2serial_request_port,
-+ .config_port = hh2serial_config_port,
-+ .verify_port = hh2serial_verify_port,
-+};
-+
-+#ifndef HH2_NO_SPI
-+/* pure SPI related functions */
-+/*******************************************************************************
-+ * FUNCTION: serial_hh2serial_suspend
-+ *
-+ * DESCRIPTION:
-+ *
-+ * PARAMETERS:
-+ *
-+ * RETURN:
-+ *
-+ ******************************************************************************/
-+static int serial_hh2serial_suspend(struct spi_device *spi, pm_message_t state)
-+{
-+ FUNC_ENTER();
-+ return 0;
-+}
-+
-+/*******************************************************************************
-+ * FUNCTION: serial_hh2serial_resume
-+ *
-+ * DESCRIPTION:
-+ *
-+ * PARAMETERS:
-+ *
-+ * RETURN:
-+ *
-+ ******************************************************************************/
-+static int serial_hh2serial_resume(struct spi_device *spi)
-+{
-+ FUNC_ENTER();
-+ return 0;
-+}
-+
-+
-+static struct mrst_spi_chip hh2spi0 = {
-+ .poll_mode = 1,
-+ .enable_dma = 0,
-+ .type = SPI_FRF_SPI,
-+};
-+
-+
-+/*******************************************************************************
-+ * FUNCTION: serial_hh2serial_probe
-+ *
-+ * DESCRIPTION:
-+ *
-+ * PARAMETERS:
-+ *
-+ * RETURN:
-+ *
-+ ******************************************************************************/
-+static int serial_hh2serial_probe(struct spi_device *spi)
-+{
-+ FUNC_ENTER();
-+#ifndef HH2_NO_SPI
-+
-+ /* set spi info */
-+ spi->mode = SPI_MODE_0;
-+#ifndef HH2SERIAL_SPI_16BIT
-+ spi->bits_per_word = 8; /* HH2 uses 8 bits */
-+#else
-+ spi->bits_per_word = 16; /* HH2 uses 8 bits, test with 16, sends byte by byte */
-+#endif
-+
-+ spi->controller_data = &hh2spi0;
-+
-+ spi_setup(spi);
-+ priv0.spi = spi;
-+ atomic_set(&priv0.spi_irq_pending, 0);
-+#endif
-+
-+
-+ return 0;
-+
-+
-+}
-+
-+/*******************************************************************************
-+ * FUNCTION: hh2serial_remove
-+ *
-+ * DESCRIPTION:
-+ *
-+ * PARAMETERS:
-+ *
-+ * RETURN:
-+ *
-+ ******************************************************************************/
-+static int hh2serial_remove(struct spi_device *dev)
-+{
-+ FUNC_ENTER();
-+
-+ return 0;
-+}
-+
-+
-+static struct spi_driver spi_hh2serial_driver = {
-+ .driver = {
-+ .name = "spi_ifx_gps",
-+ //.name = "spi_flash",
-+ .bus = &spi_bus_type,
-+ .owner = THIS_MODULE,
-+ },
-+ .probe = serial_hh2serial_probe,
-+ .remove = __devexit_p(hh2serial_remove),
-+ .suspend = serial_hh2serial_suspend,
-+ .resume = serial_hh2serial_resume,
-+};
-+
-+#endif
-+
-+static struct uart_driver hh2serial_driver = {
-+ .owner = THIS_MODULE,
-+ .driver_name = driver_name,
-+ .dev_name = tty_dev_name,
-+ .major = 240,
-+ .minor = 0,
-+ .nr = 1,
-+};
-+
-+/*******************************************************************************
-+ * FUNCTION: __init
-+ *
-+ * DESCRIPTION:
-+ *
-+ * PARAMETERS:
-+ *
-+ * RETURN:
-+ *
-+ ******************************************************************************/
-+static int __init
-+hh2serial_init (void)
-+{
-+ int ret;
-+
-+ ret = uart_register_driver(&hh2serial_driver);
-+
-+ if (ret) {
-+ pr_err("%s: could not register UART driver\n", driver_name);
-+ goto out_register_driver;
-+ }
-+
-+ memset(&priv0, sizeof(struct hh2serial_dev), 0);
-+ priv0.port.line = 0;
-+ priv0.port.ops = &hh2serial_uart_ops;
-+ priv0.port.type = PORT_16550A;
-+ spin_lock_init(&priv0.port.lock);
-+
-+ ret = uart_add_one_port(&hh2serial_driver, &priv0.port);
-+
-+ if (ret) {
-+ pr_err("%s: could not add port hh2serial0\n", driver_name);
-+ goto out_add_port0;
-+ }
-+
-+ atomic_set(&priv0.spi_need_read, 0);
-+ atomic_set(&priv0.tty_need_read, 0);
-+ atomic_set(&priv0.spi_irq_pending, 0);
-+
-+
-+
-+#ifndef HH2_NO_SPI
-+ /* Register SPI device driver*/
-+ ret = spi_register_driver(&spi_hh2serial_driver);
-+ if (ret)
-+ {
-+ pr_err("%s: could not register driver spi_hh2serial_driver\n", driver_name);
-+ goto out_add_spi;
-+ }
-+#endif
-+
-+
-+ priv0.main_thread = kthread_run(hh2serial_main_thread,
-+ &priv0, "hh2serial_main");
-+ if (IS_ERR(priv0.main_thread)) {
-+ ret = PTR_ERR(priv0.main_thread);
-+ goto err_kthread;
-+ }
-+
-+
-+
-+ printk ("Module %s loaded\n", driver_name);
-+ return 0;
-+
-+err_kthread:
-+
-+#ifndef HH2_NO_SPI
-+out_add_spi:
-+ uart_remove_one_port(&hh2serial_driver, &priv0.port);
-+#endif
-+out_add_port0:
-+ uart_unregister_driver(&hh2serial_driver);
-+out_register_driver:
-+ return ret;
-+}
-+
-+/*******************************************************************************
-+ * FUNCTION: __exit
-+ *
-+ * DESCRIPTION:
-+ *
-+ * PARAMETERS:
-+ *
-+ * RETURN:
-+ *
-+ ******************************************************************************/
-+static void __exit
-+hh2serial_exit (void)
-+{
-+ if (priv0.main_thread)
-+ kthread_stop(priv0.main_thread);
-+
-+#ifndef HH2_NO_SPI
-+ /* unregister SPI driver */
-+ spi_unregister_driver(&spi_hh2serial_driver);
-+#endif
-+ uart_remove_one_port(&hh2serial_driver, &priv0.port);
-+
-+ uart_unregister_driver(&hh2serial_driver);
-+ printk ("Module %s removed\n", driver_name);
-+}
-+
-+
-+
-+module_init(hh2serial_init);
-+module_exit(hh2serial_exit);
-Index: linux-2.6.33/drivers/misc/intel_mrst.c
-===================================================================
---- linux-2.6.33.orig/drivers/misc/intel_mrst.c
-+++ linux-2.6.33/drivers/misc/intel_mrst.c
-@@ -131,9 +131,11 @@ static int intel_mrst_bringup_8688_sdio2
- {
- unsigned int temp = 0;
-
-- /* Register 0xf4 has 2 GPIO lines connected to the MRVL 8688:
-+ /* Register 0xf4 has 4 GPIO lines connected to the MRVL 8688 * IFX GPS:
- * bit 4: PDn
-- * bit 3: WiFi RESETn */
-+ * bit 3: WiFi RESETn
-+ * bit 2: GPS RESET_N
-+ * bit 1: GPS PD_N*/
-
- intel_mrst_pmic_read(0xf4, &temp);
- temp = temp|0x8;
-@@ -142,6 +144,12 @@ static int intel_mrst_bringup_8688_sdio2
- temp = temp|0x10;
- intel_mrst_pmic_write(0xf4, temp);
-
-+ temp = temp|0x04;
-+ intel_mrst_pmic_write(0xf4, temp);
-+
-+ temp = temp|0x02;
-+ intel_mrst_pmic_write(0xf4, temp);
-+
- return 0;
- }
-
-@@ -187,10 +195,10 @@ static int __init intel_mrst_module_init
- /* We only need the following PMIC register initializations if
- * we are using the Marvell 8688 WLAN card on the SDIO2 port */
-
--#ifdef CONFIG_8688_RC
-+#if defined(CONFIG_8688_RC) || defined(CONFIG_LIBERTAS_SDIO) || defined(CONFIG_SPI_IFX_GPS)
-
- printk(KERN_INFO "intel_mrst_module_init: bringing up power for "
-- "8688 WLAN on SDIO2...\n");
-+ "8688 WLAN on SDIO2 & IFX GPS over SPI...\n");
- ret = intel_mrst_bringup_8688_sdio2();
-
- #endif /* CONFIG_8688_RC */