diff options
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.patch | 1648 |
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 */ |