diff options
Diffstat (limited to 'meta/recipes-kernel/linux/linux-netbook-2.6.33.2/linux-2.6.34-moorestown-aava-specific-changes-no-audio.patch')
-rw-r--r-- | meta/recipes-kernel/linux/linux-netbook-2.6.33.2/linux-2.6.34-moorestown-aava-specific-changes-no-audio.patch | 3342 |
1 files changed, 0 insertions, 3342 deletions
diff --git a/meta/recipes-kernel/linux/linux-netbook-2.6.33.2/linux-2.6.34-moorestown-aava-specific-changes-no-audio.patch b/meta/recipes-kernel/linux/linux-netbook-2.6.33.2/linux-2.6.34-moorestown-aava-specific-changes-no-audio.patch deleted file mode 100644 index 7336ae66c..000000000 --- a/meta/recipes-kernel/linux/linux-netbook-2.6.33.2/linux-2.6.34-moorestown-aava-specific-changes-no-audio.patch +++ /dev/null @@ -1,3342 +0,0 @@ -From: Prajwal Mohan <prajwal.karur.mohan@intel.com> -Date: Tue, 27 Apr 2010 11:23:00 -0700 -Subject: [PATCH] Aava specific patches - -This driver is from aava - -Signed-off-by: Prajwal Mohan <prajwal.karur.mohan@intel.com> -Patch-mainline: 2.6.34 ---- -Index: linux-2.6.33/drivers/misc/mrst_test_ipc/ipc_module.c -=================================================================== ---- linux-2.6.33.orig/drivers/misc/mrst_test_ipc/ipc_module.c -+++ linux-2.6.33/drivers/misc/mrst_test_ipc/ipc_module.c -@@ -44,8 +44,13 @@ - #include <linux/uaccess.h> - #include <linux/time.h> - -+ -+ - #include <asm/ipc_defs.h> - -+#include <linux/device.h> -+#include <linux/ipc_module.h> -+ - static u32 major; - #define MAX_FW_SIZE 264192 - -@@ -53,9 +58,11 @@ int init_ipc_driver(void); - int ipc_ioctl(struct inode *inode, struct file *filp, u32 cmd, - unsigned long arg); - const struct file_operations ipc_fops = { -+owner:THIS_MODULE, - ioctl:ipc_ioctl, - }; - -+static struct class *mid_ipc_class; - - int ipc_ioctl(struct inode *inode, struct file *filp, u32 cmd, - unsigned long arg) -@@ -71,6 +78,18 @@ int ipc_ioctl(struct inode *inode, struc - u8 *fw_buf = NULL ; - - switch (cmd) { -+ case IPC_IOC_PMIC_REG_READ: -+ cmd = IPC_PMIC_REGISTER_READ; -+ break; -+ case IPC_IOC_PMIC_REG_WRITE: -+ cmd = IPC_PMIC_REGISTER_WRITE; -+ break; -+ default: -+ printk(KERN_INFO "ioctl <UNRECOGNIZED> received\n"); -+ break; -+ } -+ -+ switch (cmd) { - case IPC_PMIC_REGISTER_READ: - { - printk(KERN_INFO -@@ -169,6 +188,8 @@ int ipc_ioctl(struct inode *inode, struc - - static int __init ipc_module_init(void) - { -+ struct device *dev; -+ - printk(KERN_INFO "Init ipc_module\n"); - - major = register_chrdev(0, "mid_ipc", &ipc_fops); -@@ -177,6 +198,23 @@ static int __init ipc_module_init(void) - return major; - } - -+ mid_ipc_class = class_create(THIS_MODULE, "mid_ipc"); -+ if (IS_ERR(mid_ipc_class)) { -+ unregister_chrdev(major, "mid_ipc"); -+ return PTR_ERR(mid_ipc_class); -+ } -+ -+ dev = device_create(mid_ipc_class, -+ NULL, -+ MKDEV(major, 0), -+ NULL, -+ "mid_ipc" ); -+ if (IS_ERR(dev)) { -+ class_destroy(mid_ipc_class); -+ unregister_chrdev(major, "mid_ipc"); -+ return PTR_ERR(dev); -+ } -+ - init_ipc_driver ( ) ; - return SUCCESS; - -@@ -184,6 +222,8 @@ static int __init ipc_module_init(void) - - static void __exit ipc_module_exit(void) - { -+ device_destroy(mid_ipc_class, MKDEV(major, 0)); -+ class_destroy(mid_ipc_class); - unregister_chrdev(major, "mid_ipc"); - } - -Index: linux-2.6.33/include/linux/Kbuild -=================================================================== ---- linux-2.6.33.orig/include/linux/Kbuild -+++ linux-2.6.33/include/linux/Kbuild -@@ -385,3 +385,5 @@ unifdef-y += xfrm.h - objhdr-y += version.h - header-y += wimax.h - header-y += wimax/ -+header-y += ipc_module.h -+ -Index: linux-2.6.33/drivers/gpio/gpiolib.c -=================================================================== ---- linux-2.6.33.orig/drivers/gpio/gpiolib.c -+++ linux-2.6.33/drivers/gpio/gpiolib.c -@@ -228,11 +228,14 @@ static ssize_t gpio_direction_show(struc - - if (!test_bit(FLAG_EXPORT, &desc->flags)) - status = -EIO; -- else -- status = sprintf(buf, "%s\n", -- test_bit(FLAG_IS_OUT, &desc->flags) -- ? "out" : "in"); -- -+ else { -+ status = sprintf(buf, -+ "%s\n", -+ gpio_get_direction( (desc - gpio_desc) ) == -+ DIRECTION_OUT ? -+ "out" : -+ "in"); -+ } - mutex_unlock(&sysfs_lock); - return status; - } -@@ -1507,6 +1510,29 @@ void gpio_set_value_cansleep(unsigned gp - } - EXPORT_SYMBOL_GPL(gpio_set_value_cansleep); - -+enum gpio_direction gpio_get_direction(unsigned gpio) -+{ -+ struct gpio_chip *chip; -+ struct gpio_desc *desc = &gpio_desc[gpio]; -+ -+ chip = gpio_to_chip(gpio); -+ might_sleep_if(extra_checks && chip->can_sleep); -+ -+ if (chip->get_direction) { -+ if (chip->get_direction(chip, gpio - chip->base) == -+ DIRECTION_IN) { -+ clear_bit(FLAG_IS_OUT, &desc->flags); -+ return DIRECTION_IN; -+ } else { -+ set_bit(FLAG_IS_OUT, &desc->flags); -+ return DIRECTION_OUT; -+ } -+ } -+ return test_bit(FLAG_IS_OUT, &desc->flags) ? -+ DIRECTION_OUT : -+ DIRECTION_IN; -+} -+EXPORT_SYMBOL_GPL(gpio_get_direction); - - #ifdef CONFIG_DEBUG_FS - -Index: linux-2.6.33/drivers/gpio/langwell_gpio.c -=================================================================== ---- linux-2.6.33.orig/drivers/gpio/langwell_gpio.c -+++ linux-2.6.33/drivers/gpio/langwell_gpio.c -@@ -107,6 +107,19 @@ static int lnw_gpio_direction_output(str - return 0; - } - -+static enum gpio_direction lnw_gpio_get_direction(struct gpio_chip *chip, -+ unsigned offset) -+{ -+ struct lnw_gpio *lnw = container_of(chip, struct lnw_gpio, chip); -+ u8 reg = offset / 32; -+ void __iomem *gpdr; -+ -+ gpdr = (void __iomem *)(&lnw->reg_base->GPDR[reg]); -+ if (readl(gpdr) & BIT(offset % 32)) -+ return DIRECTION_OUT; -+ return DIRECTION_IN; -+} -+ - static int lnw_gpio_to_irq(struct gpio_chip *chip, unsigned offset) - { - struct lnw_gpio *lnw = container_of(chip, struct lnw_gpio, chip); -@@ -240,6 +253,7 @@ static int __devinit lnw_gpio_probe(stru - lnw->chip.label = dev_name(&pdev->dev); - lnw->chip.direction_input = lnw_gpio_direction_input; - lnw->chip.direction_output = lnw_gpio_direction_output; -+ lnw->chip.get_direction = lnw_gpio_get_direction; - lnw->chip.get = lnw_gpio_get; - lnw->chip.set = lnw_gpio_set; - lnw->chip.to_irq = lnw_gpio_to_irq; -Index: linux-2.6.33/drivers/gpio/langwell_pmic_gpio.c -=================================================================== ---- linux-2.6.33.orig/drivers/gpio/langwell_pmic_gpio.c -+++ linux-2.6.33/drivers/gpio/langwell_pmic_gpio.c -@@ -165,15 +165,33 @@ static int pmic_gpio_direction_output(st - return rc; - } - --static int pmic_gpio_get(struct gpio_chip *chip, unsigned offset) -+static enum gpio_direction pmic_gpio_get_direction(struct gpio_chip *chip, -+ unsigned offset) - { -- /* we only have 8 GPIO can use as input */ - if (offset > 8) { -- printk(KERN_ERR -- "%s: only pin 0-7 support input\n", __func__); -- return -1; -+ /* GPOWSs and GPOs are always outputs */ -+ return DIRECTION_OUT; - } -- return ipc_read_char(GPIO0 + offset) & GPIO_DIN; -+ if (ipc_read_char(GPIO0 + offset) & GPIO_DIR) -+ return DIRECTION_IN; -+ return DIRECTION_OUT; -+} -+ -+static int pmic_gpio_get(struct gpio_chip *chip, unsigned offset) -+{ -+ if (offset < 8) { -+ /* GPIOSW: Get state according to direction */ -+ if (pmic_gpio_get_direction( chip, offset ) == DIRECTION_IN) -+ return (ipc_read_char(GPIO0 + offset) & GPIO_DIN); -+ return (ipc_read_char(GPIO0 + offset) & GPIO_DOU); -+ } else if (offset < 16) { -+ /* GPOSW */ -+ return (ipc_read_char(GPOSWCTL0 + offset - 8) & GPOSW_DOU); -+ } else if (offset < 24) { -+ /* GPO */ -+ return (ipc_read_char(GPO) & (1 << (offset - 16))); -+ } -+ return 0; - } - - static void pmic_gpio_set(struct gpio_chip *chip, unsigned offset, int value) -@@ -284,6 +302,7 @@ static int __devinit pmic_gpio_probe(str - pg->chip.label = "langwell_pmic"; - pg->chip.direction_input = pmic_gpio_direction_input; - pg->chip.direction_output = pmic_gpio_direction_output; -+ pg->chip.get_direction = pmic_gpio_get_direction; - pg->chip.get = pmic_gpio_get; - pg->chip.set = pmic_gpio_set; - pg->chip.to_irq = pmic_gpio_to_irq; -Index: linux-2.6.33/drivers/gpio/pca953x.c -=================================================================== ---- linux-2.6.33.orig/drivers/gpio/pca953x.c -+++ linux-2.6.33/drivers/gpio/pca953x.c -@@ -144,6 +144,24 @@ static int pca953x_gpio_direction_output - return 0; - } - -+static enum gpio_direction pca953x_gpio_get_direction(struct gpio_chip *gc, -+ unsigned off) -+{ -+ struct pca953x_chip *chip; -+ uint16_t reg_val; -+ int ret; -+ -+ chip = container_of(gc, struct pca953x_chip, gpio_chip); -+ -+ ret = pca953x_read_reg(chip, PCA953X_DIRECTION, ®_val); -+ if (ret == 0) { -+ if ( reg_val & (1u << off) ) -+ return DIRECTION_IN; -+ return DIRECTION_OUT; -+ } -+ return DIRECTION_IN; -+} -+ - static int pca953x_gpio_get_value(struct gpio_chip *gc, unsigned off) - { - struct pca953x_chip *chip; -@@ -199,6 +217,7 @@ static void pca953x_setup_gpio(struct pc - - gc->direction_input = pca953x_gpio_direction_input; - gc->direction_output = pca953x_gpio_direction_output; -+ gc->get_direction = pca953x_gpio_get_direction; - gc->get = pca953x_gpio_get_value; - gc->set = pca953x_gpio_set_value; - gc->to_irq = pca953x_gpio_to_irq; -Index: linux-2.6.33/include/asm-generic/gpio.h -=================================================================== ---- linux-2.6.33.orig/include/asm-generic/gpio.h -+++ linux-2.6.33/include/asm-generic/gpio.h -@@ -101,6 +101,8 @@ struct gpio_chip { - char **names; - unsigned can_sleep:1; - unsigned exported:1; -+ enum gpio_direction (*get_direction)(struct gpio_chip *chip, -+ unsigned offset); - }; - - extern const char *gpiochip_is_requested(struct gpio_chip *chip, -@@ -120,6 +122,7 @@ extern void gpio_free(unsigned gpio); - - extern int gpio_direction_input(unsigned gpio); - extern int gpio_direction_output(unsigned gpio, int value); -+extern enum gpio_direction gpio_get_direction(unsigned gpio); - - extern int gpio_get_value_cansleep(unsigned gpio); - extern void gpio_set_value_cansleep(unsigned gpio, int value); -Index: linux-2.6.33/include/linux/gpio.h -=================================================================== ---- linux-2.6.33.orig/include/linux/gpio.h -+++ linux-2.6.33/include/linux/gpio.h -@@ -3,6 +3,11 @@ - - /* see Documentation/gpio.txt */ - -+enum gpio_direction { -+ DIRECTION_IN = 0, -+ DIRECTION_OUT = 1, -+}; -+ - #ifdef CONFIG_GENERIC_GPIO - #include <asm/gpio.h> - -@@ -126,6 +131,13 @@ static inline int irq_to_gpio(unsigned i - return -EINVAL; - } - -+static inline enum gpio_direction gpio_get_direction(unsigned gpio) -+{ -+ /* GPIO can never have been requested or set as {in,out}put */ -+ WARN_ON(1); -+ return DIRECTION_IN; -+} -+ - #endif - - #endif /* __LINUX_GPIO_H */ -Index: linux-2.6.33/include/linux/ipc_module.h -=================================================================== ---- /dev/null -+++ linux-2.6.33/include/linux/ipc_module.h -@@ -0,0 +1,60 @@ -+/* -+ * include/linux/ipc_module.h -+ * -+ * Copyright (C) 2009 Aava Mobile Oy -+ * Written by Mikko Kovanen <mikko.kovanen@aavamobile.com> -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope that 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -+ */ -+ -+#ifndef IPC_MODULE_H -+#define IPC_MODULE_H -+ -+#include <linux/types.h> -+ -+#ifndef __IPC_DEFS_H__ -+#define E_INVALID_CMD -249 -+#define E_READ_USER_CMD -250 -+#define E_READ_USER_DATA -251 -+#define E_WRITE_USER_DATA -252 -+#define E_PMIC_MALLOC -253 -+ -+#define MAX_PMICREGS 5 -+#define MAX_PMIC_MOD_REGS 4 -+ -+struct pmicreg { -+ __u16 register_address; -+ __u8 value; -+}; -+ -+struct ipc_pmic_reg_data { -+ _Bool ioc; -+ struct pmicreg pmic_reg_data[MAX_PMICREGS]; -+ __u8 num_entries; -+}; -+#endif /* __IPC_DEFS_H__ */ -+ -+#define IPC_IOC_MAGIC 'a' -+ -+ -+#define IPC_IOC_PMIC_REG_READ _IOR(IPC_IOC_MAGIC, \ -+ 0, \ -+ struct ipc_pmic_reg_data) -+ -+#define IPC_IOC_PMIC_REG_WRITE _IOW(IPC_IOC_MAGIC, \ -+ 1, \ -+ struct ipc_pmic_reg_data) -+ -+#endif /* IPC_MODULE_H */ -+ -Index: linux-2.6.33/drivers/input/keyboard/mrst_keypad.c -=================================================================== ---- linux-2.6.33.orig/drivers/input/keyboard/mrst_keypad.c -+++ linux-2.6.33/drivers/input/keyboard/mrst_keypad.c -@@ -40,6 +40,9 @@ - #include <linux/device.h> - #include <linux/err.h> - #include <linux/gpio.h> -+/*jhuot start*/ -+#include <asm/ipc_defs.h> -+/*jhuot end*/ - - /* - * Keypad Controller registers -@@ -116,10 +119,10 @@ MODULE_DEVICE_TABLE(pci, keypad_pci_tbl) - #define keypad_writel(off, v) writel((v), keypad->mmio_base + (off)) - - #define MAX_MATRIX_KEY_NUM (8 * 8) --#define MAX_DIRECT_KEY_NUM (4) -+#define MAX_DIRECT_KEY_NUM (2) - --#define MAX_MATRIX_KEY_ROWS (8) --#define MAX_MATRIX_KEY_COLS (8) -+#define MAX_MATRIX_KEY_ROWS (7) -+#define MAX_MATRIX_KEY_COLS (7) - #define DEBOUNCE_INTERVAL 100 - - #define KEY_HALFSHUTTER KEY_PROG1 -@@ -167,7 +170,7 @@ static unsigned int mrst_keycode_fn[MAX_ - - /* direct key map */ - static unsigned int mrst_direct_keycode[MAX_DIRECT_KEY_NUM] = { -- KEY_VOLUMEUP, KEY_VOLUMEDOWN, KEY_HALFSHUTTER, KEY_FULLSHUTTER, -+ KEY_VOLUMEUP, KEY_VOLUMEDOWN, //KEY_HALFSHUTTER, KEY_FULLSHUTTER, - }; - - struct mrst_keypad { -@@ -430,6 +433,8 @@ scan: - if ((bits_changed & (1 << row)) == 0) - continue; - -+ printk(KERN_INFO "BUTTONS: " -+ "report key row %d, col %d\n", row, col); - input_report_key(keypad->input_dev, - lookup_matrix_keycode(keypad, row, col), - new_state[col] & (1 << row)); -@@ -513,6 +518,8 @@ static void mrst_keypad_scan_direct(stru - - for (i = 0; i < keypad->direct_key_num; i++) { - if (bits_changed & (1 << i)) { -+ printk(KERN_INFO "BUTTONS: " -+ "scan_direct %d\n", keypad->direct_key_map[i]); - input_report_key(keypad->input_dev, - keypad->direct_key_map[i], - (new_state & (1 << i))); -@@ -528,10 +535,13 @@ static irqreturn_t mrst_keypad_irq_handl - struct mrst_keypad *keypad = dev_id; - unsigned long kpc = keypad_readl(KPC); - -+ printk(KERN_INFO "BUTTONS: irq_handler, kpc %lu\n", kpc); - if (kpc & KPC_DI) -+ printk(KERN_INFO "BUTTONS: mrst_keypad_scan_direct\n"); - mrst_keypad_scan_direct(keypad); - - if (kpc & KPC_MI) -+ printk(KERN_INFO "BUTTONS: mrst_keypad_scan_matrix\n"); - mrst_keypad_scan_matrix(keypad); - - return IRQ_HANDLED; -@@ -544,13 +554,47 @@ static int mrst_keypad_gpio_init(void) - MAX_MATRIX_KEY_COLS + MAX_DIRECT_KEY_NUM; - - /* explicitely tell which pins have been occupied... */ -+/* - for (i = KEYPAD_MATRIX_GPIO_IN_PIN; i < pins; i++, cnt++) { - err = gpio_request(i, NULL); - if (err) { - printk(KERN_ERR "GPIO pin %d failed to request.\n", i); - goto err_request; - } -- } -+ }*/ -+ -+ for (i = 0; i < MAX_MATRIX_KEY_ROWS; i++){ -+ err = gpio_request(KEYPAD_MATRIX_GPIO_IN_PIN + i,NULL); -+ -+ if (err) { -+ printk(KERN_ERR "GPIO pin %d failed to request.\n", i); -+ goto err_request; -+ } -+ -+ } -+ -+ for (i = 0; i < MAX_MATRIX_KEY_COLS; i++) -+ { -+ err = gpio_request(KEYPAD_MATRIX_GPIO_OUT_PIN + i, NULL); -+ if (err) { -+ printk(KERN_ERR "GPIO pin %d failed to request.\n", i); -+ goto err_request; -+ } -+ -+ } -+ -+ for (i = 0; i < MAX_DIRECT_KEY_NUM; i++) -+ { -+ err = gpio_request(KEYPAD_DIRECT_GPIO_IN_PIN + i,NULL); -+ -+ if (err) { -+ printk(KERN_ERR "GPIO pin %d failed to request.\n", i); -+ goto err_request; -+ } -+ -+ -+ } -+ - - for (i = 0; i < MAX_MATRIX_KEY_ROWS; i++) - gpio_direction_input(KEYPAD_MATRIX_GPIO_IN_PIN + i); -@@ -642,6 +686,9 @@ static int __devinit mrst_keypad_probe(s - struct mrst_keypad *keypad; - struct input_dev *input_dev; - int error; -+/* jhuot start */ -+ struct ipc_io_bus_master_regs *p_reg_data; -+/* jhuot end */ - - #ifndef MODULE - printk(KERN_INFO MRST_KEYPAD_DRIVER_NAME "\n"); -@@ -711,6 +758,18 @@ static int __devinit mrst_keypad_probe(s - goto failed_free_dev; - } - -+ -+/* jhuot start */ -+ /* Enable 75 kOhm internal pull-ups for KBD_DKIN0 and KBD_DKIN1 */ -+ /*bus: 0x4h, address: 0x20h, bits 0...3 */ -+ p_reg_data = kzalloc(sizeof(struct ipc_io_bus_master_regs), GFP_KERNEL); -+ /*01 = W, 04 = bus, 20 = address*/ -+ p_reg_data->ctrl_reg_addr = 0x01040020; -+ /*b3-b0 = 1010 (75kOhm pull-ups) = 0xAh*/ -+ p_reg_data->ctrl_reg_data = 0xA; -+ ipc_program_io_bus_master(p_reg_data); -+/* jhuot end */ -+ - /* Register the input device */ - error = input_register_device(input_dev); - if (error) { -Index: linux-2.6.33/drivers/gpu/drm/mrst/Kconfig -=================================================================== ---- linux-2.6.33.orig/drivers/gpu/drm/mrst/Kconfig -+++ linux-2.6.33/drivers/gpu/drm/mrst/Kconfig -@@ -23,6 +23,20 @@ config IMG_DOES_NOT_SUPPORT_MENLOW - help - Choose Menlow - -+config DRM_MRST_AAVA -+ bool "Aava platform specific MIPI display" -+ depends on DRM_MRST -+ default n -+ help -+ Choose Aava platform MIPI display, temp option -+ -+config DRM_MRST_CDK -+ bool "Aava platform specific MIPI display" -+ depends on DRM_MRST && !DRM_MRST_AAVA -+ default y -+ help -+ Choose CDK -+ - config PVR_RELEASE - string "Build IMG kernel services as release" - depends on DRM_MRST -Index: linux-2.6.33/drivers/misc/Makefile -=================================================================== ---- linux-2.6.33.orig/drivers/misc/Makefile -+++ linux-2.6.33/drivers/misc/Makefile -@@ -21,7 +21,7 @@ obj-$(CONFIG_SGI_XP) += sgi-xp/ - obj-$(CONFIG_SGI_GRU) += sgi-gru/ - obj-$(CONFIG_CS5535_MFGPT) += cs5535-mfgpt.o - obj-$(CONFIG_HP_ILO) += hpilo.o --obj-$(CONFIG_MRST) += intel_mrst.o -+obj-$(CONFIG_X86_MRST) += intel_mrst.o - obj-$(CONFIG_ISL29003) += isl29003.o - obj-$(CONFIG_MRST_RAR_HANDLER) += memrar.o - memrar-y := memrar_allocator.o memrar_handler.o -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 -@@ -112,6 +112,48 @@ static int intel_mrst_sdio_EVP_power_dow - - static int intel_mrst_sdio_8688_power_up(void) - { -+/*ouljhuot start*/ -+/*WLAN / BT power-up sequence:*/ -+/*1. power (GPO4) & reset (GPO3) low*/ -+/*2. power (GPO4) high*/ -+/*3. reset (GPO3) high*/ -+ -+/*GPS power-up sequence:*/ -+/*1. power (GPO1) & reset (GPO2) low*/ -+/*2. VDD_IO and VDD_LP_PLLREG_IN high*/ -+/*VDD_IO & VDD_LP_PLLREG_IN == VPMIC_1V8*/ -+/*3. usleep(1) (tvddio_nreset min. 500ns)*/ -+/*4. reset (GPO2) high*/ -+/*5. VDD_COREREG_IN and VDD_RFREG_IN high*/ -+ /*VDD_COREREG_IN == VWLAN_GPS_1V8 (GYMXIO)*/ -+ /*VDD_RFREG_IN == VGPS_ANA_3V3 (GYMX33)*/ -+/*6. power (GPO1) high*/ -+/*7. msleep(1);*/ -+ unsigned int temp = 0; -+ -+ /* Register 0xf4 has 4 GPIO lines connected to the MRVL 8688 * IFX GPS: -+ * bit 4: WiFi PDn -+ * bit 3: WiFi RESETn -+ * bit 2: GPS RESET_N -+ * bit 1: GPS PD_N*/ -+ -+ /*WLAN POWER and RESET low*/ -+ intel_mrst_pmic_read(0xf4, &temp); -+ temp &= ~0x18; -+ intel_mrst_pmic_write(0xf4, temp); -+/* msleep(1);*/ -+ -+ /*GPS RESET low & POWER low*/ -+ intel_mrst_pmic_read(0xf4, &temp); -+ temp &= ~0x6; -+ intel_mrst_pmic_write(0xf4, temp); -+/* usleep(1);*/ -+ -+ msleep(1); -+ /*GPS RESET high*/ -+ temp |= 0x4; -+ intel_mrst_pmic_write(0xf4, temp); -+/*ouljhuot end*/ - intel_mrst_pmic_write(0x37, 0x3f); /* Set VDDQ for Marvell 8688 */ - intel_mrst_pmic_write(0x4a, 0x3f); /* Set GYMXIOCNT for Marvell 8688 */ - intel_mrst_pmic_write(0x4e, 0x3f); /* Set GYMX33CNT for Marvell 8688 */ -@@ -124,6 +166,22 @@ static int intel_mrst_sdio_8688_power_up - intel_mrst_pmic_write(0x4c, 0x27); /* Enable V1p8_VWYMXARF for - MRVL8688 */ - -+ -+/*ouljhuot start*/ -+ /*WLAN POWER high*/ -+ temp |= 0x10; -+ intel_mrst_pmic_write(0xf4, temp); -+ -+ /*WLAN RESET high*/ -+ temp |= 0x8; -+ intel_mrst_pmic_write(0xf4, temp); -+ -+ /*GPS POWER high*/ -+ temp |= 0x2; -+ intel_mrst_pmic_write(0xf4, temp); -+/* msleep(16);*/ -+/*ouljhuot end*/ -+ - return 0; - } - -@@ -153,6 +211,35 @@ static int intel_mrst_bringup_8688_sdio2 - return 0; - } - -+ -+ -+ -+ /*ouljhuot start*/ -+static int intel_mrst_sdio_gps_power_up(void) -+ { -+ unsigned int temp = 0; -+ -+ /*GPS RESET low & POWER low*/ -+ intel_mrst_pmic_read(0xf4, &temp); -+ temp &= ~0x6; -+ intel_mrst_pmic_write(0xf4, temp); -+ msleep(1); -+ /*GPS RESET high*/ -+ temp |= 0x4; -+ intel_mrst_pmic_write(0xf4, temp); -+ -+ intel_mrst_pmic_write(0x4a, 0x3f); /* Ensure GYMXIOCNT */ -+ intel_mrst_pmic_write(0x4e, 0x3f); /* Ensure GYMX33CNT */ -+ -+ /*GPS POWER high*/ -+ temp |= 0x2; -+ intel_mrst_pmic_write(0xf4, temp); -+ /* Wait to settle */ -+ msleep(16); -+ -+ return 0; -+ } -+ - static int intel_mrst_bringup_EVP_sdio2_Option_spi(void) - { - unsigned int temp = 0; -@@ -199,7 +286,10 @@ static int __init intel_mrst_module_init - - printk(KERN_INFO "intel_mrst_module_init: bringing up power for " - "8688 WLAN on SDIO2 & IFX GPS over SPI...\n"); -- ret = intel_mrst_bringup_8688_sdio2(); -+/*ouljhuot start*/ -+ ret = intel_mrst_sdio_8688_power_up(); -+/* ret = intel_mrst_sdio_gps_power_up();*/ -+/*ouljhuot end*/ - - #endif /* CONFIG_8688_RC */ - -Index: linux-2.6.33/drivers/hwmon/lis331dl.c -=================================================================== ---- linux-2.6.33.orig/drivers/hwmon/lis331dl.c -+++ linux-2.6.33/drivers/hwmon/lis331dl.c -@@ -45,6 +45,8 @@ MODULE_LICENSE("GPL v2"); - #define ACCEL_NORMAL_MODE 0 - #define ACCEL_MEMORY_REBOOT 1 - -+#define POS_READ_MAX_RETRY (5) -+ - /* internal return values */ - - struct acclero_data { -@@ -93,9 +95,24 @@ static ssize_t x_pos_show(struct device - { - struct i2c_client *client = to_i2c_client(dev); - int ret_val; -+ int retry = 0; - -+x_retry: - ret_val = i2c_smbus_read_byte_data(client, 0x29); -- return sprintf(buf, "%d\n", ret_val); -+ if (ret_val == -ETIMEDOUT) { -+ dev_dbg(dev, "x pos read timed out, retry %d\n", retry); -+ retry++; -+ if (retry <= POS_READ_MAX_RETRY) { -+ msleep(10); -+ goto x_retry; -+ } else { -+ ret_val = 0; -+ dev_err(dev, "x pos read failed %d retries\n", retry); -+ } -+ } -+ /* ouljkorh, 09.11.2009, change start */ -+ return sprintf(buf, "%d\n", (signed char)ret_val); -+ /* ouljkorh, 09.11.2009, change end */ - } - - static ssize_t y_pos_show(struct device *dev, -@@ -103,9 +120,24 @@ static ssize_t y_pos_show(struct device - { - struct i2c_client *client = to_i2c_client(dev); - int ret_val; -+ int retry = 0; - -+y_retry: - ret_val = i2c_smbus_read_byte_data(client, 0x2B); -- return sprintf(buf, "%d\n", ret_val); -+ if (ret_val == -ETIMEDOUT) { -+ dev_dbg(dev, "y pos read timed out, retry %d\n", retry); -+ retry++; -+ if (retry <= POS_READ_MAX_RETRY) { -+ msleep(10); -+ goto y_retry; -+ } else { -+ ret_val = 0; -+ dev_err(dev, "y pos read failed %d retries\n", retry); -+ } -+ } -+ /* ouljkorh, 09.11.2009, change start */ -+ return sprintf(buf, "%d\n", (signed char)ret_val); -+ /* ouljkorh, 09.11.2009, change end */ - } - - static ssize_t z_pos_show(struct device *dev, -@@ -113,9 +145,24 @@ static ssize_t z_pos_show(struct device - { - struct i2c_client *client = to_i2c_client(dev); - int ret_val; -+ int retry = 0; - -+z_retry: - ret_val = i2c_smbus_read_byte_data(client, 0x2D); -- return sprintf(buf, "%d\n", ret_val); -+ if (ret_val == -ETIMEDOUT) { -+ dev_dbg(dev, "z pos read timed out, retry %d\n", retry); -+ retry++; -+ if (retry <= POS_READ_MAX_RETRY) { -+ msleep(10); -+ goto z_retry; -+ } else { -+ ret_val = 0; -+ dev_err(dev, "z pos read failed %d retries\n", retry); -+ } -+ } -+ /* ouljkorh, 09.11.2009, change start */ -+ return sprintf(buf, "%d\n", (signed char)ret_val); -+ /* ouljkorh, 09.11.2009, change end */ - } - - static ssize_t xyz_pos_show(struct device *dev, -@@ -123,11 +170,38 @@ static ssize_t xyz_pos_show(struct devic - { - int x, y, z; - struct i2c_client *client = to_i2c_client(dev); -+ int retry = 0; - -+xyz_retry: -+ if (retry > POS_READ_MAX_RETRY) { -+ dev_err(dev, "xyz read retry failed\n"); -+ x = y = z = 0; -+ return sprintf(buf, "(%d,%d,%d)\n", (signed char)x, -+ (signed char)y, (signed char)z); -+ } -+ retry++; - x = i2c_smbus_read_byte_data(client, 0x29); -+ if (x == -ETIMEDOUT) { -+ msleep(100); -+ goto xyz_retry; -+ } -+ msleep(100); - y = i2c_smbus_read_byte_data(client, 0x2B); -+ if (y == -ETIMEDOUT) { -+ msleep(100); -+ goto xyz_retry; -+ } -+ msleep(100); - z = i2c_smbus_read_byte_data(client, 0x2D); -- return sprintf(buf, "(%d,%d,%d)\n", x, y, z); -+ if (z == -ETIMEDOUT) { -+ msleep(100); -+ goto xyz_retry; -+ } -+ -+ /* ouljkorh, 09.11.2009, change start */ -+ return sprintf(buf, "(%d,%d,%d)\n", (signed char)x, -+ (signed char)y, (signed char)z); -+ /* ouljkorh, 09.11.2009, change end */ - } - - static ssize_t data_rate_store(struct device *dev, -Index: linux-2.6.33/drivers/usb/gadget/u_serial.c -=================================================================== ---- linux-2.6.33.orig/drivers/usb/gadget/u_serial.c -+++ linux-2.6.33/drivers/usb/gadget/u_serial.c -@@ -783,11 +783,6 @@ static int gs_open(struct tty_struct *tt - port->open_count = 1; - port->openclose = false; - -- /* low_latency means ldiscs work in tasklet context, without -- * needing a workqueue schedule ... easier to keep up. -- */ -- tty->low_latency = 1; -- - /* if connected, start the I/O stream */ - if (port->port_usb) { - struct gserial *gser = port->port_usb; -Index: linux-2.6.33/drivers/i2c/busses/i2c-mrst.c -=================================================================== ---- linux-2.6.33.orig/drivers/i2c/busses/i2c-mrst.c -+++ linux-2.6.33/drivers/i2c/busses/i2c-mrst.c -@@ -37,7 +37,7 @@ - - #include "i2c-mrst.h" - --#define MAX_T_POLL_COUNT 4000 /* FIXME */ -+#define MAX_T_POLL_COUNT 8000 /* FIXME */ - #define DEF_BAR 0 - #define VERSION "Version 0.5" - -Index: linux-2.6.33/arch/x86/kernel/mrst.c -=================================================================== ---- linux-2.6.33.orig/arch/x86/kernel/mrst.c -+++ linux-2.6.33/arch/x86/kernel/mrst.c -@@ -23,6 +23,9 @@ - #include <linux/input.h> - #include <linux/platform_device.h> - #include <linux/irq.h> -+/*jhuot, added for MAX3107 data*/ -+#include <linux/spi/mrst_spi.h> -+ - - #include <asm/string.h> - #include <asm/setup.h> -@@ -267,6 +270,27 @@ void __init x86_mrst_early_setup(void) - #define MRST_SPI2_CS_START 4 - static struct langwell_pmic_gpio_platform_data pmic_gpio_pdata; - -+#ifdef CONFIG_SERIAL_MAX3107 -+static struct mrst_spi_chip spi_slave0 = { -+ .poll_mode = 1, -+ .enable_dma = 0, -+ .type = SPI_FRF_SPI, -+}; -+ -+static struct spi_board_info mrst_spi_board_info[] __initdata = { -+ { -+ /* the modalias must be the same as spi device driver name */ -+ .modalias = "max3107", /* spi_driver name driving device */ -+ .max_speed_hz = 3125000,/* default value */ -+ .bus_num = 0, /* SPI0 */ -+ .chip_select = 0, /* Framework chip select. */ -+ .platform_data = NULL, /* fill later */ -+ .controller_data = &spi_slave0, -+ .irq = 0x13d, -+ }, -+}; -+#endif -+ - static int __init sfi_parse_spib(struct sfi_table_header *table) - { - struct sfi_table_simple *sb; -@@ -290,31 +314,48 @@ static int __init sfi_parse_spib(struct - pr_info("Moorestown SPI devices info:\n"); - - for (i = 0, j = 0; i < num; i++, pentry++) { -- strncpy(info[j].modalias, pentry->name, 16); -- info[j].irq = pentry->irq_info; -- info[j].bus_num = pentry->host_num; -- info[j].chip_select = pentry->cs; -- info[j].max_speed_hz = 3125000; /* hard coded */ -- if (info[i].chip_select >= MRST_SPI2_CS_START) { -- /* these SPI2 devices are not exposed to system as PCI -- * devices, but they have separate RTE entry in IOAPIC -- * so we have to enable them one by one here -- */ -- ioapic = mp_find_ioapic(info[j].irq); -- irq_attr.ioapic = ioapic; -- irq_attr.ioapic_pin = info[j].irq; -- irq_attr.trigger = 1; -- irq_attr.polarity = 1; -- io_apic_set_pci_routing(NULL, info[j].irq, -+#ifdef CONFIG_SERIAL_MAX3107 -+ if (j != 1) { /*other devices info*/ -+#endif -+ strncpy(info[j].modalias, pentry->name, 16); -+ info[j].irq = pentry->irq_info; -+ info[j].bus_num = pentry->host_num; -+ info[j].chip_select = pentry->cs; -+ info[j].max_speed_hz = 3125000; /* hard coded */ -+ if (info[i].chip_select >= MRST_SPI2_CS_START) { -+ /* these SPI2 devices are not exposed to system as PCI -+ * devices, but they have separate RTE entry in IOAPIC -+ * so we have to enable them one by one here -+ */ -+ ioapic = mp_find_ioapic(info[j].irq); -+ irq_attr.ioapic = ioapic; -+ irq_attr.ioapic_pin = info[j].irq; -+ irq_attr.trigger = 1; -+ irq_attr.polarity = 1; -+ io_apic_set_pci_routing(NULL, info[j].irq, - &irq_attr); -- } -- info[j].platform_data = pentry->dev_info; -+ } - -- if (!strcmp(pentry->name, "pmic_gpio")) { -- memcpy(&pmic_gpio_pdata, pentry->dev_info, 8); -- pmic_gpio_pdata.gpiointr = 0xffffeff8; -- info[j].platform_data = &pmic_gpio_pdata; -+ info[j].platform_data = pentry->dev_info; -+ -+ if (!strcmp(pentry->name, "pmic_gpio")) { -+ memcpy(&pmic_gpio_pdata, pentry->dev_info, 8); -+ pmic_gpio_pdata.gpiointr = 0xffffeff8; -+ info[j].platform_data = &pmic_gpio_pdata; -+ } -+#ifdef CONFIG_SERIAL_MAX3107 -+ } else { /*MAX3107 info*/ -+ info[j] = mrst_spi_board_info[0]; -+ } -+ -+#endif -+ /* jhuot edit start: change GPS chip select from 2 to 3 */ -+ if (info[j].bus_num == 0 && info[j].chip_select == 2) { -+ info[j].chip_select = 3; -+ } else if (info[j].bus_num == 0 && info[j].chip_select == 3) { -+ info[j].chip_select = 2; - } -+ /* jhuot edit end */ - pr_info("info[%d]: name = %16s, irq = 0x%04x, bus = %d, " - "cs = %d\n", j, info[j].modalias, info[j].irq, - info[j].bus_num, info[j].chip_select); -Index: linux-2.6.33/drivers/serial/Kconfig -=================================================================== ---- linux-2.6.33.orig/drivers/serial/Kconfig -+++ linux-2.6.33/drivers/serial/Kconfig -@@ -540,6 +540,21 @@ config SERIAL_S5PC100 - help - Serial port support for the Samsung S5PC100 SoCs - -+config SERIAL_MAX3107 -+ tristate "MAX3107 support" -+ depends on SPI -+ select SERIAL_CORE -+ help -+ MAX3107 chip support -+ -+config MAX3107_LOW_POWER -+ boolean "Enable very low power consumption scheme for Max3107" -+ default n -+ depends on SERIAL_MAX3107 -+ help -+ Adds hardware suspend for MAX3107 instead of sleep/auto-sleep, -+ but causes longer latency in wake-up (re-initialization of the chip). -+ - config SERIAL_MAX3100 - tristate "MAX3100 support" - depends on SPI -Index: linux-2.6.33/drivers/serial/Makefile -=================================================================== ---- linux-2.6.33.orig/drivers/serial/Makefile -+++ linux-2.6.33/drivers/serial/Makefile -@@ -46,6 +46,7 @@ obj-$(CONFIG_SERIAL_S3C24A0) += s3c24a0. - obj-$(CONFIG_SERIAL_S3C6400) += s3c6400.o - obj-$(CONFIG_SERIAL_S5PC100) += s3c6400.o - obj-$(CONFIG_SERIAL_MAX3100) += max3100.o -+obj-$(CONFIG_SERIAL_MAX3107) += max3107.o - obj-$(CONFIG_SERIAL_IP22_ZILOG) += ip22zilog.o - obj-$(CONFIG_SERIAL_MUX) += mux.o - obj-$(CONFIG_SERIAL_68328) += 68328serial.o -Index: linux-2.6.33/drivers/serial/max3107.c -=================================================================== ---- /dev/null -+++ linux-2.6.33/drivers/serial/max3107.c -@@ -0,0 +1,1484 @@ -+/* -+ * max3107.c - spi uart protocol driver for Maxim 3107 -+ * Based on max3100.c -+ * by Christian Pellegrin <chripell@evolware.org> -+ * and max3110.c -+ * by Feng Tang <feng.tang@intel.com> -+ * -+ * Copyright (C) Aavamobile 2009 -+ * -+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -+ * -+ * 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; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -+ * -+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -+ * -+ */ -+ -+#include <linux/delay.h> -+#include <linux/device.h> -+#include <linux/serial_core.h> -+#include <linux/serial.h> -+#include <linux/spi/spi.h> -+#include <linux/spi/mrst_spi.h> -+#include <linux/freezer.h> -+#include <linux/platform_device.h> -+#include <linux/gpio.h> -+#include <linux/serial_max3107.h> -+ -+/* Debug trace definitions */ -+#define DBG_LEVEL 0 -+ -+#if (DBG_LEVEL > 0) -+#define DBG_TRACE(format,args...) printk(KERN_ERR "%s: " format, \ -+ __FUNCTION__ , ## args) -+#else -+#define DBG_TRACE(format,args...) -+#endif -+ -+#if (DBG_LEVEL > 1) -+#define DBG_TRACE_SPI_DATA -+#endif -+ -+struct max3107_port { -+ /* UART port structure */ -+ struct uart_port port; -+ -+ /* SPI device structure */ -+ struct spi_device *spi; -+ -+ /* GPIO chip stucture */ -+ struct gpio_chip chip; -+ -+ /* Workqueue that does all the magic */ -+ struct workqueue_struct *workqueue; -+ struct work_struct work; -+ -+ /* Lock for shared data */ -+ spinlock_t data_lock; -+ -+ /* Device configuration */ -+ int ext_clk; /* 1 if external clock used */ -+ int loopback; /* Current loopback mode state */ -+ int baud; /* Current baud rate */ -+ -+ /* State flags */ -+ int suspended; /* Indicates suspend mode */ -+ int tx_fifo_empty; /* Flag for TX FIFO state */ -+ int rx_enabled; /* Flag for receiver state */ -+ int tx_enabled; /* Flag for transmitter state */ -+ -+ /* Shared data */ -+ u16 irqen_reg; /* Current IRQ enable register value */ -+ u16 mode1_reg; /* Current mode1 register value*/ -+ int mode1_commit; /* Flag for setting new mode1 register value */ -+ u16 lcr_reg; /* Current LCR register value */ -+ int lcr_commit; /* Flag for setting new LCR register value */ -+ u32 brg_cfg; /* Current Baud rate generator config */ -+ int brg_commit; /* Flag for setting new baud rate generator -+ * config -+ */ -+ -+ int handle_irq; /* Indicates that IRQ should be handled */ -+}; -+ -+/* Platform data structure */ -+struct max3107_plat { -+ /* Loopback mode enable */ -+ int loopback; -+ /* External clock enable */ -+ int ext_clk; -+ /* HW suspend function */ -+ void (*max3107_hw_suspend) (struct max3107_port *s, int suspend); -+ /* Polling mode enable */ -+ int polled_mode; -+ /* Polling period if polling mode enabled */ -+ int poll_time; -+}; -+ -+ -+/* Perform SPI transfer for write/read of device register(s) */ -+static int max3107_rw(struct max3107_port *s, u8 *tx, u8 *rx, int len) -+{ -+ struct spi_message spi_msg; -+ struct spi_transfer spi_xfer; -+ -+ DBG_TRACE("enter\n"); -+ -+ /* Initialize SPI ,message */ -+ spi_message_init(&spi_msg); -+ -+ /* Initialize SPI transfer */ -+ memset(&spi_xfer, 0, sizeof spi_xfer); -+ spi_xfer.len = len; -+ spi_xfer.tx_buf = tx; -+ spi_xfer.rx_buf = rx; -+ spi_xfer.speed_hz = MAX3107_SPI_SPEED; -+ -+ /* Add SPI transfer to SPI message */ -+ spi_message_add_tail(&spi_xfer, &spi_msg); -+ -+#ifdef DBG_TRACE_SPI_DATA -+ { -+ int i; -+ printk("tx len %d:\n", spi_xfer.len); -+ for (i = 0 ; i < spi_xfer.len && i < 32 ; i++) { -+ printk(" %x", ((u8*)spi_xfer.tx_buf)[i]); -+ } -+ printk("\n"); -+ } -+#endif -+ -+ /* Perform synchronous SPI transfer */ -+ if (spi_sync(s->spi, &spi_msg)) { -+ dev_err(&s->spi->dev, "spi_sync failure\n"); -+ return -EIO; -+ } -+ -+#ifdef DBG_TRACE_SPI_DATA -+ if (spi_xfer.rx_buf) { -+ int i; -+ printk("rx len %d:\n", spi_xfer.len); -+ for (i = 0 ; i < spi_xfer.len && i < 32 ; i++) { -+ printk(" %x", ((u8*)spi_xfer.rx_buf)[i]); -+ } -+ printk("\n"); -+ } -+#endif -+ return 0; -+} -+ -+/* Puts received data to circular buffer */ -+static void put_data_to_circ_buf(struct max3107_port *s, unsigned char *data, -+ int len) -+{ -+ struct uart_port *port = &s->port; -+ struct tty_struct *tty; -+ -+ DBG_TRACE("enter\n"); -+ -+ if (!port->state) { -+ /* UART is not open */ -+ dev_warn(&s->spi->dev, "UART is closed\n"); -+ return; -+ } -+ -+ tty = port->state->port.tty; -+ if (!tty) { -+ /* TTY is not open */ -+ dev_warn(&s->spi->dev, "TTY is closed\n"); -+ return; -+ } -+ -+ /* Insert received data */ -+ tty_insert_flip_string(tty, data, len); -+ /* Update RX counter */ -+ port->icount.rx += len; -+} -+ -+/* Handle data receiving */ -+static void max3107_handlerx(struct max3107_port *s, u16 rxlvl) -+{ -+ int i; -+ int j; -+ int len; /* SPI transfer buffer length */ -+ u16 buf[MAX3107_RX_FIFO_SIZE+2]; /* SPI transfer buffer -+ * +2 for RX FIFO interrupt -+ * disabling and RX level query -+ */ -+ u8 valid_str[MAX3107_RX_FIFO_SIZE]; -+ -+ DBG_TRACE("enter\n"); -+ -+ if (!s->rx_enabled) { -+ /* RX is disabled */ -+ return; -+ } -+ -+ if (rxlvl == 0) { -+ /* RX fifo is empty */ -+ return; -+ } else if (rxlvl >= MAX3107_RX_FIFO_SIZE) { -+ dev_warn(&s->spi->dev, "Possible RX FIFO overrun %d\n", rxlvl); -+ /* Ensure sanity of RX level */ -+ rxlvl = MAX3107_RX_FIFO_SIZE; -+ } -+ -+ while (rxlvl) { -+ DBG_TRACE("rxlvl %d\n", rxlvl); -+ /* Clear buffer */ -+ memset(buf, 0, sizeof(buf)); -+ len = 0; -+ if (s->irqen_reg & MAX3107_IRQ_RXFIFO_BIT) { -+ /* First disable RX FIFO interrupt */ -+ DBG_TRACE("Disabling RX INT\n"); -+ buf[0] = (MAX3107_WRITE_BIT | MAX3107_IRQEN_REG); -+ spin_lock(&s->data_lock); -+ s->irqen_reg &= ~MAX3107_IRQ_RXFIFO_BIT; -+ buf[0] |= s->irqen_reg; -+ spin_unlock(&s->data_lock); -+ len++; -+ } -+ /* Just increase the length by amount of words in FIFO since -+ * buffer was zeroed and SPI transfer of 0x0000 means reading -+ * from RX FIFO -+ */ -+ len += rxlvl; -+ /* Append RX level query */ -+ buf[len] = MAX3107_RXFIFOLVL_REG; -+ len++; -+ -+ /* Perform the SPI transfer */ -+ if (max3107_rw(s, (u8 *)buf, (u8 *)buf, len*2)) { -+ dev_err(&s->spi->dev, -+ "SPI transfer for RX handling failed\n"); -+ return; -+ } -+ -+ /* Skip RX FIFO interrupt disabling word if it was added */ -+ j = ((len-1)-rxlvl); -+ /* Read received words */ -+ for (i = 0; i < rxlvl; i++, j++) { -+ valid_str[i] = (u8)buf[j]; -+ } -+ put_data_to_circ_buf(s, valid_str, rxlvl); -+ /* Get new RX level */ -+ rxlvl = (buf[len-1] & MAX3107_SPI_RX_DATA_MASK); -+ } -+ -+ if (s->rx_enabled) { -+ /* RX still enabled, re-enable RX FIFO interrupt */ -+ DBG_TRACE("Enabling RX INT\n"); -+ buf[0] = (MAX3107_WRITE_BIT | MAX3107_IRQEN_REG); -+ spin_lock(&s->data_lock); -+ s->irqen_reg |= MAX3107_IRQ_RXFIFO_BIT; -+ buf[0] |= s->irqen_reg; -+ spin_unlock(&s->data_lock); -+ if (max3107_rw(s, (u8 *)buf, NULL, 2)) { -+ dev_err(&s->spi->dev, -+ "RX FIFO interrupt enabling failed\n"); -+ } -+ } -+ -+ /* Push the received data to receivers */ -+ tty_flip_buffer_push(s->port.state->port.tty); -+} -+ -+ -+/* Handle data sending */ -+static void max3107_handletx(struct max3107_port *s) -+{ -+ struct circ_buf *xmit = &s->port.state->xmit; -+ int i; -+ int len; /* SPI transfer buffer length */ -+ u16 buf[MAX3107_TX_FIFO_SIZE+3]; /* SPI transfer buffer -+ * +3 for TX FIFO empty -+ * interrupt disabling and -+ * enabling and TX enabling -+ */ -+ -+ DBG_TRACE("enter\n"); -+ -+ if (!s->tx_fifo_empty) { -+ /* Don't send more data before previous data is sent */ -+ return; -+ } -+ -+ if (uart_circ_empty(xmit) || uart_tx_stopped(&s->port)) { -+ /* No data to send or TX is stopped */ -+ return; -+ } -+ -+ /* Get length of data pending in circular buffer */ -+ len = uart_circ_chars_pending(xmit); -+ if (len) { -+ /* Limit to size of TX FIFO */ -+ if (len > MAX3107_TX_FIFO_SIZE) -+ len = MAX3107_TX_FIFO_SIZE; -+ -+ DBG_TRACE("txlen %d\n", len); -+ -+ /* Update TX counter */ -+ s->port.icount.tx += len; -+ -+ /* TX FIFO will no longer be empty */ -+ s->tx_fifo_empty = 0; -+ -+ i = 0; -+ if (s->irqen_reg & MAX3107_IRQ_TXEMPTY_BIT) { -+ /* First disable TX empty interrupt */ -+ DBG_TRACE("Disabling TE INT\n"); -+ buf[i] = (MAX3107_WRITE_BIT | MAX3107_IRQEN_REG); -+ spin_lock(&s->data_lock); -+ s->irqen_reg &= ~MAX3107_IRQ_TXEMPTY_BIT; -+ buf[i] |= s->irqen_reg; -+ spin_unlock(&s->data_lock); -+ i++; -+ len++; -+ } -+ -+ /* Add data to send */ -+ for ( ; i < len ; i++ ) { -+ buf[i] = (MAX3107_WRITE_BIT | MAX3107_THR_REG); -+ buf[i] |= ((u16)xmit->buf[xmit->tail] & -+ MAX3107_SPI_TX_DATA_MASK); -+ xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); -+ } -+ -+ if (!(s->irqen_reg & MAX3107_IRQ_TXEMPTY_BIT)) { -+ /* Enable TX empty interrupt */ -+ DBG_TRACE("Enabling TE INT\n"); -+ buf[i] = (MAX3107_WRITE_BIT | MAX3107_IRQEN_REG); -+ spin_lock(&s->data_lock); -+ s->irqen_reg |= MAX3107_IRQ_TXEMPTY_BIT; -+ buf[i] |= s->irqen_reg; -+ spin_unlock(&s->data_lock); -+ i++; -+ len++; -+ } -+ if (!s->tx_enabled) { -+ /* Enable TX */ -+ DBG_TRACE("Enable TX\n"); -+ buf[i] = (MAX3107_WRITE_BIT | MAX3107_MODE1_REG); -+ spin_lock(&s->data_lock); -+ s->mode1_reg &= ~MAX3107_MODE1_TXDIS_BIT; -+ buf[i] |= s->mode1_reg; -+ spin_unlock(&s->data_lock); -+ s->tx_enabled = 1; -+ i++; -+ len++; -+ } -+ -+ /* Perform the SPI transfer */ -+ if (max3107_rw(s, (u8 *)buf, NULL, len*2)) { -+ dev_err(&s->spi->dev, -+ "SPI transfer for TX handling failed\n"); -+ return; -+ } -+ } -+ -+ /* Indicate wake up if circular buffer is getting low on data */ -+ if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) -+ uart_write_wakeup(&s->port); -+ -+} -+ -+/* Handle interrupts -+ * Also reads and returns current RX FIFO level -+ */ -+static u16 handle_interrupt(struct max3107_port *s) -+{ -+ u16 buf[4]; /* Buffer for SPI transfers */ -+ u8 irq_status; -+ u16 rx_level; -+ -+ DBG_TRACE("enter\n"); -+ -+ /* Read IRQ status register */ -+ buf[0] = MAX3107_IRQSTS_REG; -+ /* Read status IRQ status register */ -+ buf[1] = MAX3107_STS_IRQSTS_REG; -+ /* Read LSR IRQ status register */ -+ buf[2] = MAX3107_LSR_IRQSTS_REG; -+ /* Query RX level */ -+ buf[3] = MAX3107_RXFIFOLVL_REG; -+ -+ if (max3107_rw(s, (u8 *)buf, (u8 *)buf, 8)) { -+ dev_err(&s->spi->dev, -+ "SPI transfer for interrupt handling failed\n"); -+ return 0; -+ } -+ -+ irq_status = (u8)buf[0]; -+ DBG_TRACE("IRQSTS %x\n", irq_status); -+ rx_level = (buf[3] & MAX3107_SPI_RX_DATA_MASK); -+ -+ if (irq_status & MAX3107_IRQ_LSR_BIT) { -+ /* LSR interrupt */ -+ if ( buf[2] & MAX3107_LSR_RXTO_BIT ) { -+ /* RX timeout interrupt, -+ * handled by normal RX handling -+ */ -+ DBG_TRACE("RX TO INT\n"); -+ } -+ } -+ -+ if (irq_status & MAX3107_IRQ_TXEMPTY_BIT) { -+ /* Tx empty interrupt, -+ * disable TX and set tx_fifo_empty flag -+ */ -+ DBG_TRACE("TE INT, disabling TX\n"); -+ buf[0] = (MAX3107_WRITE_BIT | MAX3107_MODE1_REG); -+ spin_lock(&s->data_lock); -+ s->mode1_reg |= MAX3107_MODE1_TXDIS_BIT; -+ buf[0] |= s->mode1_reg; -+ spin_unlock(&s->data_lock); -+ if (max3107_rw(s, (u8 *)buf, NULL, 2)) -+ dev_err(&s->spi->dev, -+ "SPI transfer for TX disabling failed\n"); -+ s->tx_enabled = 0; -+ s->tx_fifo_empty = 1; -+ } -+ -+ if (irq_status & MAX3107_IRQ_RXFIFO_BIT) { -+ /* RX FIFO interrupt, -+ * handled by normal RX handling -+ */ -+ DBG_TRACE("RFIFO INT\n"); -+ } -+ -+ /* Return RX level */ -+ return rx_level; -+} -+ -+/* Trigger work thread*/ -+static void max3107_dowork(struct max3107_port *s) -+{ -+ if (!work_pending(&s->work) && !freezing(current) && !s->suspended) -+ queue_work(s->workqueue, &s->work); -+} -+ -+/* Work thread */ -+static void max3107_work(struct work_struct *w) -+{ -+ struct max3107_port *s = container_of(w, struct max3107_port, work); -+ u16 rxlvl = 0; -+ int len; /* SPI transfer buffer length */ -+ u16 buf[5]; /* Buffer for SPI transfers */ -+ -+ DBG_TRACE("enter\n"); -+ -+ /* Start by reading current RX FIFO level */ -+ buf[0] = MAX3107_RXFIFOLVL_REG; -+ if (max3107_rw(s, (u8 *)buf, (u8 *)buf, 2)) { -+ dev_err(&s->spi->dev, -+ "SPI transfer for RX level query failed\n"); -+ rxlvl = 0; -+ } else { -+ rxlvl = (buf[0] & MAX3107_SPI_RX_DATA_MASK); -+ } -+ -+ do { -+ DBG_TRACE("rxlvl %d\n", rxlvl); -+ -+ /* Handle RX */ -+ max3107_handlerx(s, rxlvl); -+ rxlvl = 0; -+ -+ if (s->handle_irq) { -+ /* Handle pending interrupts -+ * We also get new RX FIFO level since new data may -+ * have been received while pushing received data to -+ * receivers -+ */ -+ s->handle_irq = 0; -+ rxlvl = handle_interrupt(s); -+ } -+ -+ /* Handle TX */ -+ max3107_handletx(s); -+ -+ /* Handle configuration changes */ -+ len = 0; -+ spin_lock(&s->data_lock); -+ if (s->mode1_commit) { -+ DBG_TRACE("mode1_commit\n"); -+ buf[len] = (MAX3107_WRITE_BIT | MAX3107_MODE1_REG); -+ buf[len++] |= s->mode1_reg; -+ s->mode1_commit = 0; -+ } -+ if (s->lcr_commit) { -+ DBG_TRACE("lcr_commit\n"); -+ buf[len] = (MAX3107_WRITE_BIT | MAX3107_LCR_REG); -+ buf[len++] |= s->lcr_reg; -+ s->lcr_commit = 0; -+ } -+ if (s->brg_commit) { -+ DBG_TRACE("brg_commit\n"); -+ buf[len] = (MAX3107_WRITE_BIT | MAX3107_BRGDIVMSB_REG); -+ buf[len++] |= ((s->brg_cfg >> 16) & -+ MAX3107_SPI_TX_DATA_MASK); -+ buf[len] = (MAX3107_WRITE_BIT | MAX3107_BRGDIVLSB_REG); -+ buf[len++] |= ((s->brg_cfg >> 8) & -+ MAX3107_SPI_TX_DATA_MASK); -+ buf[len] = (MAX3107_WRITE_BIT | MAX3107_BRGCFG_REG); -+ buf[len++] |= ((s->brg_cfg) & 0xff); -+ s->brg_commit = 0; -+ } -+ spin_unlock(&s->data_lock); -+ -+ if (len > 0) { -+ if (max3107_rw(s, (u8 *)buf, NULL, len*2)) -+ dev_err(&s->spi->dev, -+ "SPI transfer for config failed\n"); -+ } -+ -+ /* Reloop if interrupt handling indicated data in RX FIFO */ -+ } while (rxlvl); -+ -+} -+ -+/* Set sleep mode */ -+static void max3107_set_sleep(struct max3107_port *s, int mode) -+{ -+ u16 buf[1]; /* Buffer for SPI transfer */ -+ -+ DBG_TRACE("enter, mode %d\n", mode); -+ -+ buf[0] = (MAX3107_WRITE_BIT | MAX3107_MODE1_REG); -+ spin_lock(&s->data_lock); -+ switch (mode) { -+ case MAX3107_DISABLE_FORCED_SLEEP: -+ s->mode1_reg &= ~MAX3107_MODE1_FORCESLEEP_BIT; -+ break; -+ case MAX3107_ENABLE_FORCED_SLEEP: -+ s->mode1_reg |= MAX3107_MODE1_FORCESLEEP_BIT; -+ break; -+ case MAX3107_DISABLE_AUTOSLEEP: -+ s->mode1_reg &= ~MAX3107_MODE1_AUTOSLEEP_BIT; -+ break; -+ case MAX3107_ENABLE_AUTOSLEEP: -+ s->mode1_reg |= MAX3107_MODE1_AUTOSLEEP_BIT; -+ break; -+ default: -+ spin_unlock(&s->data_lock); -+ dev_warn(&s->spi->dev, "invalid sleep mode\n"); -+ return; -+ } -+ buf[0] |= s->mode1_reg; -+ spin_unlock(&s->data_lock); -+ -+ if (max3107_rw(s, (u8 *)buf, NULL, 2)) -+ dev_err(&s->spi->dev, "SPI transfer for sleep mode failed\n"); -+ -+ if (mode == MAX3107_DISABLE_AUTOSLEEP || -+ mode == MAX3107_DISABLE_FORCED_SLEEP ) { -+ msleep(MAX3107_WAKEUP_DELAY); -+ } -+} -+ -+/* Perform full register initialization */ -+static void max3107_register_init(struct max3107_port *s) -+{ -+ int len = 0; /* SPI transfer buffer length */ -+ u16 buf[11]; /* Buffer for SPI transfers */ -+ -+ DBG_TRACE("enter\n"); -+ -+ /* 1. Configure baud rate, 9600 as default */ -+ s->baud = 9600; -+ if (s->ext_clk) -+ s->brg_cfg = MAX3107_BRG_B9600; -+ else -+ s->brg_cfg = MAX3107_BRG_IB9600; -+ buf[len] = (MAX3107_WRITE_BIT | MAX3107_BRGDIVMSB_REG); -+ buf[len++] |= ((s->brg_cfg >> 16) & MAX3107_SPI_TX_DATA_MASK); -+ buf[len] = (MAX3107_WRITE_BIT | MAX3107_BRGDIVLSB_REG); -+ buf[len++] |= ((s->brg_cfg >> 8) & MAX3107_SPI_TX_DATA_MASK); -+ buf[len] = (MAX3107_WRITE_BIT | MAX3107_BRGCFG_REG); -+ buf[len++] |= ((s->brg_cfg) & 0xff); -+ -+ /* 2. Configure LCR register, 8N1 mode by default */ -+ s->lcr_reg = MAX3107_LCR_WORD_LEN_8; -+ buf[len] = (MAX3107_WRITE_BIT | MAX3107_LCR_REG); -+ buf[len++] |= s->lcr_reg; -+ -+ /* 3. Configure MODE 1 register */ -+ s->mode1_reg = 0; -+ /* Enable IRQ pin */ -+ s->mode1_reg |= MAX3107_MODE1_IRQSEL_BIT; -+ /* Disable TX */ -+ s->mode1_reg |= MAX3107_MODE1_TXDIS_BIT; -+ s->tx_enabled = 0; -+ /* RX is enabled */ -+ s->rx_enabled = 1; -+ buf[len] = (MAX3107_WRITE_BIT | MAX3107_MODE1_REG); -+ buf[len++] |= s->mode1_reg; -+ -+ /* 4. Configure MODE 2 register */ -+ buf[len] = (MAX3107_WRITE_BIT | MAX3107_MODE2_REG); -+ if (s->loopback) { -+ /* Enable loopback */ -+ buf[len] |= MAX3107_MODE2_LOOPBACK_BIT; -+ } -+ /* Reset FIFOs */ -+ buf[len++] |= MAX3107_MODE2_FIFORST_BIT; -+ s->tx_fifo_empty = 1; -+ -+ /* 5. Configure FIFO trigger level register */ -+ buf[len] = (MAX3107_WRITE_BIT | MAX3107_FIFOTRIGLVL_REG); -+ /* RX FIFO trigger for 16 words, TX FIFO trigger not used */ -+ buf[len++] |= (MAX3107_FIFOTRIGLVL_RX(16) | MAX3107_FIFOTRIGLVL_TX(0)); -+ -+ /* 6. Configure flow control levels */ -+ buf[len] = (MAX3107_WRITE_BIT | MAX3107_FLOWLVL_REG); -+ /* Flow control halt level 96, resume level 48 */ -+ buf[len++] |= (MAX3107_FLOWLVL_RES(48) | MAX3107_FLOWLVL_HALT(96)); -+ -+ /* 7. Configure flow control */ -+ buf[len] = (MAX3107_WRITE_BIT | MAX3107_FLOWCTRL_REG); -+ /* Enable auto CTS and auto RTS flow control */ -+ buf[len++] |= (MAX3107_FLOWCTRL_AUTOCTS_BIT | -+ MAX3107_FLOWCTRL_AUTORTS_BIT); -+ -+ /* 8. Configure RX timeout register */ -+ buf[len] = (MAX3107_WRITE_BIT | MAX3107_RXTO_REG); -+ /* Timeout after 48 character intervals */ -+ buf[len++] |= 0x0030; -+ -+ /* 9. Configure LSR interrupt enable register */ -+ buf[len] = (MAX3107_WRITE_BIT | MAX3107_LSR_IRQEN_REG); -+ /* Enable RX timeout interrupt */ -+ buf[len++] |= MAX3107_LSR_RXTO_BIT; -+ -+ /* Perform SPI transfer */ -+ if (max3107_rw(s, (u8 *)buf, NULL, len*2)) -+ dev_err(&s->spi->dev, "SPI transfer for init failed\n"); -+ -+ len = 0; -+ /* 10. Clear IRQ status register by reading it */ -+ buf[len++] = MAX3107_IRQSTS_REG; -+ -+ /* 11. Configure interrupt enable register */ -+ /* Enable LSR interrupt */ -+ s->irqen_reg = MAX3107_IRQ_LSR_BIT; -+ /* Enable RX FIFO interrupt */ -+ s->irqen_reg |= MAX3107_IRQ_RXFIFO_BIT; -+ buf[len] = (MAX3107_WRITE_BIT | MAX3107_IRQEN_REG); -+ buf[len++] |= s->irqen_reg; -+ -+ /* 12. Clear FIFO reset that was set in step 6 */ -+ buf[len] = (MAX3107_WRITE_BIT | MAX3107_MODE2_REG); -+ if (s->loopback) { -+ /* Keep loopback enabled */ -+ buf[len] |= MAX3107_MODE2_LOOPBACK_BIT; -+ } -+ buf[len++] |= 0x0000; -+ -+ /* Perform SPI transfer */ -+ if (max3107_rw(s, (u8 *)buf, (u8 *)buf, len*2)) -+ dev_err(&s->spi->dev, "SPI transfer for init failed\n"); -+ -+} -+ -+/* IRQ handler */ -+static irqreturn_t max3107_irq(int irqno, void *dev_id) -+{ -+ struct max3107_port *s = dev_id; -+ -+ if (irqno != s->spi->irq) { -+ /* Unexpected IRQ */ -+ return IRQ_NONE; -+ } -+ -+ /* Indicate irq */ -+ s->handle_irq = 1; -+ -+ /* Trigger work thread */ -+ max3107_dowork(s); -+ -+ return IRQ_HANDLED; -+} -+ -+/* HW suspension function -+ * -+ * Currently autosleep is used to decrease current consumption, alternative -+ * approach would be to set the chip to reset mode if UART is not being -+ * used but that would mess the GPIOs -+ * -+ */ -+static void max3107_hw_susp(struct max3107_port *s, int suspend) -+{ -+ DBG_TRACE("enter, suspend %d\n", suspend); -+ -+ if (suspend) { -+ /* Suspend requested, -+ * enable autosleep to decrease current consumption -+ */ -+ s->suspended = 1; -+ max3107_set_sleep(s, MAX3107_ENABLE_AUTOSLEEP); -+ } else { -+ /* Resume requested, -+ * disable autosleep -+ */ -+ s->suspended = 0; -+ max3107_set_sleep(s, MAX3107_DISABLE_AUTOSLEEP); -+ } -+} -+ -+/* Modem status IRQ enabling */ -+static void max3107_enable_ms(struct uart_port *port) -+{ -+ /* Modem status not supported */ -+} -+ -+/* Data send function */ -+static void max3107_start_tx(struct uart_port *port) -+{ -+ struct max3107_port *s = container_of(port, struct max3107_port, port); -+ -+ DBG_TRACE("enter\n"); -+ -+ /* Trigger work thread for sending data */ -+ max3107_dowork(s); -+} -+ -+/* Function for checking that there is no pending transfers */ -+static unsigned int max3107_tx_empty(struct uart_port *port) -+{ -+ struct max3107_port *s = container_of(port, struct max3107_port, port); -+ -+ DBG_TRACE("returning %d\n", -+ (s->tx_fifo_empty && uart_circ_empty(&s->port.state->xmit))); -+ return (s->tx_fifo_empty && uart_circ_empty(&s->port.state->xmit)); -+} -+ -+/* Function for stopping RX */ -+static void max3107_stop_rx(struct uart_port *port) -+{ -+ struct max3107_port *s = container_of(port, struct max3107_port, port); -+ -+ DBG_TRACE("enter\n"); -+ -+ /* Set RX disabled in MODE 1 register */ -+ spin_lock(&s->data_lock); -+ s->mode1_reg |= MAX3107_MODE1_RXDIS_BIT; -+ s->mode1_commit = 1; -+ spin_unlock(&s->data_lock); -+ /* Set RX disabled */ -+ s->rx_enabled = 0; -+ /* Trigger work thread for doing the actual configuration change */ -+ max3107_dowork(s); -+} -+ -+/* Function for returning control pin states */ -+static unsigned int max3107_get_mctrl(struct uart_port *port) -+{ -+ /* DCD and DSR are not wired and CTS/RTS is handled automatically -+ * so just indicate DSR and CAR asserted -+ */ -+ return (TIOCM_DSR | TIOCM_CAR); -+} -+ -+/* Function for setting control pin states */ -+static void max3107_set_mctrl(struct uart_port *port, unsigned int mctrl) -+{ -+ /* DCD and DSR are not wired and CTS/RTS is hadnled automatically -+ * so do nothing -+ */ -+} -+ -+/* Function for configuring UART parameters */ -+static void max3107_set_termios(struct uart_port *port, -+ struct ktermios *termios, -+ struct ktermios *old) -+{ -+ struct max3107_port *s = container_of(port, struct max3107_port, port); -+ struct tty_struct *tty; -+ int baud; -+ u16 new_lcr = 0; -+ u32 new_brg = 0; -+ -+ DBG_TRACE("enter\n"); -+ -+ if (!port->state) { -+ /* UART is not open */ -+ dev_warn(&s->spi->dev, "UART is closed\n"); -+ return; -+ } -+ -+ tty = port->state->port.tty; -+ if (!tty) { -+ /* TTY is not open */ -+ dev_warn(&s->spi->dev, "TTY is closed\n"); -+ return; -+ } -+ -+ if (old) { -+ if ((termios->c_cflag == old->c_cflag) && -+ (RELEVANT_IFLAG(termios->c_iflag) == -+ RELEVANT_IFLAG(old->c_iflag))) { -+ /* Nothing relevant is changing */ -+ return; -+ } -+ } -+ -+ /* Get new LCR register values */ -+ /* Word size */ -+ if ((termios->c_cflag & CSIZE) == CS7) -+ new_lcr |= MAX3107_LCR_WORD_LEN_7; -+ else -+ new_lcr |= MAX3107_LCR_WORD_LEN_8; -+ -+ /* Parity */ -+ if (termios->c_cflag & PARENB) { -+ new_lcr |= MAX3107_LCR_PARITY_BIT; -+ if (!(termios->c_cflag & PARODD)) -+ new_lcr |= MAX3107_LCR_EVENPARITY_BIT; -+ } -+ -+ /* Stop bits */ -+ if (termios->c_cflag & CSTOPB) { -+ /* 2 stop bits */ -+ new_lcr |= MAX3107_LCR_STOPLEN_BIT; -+ } -+ -+ /* Mask termios capabilities we don't support */ -+ termios->c_cflag &= ~CMSPAR; -+ -+ /* Set status ignore mask */ -+ s->port.ignore_status_mask = 0; -+ if (termios->c_iflag & IGNPAR) -+ s->port.ignore_status_mask |= MAX3107_ALL_ERRORS; -+ -+ /* Set low latency to immediately handle pushed data */ -+ s->port.state->port.tty->low_latency = 1; -+ -+ /* Get new baud rate generator configuration */ -+ baud = tty_get_baud_rate(tty); -+ switch (baud) { -+ case 300: -+ new_brg = s->ext_clk ? MAX3107_BRG_B300 : MAX3107_BRG_IB300; -+ break; -+ case 600: -+ new_brg = s->ext_clk ? MAX3107_BRG_B600 : MAX3107_BRG_IB600; -+ break; -+ case 1200: -+ new_brg = s->ext_clk ? MAX3107_BRG_B1200 : MAX3107_BRG_IB1200; -+ break; -+ case 2400: -+ new_brg = s->ext_clk ? MAX3107_BRG_B2400 : MAX3107_BRG_IB2400; -+ break; -+ case 4800: -+ new_brg = s->ext_clk ? MAX3107_BRG_B4800 : MAX3107_BRG_IB4800; -+ break; -+ case 9600: -+ new_brg = s->ext_clk ? MAX3107_BRG_B9600 : MAX3107_BRG_IB9600; -+ break; -+ case 19200: -+ new_brg = s->ext_clk ? MAX3107_BRG_B19200 : MAX3107_BRG_IB19200; -+ break; -+ case 38400: -+ new_brg = s->ext_clk ? MAX3107_BRG_B38400 : MAX3107_BRG_IB38400; -+ break; -+ case 57600: -+ new_brg = s->ext_clk ? MAX3107_BRG_B57600 : MAX3107_BRG_IB57600; -+ break; -+ case 115200: -+ new_brg = s->ext_clk ? MAX3107_BRG_B115200 : MAX3107_BRG_IB115200; -+ break; -+ case 230400: -+ new_brg = s->ext_clk ? MAX3107_BRG_B230400 : MAX3107_BRG_IB230400; -+ break; -+ case 460800: -+ new_brg = s->ext_clk ? MAX3107_BRG_B460800 : MAX3107_BRG_IB460800; -+ break; -+ case 921600: -+ new_brg = s->ext_clk ? MAX3107_BRG_B921600 : MAX3107_BRG_IB921600; -+ break; -+ default: -+ /* Use previous */ -+ baud = s->baud; -+ new_brg = s->brg_cfg; -+ tty_termios_encode_baud_rate(termios, baud, baud); -+ } -+ s->baud = baud; -+ -+ /* Update timeout according to new baud rate */ -+ uart_update_timeout(port, termios->c_cflag, baud); -+ -+ spin_lock(&s->data_lock); -+ if (s->lcr_reg != new_lcr) { -+ s->lcr_reg = new_lcr; -+ s->lcr_commit = 1; -+ } -+ if (s->brg_cfg != new_brg) { -+ s->brg_cfg = new_brg; -+ s->brg_commit = 1; -+ } -+ spin_unlock(&s->data_lock); -+ -+ /* Trigger work thread for doing the actual configuration change */ -+ max3107_dowork(s); -+} -+ -+/* Port shutdown function */ -+static void max3107_shutdown(struct uart_port *port) -+{ -+ struct max3107_port *s = container_of(port, struct max3107_port, port); -+ -+ DBG_TRACE("enter\n"); -+ -+ if (s->suspended) { -+ /* Resume HW */ -+ max3107_hw_susp(s, 0); -+ } -+ -+ /* Free the interrupt */ -+ free_irq(s->spi->irq, s); -+ -+ if (s->workqueue) { -+ /* Flush and destroy work queue */ -+ flush_workqueue(s->workqueue); -+ destroy_workqueue(s->workqueue); -+ s->workqueue = NULL; -+ } -+ -+ /* Suspend HW */ -+ max3107_hw_susp(s, 1); -+} -+ -+/* Port startup function */ -+static int max3107_startup(struct uart_port *port) -+{ -+ struct max3107_port *s = container_of(port, struct max3107_port, port); -+ -+ DBG_TRACE("enter\n"); -+ -+ /* Initialize work queue */ -+ s->workqueue = create_freezeable_workqueue("max3107"); -+ if (!s->workqueue) { -+ dev_err(&s->spi->dev, "Workqueue creation failed\n"); -+ return -EBUSY; -+ } -+ INIT_WORK(&s->work, max3107_work); -+ -+ /* Setup IRQ */ -+ if (request_irq(s->spi->irq, max3107_irq, IRQF_TRIGGER_FALLING, -+ "max3107", s)) { -+ dev_err(&s->spi->dev, "IRQ reguest failed\n"); -+ destroy_workqueue(s->workqueue); -+ s->workqueue = NULL; -+ return -EBUSY; -+ } -+ -+ /* Resume HW */ -+ max3107_hw_susp(s, 0); -+ -+ /* Init registers */ -+ max3107_register_init(s); -+ -+ return 0; -+} -+ -+/* Port type function */ -+static const char *max3107_type(struct uart_port *port) -+{ -+ struct max3107_port *s = container_of(port, struct max3107_port, port); -+ return s->spi->modalias; -+} -+ -+/* Port release function */ -+static void max3107_release_port(struct uart_port *port) -+{ -+ /* Do nothing */ -+} -+ -+/* Port request function */ -+static int max3107_request_port(struct uart_port *port) -+{ -+ /* Do nothing */ -+ return 0; -+} -+ -+/* Port config function */ -+static void max3107_config_port(struct uart_port *port, int flags) -+{ -+ struct max3107_port *s = container_of(port, struct max3107_port, port); -+ -+ /* Use PORT_MAX3100 since we are at least int the same serie */ -+ s->port.type = PORT_MAX3100; -+} -+ -+/* Port verify function */ -+static int max3107_verify_port(struct uart_port *port, -+ struct serial_struct *ser) -+{ -+ if (ser->type == PORT_UNKNOWN || ser->type == PORT_MAX3100) -+ return 0; -+ -+ return -EINVAL; -+} -+ -+/* Port stop TX function */ -+static void max3107_stop_tx(struct uart_port *port) -+{ -+ /* Do nothing */ -+} -+ -+/* Port break control function */ -+static void max3107_break_ctl(struct uart_port *port, int break_state) -+{ -+ /* We don't support break control, do nothing */ -+} -+ -+/* GPIO direction query function */ -+static enum gpio_direction max3107_gpio_get_direction(struct gpio_chip *chip, -+ unsigned offset) -+{ -+ struct max3107_port *s = container_of(chip, struct max3107_port, chip); -+ u16 buf[1]; /* Buffer for SPI transfer */ -+ -+ DBG_TRACE("enter\n"); -+ -+ if (offset >= MAX3107_GPIO_COUNT) { -+ dev_err(&s->spi->dev, "Invalid GPIO\n"); -+ return -EINVAL; -+ } -+ -+ /* Read current GPIO configuration register */ -+ buf[0] = MAX3107_GPIOCFG_REG; -+ /* Perform SPI transfer */ -+ if (max3107_rw(s, (u8 *)buf, (u8 *)buf, 2)) { -+ dev_err(&s->spi->dev, -+ "SPI transfer for GPIO config read failed\n"); -+ return -EIO; -+ } -+ buf[0] &= MAX3107_SPI_RX_DATA_MASK; -+ -+ /* Check the direction bit */ -+ if (buf[0] & (0x0001 << offset)) -+ return DIRECTION_OUT; -+ return DIRECTION_IN; -+} -+ -+/* GPIO direction to input function */ -+static int max3107_gpio_direction_in(struct gpio_chip *chip, unsigned offset) -+{ -+ struct max3107_port *s = container_of(chip, struct max3107_port, chip); -+ u16 buf[1]; /* Buffer for SPI transfer */ -+ -+ DBG_TRACE("enter\n"); -+ -+ if (offset >= MAX3107_GPIO_COUNT) { -+ dev_err(&s->spi->dev, "Invalid GPIO\n"); -+ return -EINVAL; -+ } -+ -+ /* Read current GPIO configuration register */ -+ buf[0] = MAX3107_GPIOCFG_REG; -+ /* Perform SPI transfer */ -+ if (max3107_rw(s, (u8 *)buf, (u8 *)buf, 2)) { -+ dev_err(&s->spi->dev, -+ "SPI transfer for GPIO config read failed\n"); -+ return -EIO; -+ } -+ buf[0] &= MAX3107_SPI_RX_DATA_MASK; -+ -+ /* Set GPIO to input */ -+ buf[0] &= ~(0x0001 << offset); -+ -+ /* Write new GPIO configuration register value */ -+ buf[0] |= (MAX3107_WRITE_BIT | MAX3107_GPIOCFG_REG); -+ /* Perform SPI transfer */ -+ if (max3107_rw(s, (u8 *)buf, NULL, 2)) { -+ dev_err(&s->spi->dev, -+ "SPI transfer for GPIO config write failed\n"); -+ return -EIO; -+ } -+ return 0; -+} -+ -+/* GPIO direction to output function */ -+static int max3107_gpio_direction_out(struct gpio_chip *chip, unsigned offset, -+ int value) -+{ -+ struct max3107_port *s = container_of(chip, struct max3107_port, chip); -+ u16 buf[2]; /* Buffer for SPI transfers */ -+ -+ DBG_TRACE("enter\n"); -+ -+ if (offset >= MAX3107_GPIO_COUNT) { -+ dev_err(&s->spi->dev, "Invalid GPIO\n"); -+ return -EINVAL; -+ } -+ -+ /* Read current GPIO configuration and data registers */ -+ buf[0] = MAX3107_GPIOCFG_REG; -+ buf[1] = MAX3107_GPIODATA_REG; -+ /* Perform SPI transfer */ -+ if (max3107_rw(s, (u8 *)buf, (u8 *)buf, 4)) { -+ dev_err(&s->spi->dev, -+ "SPI transfer for GPIO config and data read failed\n"); -+ return -EIO; -+ } -+ buf[0] &= MAX3107_SPI_RX_DATA_MASK; -+ buf[1] &= MAX3107_SPI_RX_DATA_MASK; -+ -+ /* Set GPIO to output */ -+ buf[0] |= (0x0001 << offset); -+ /* Set value */ -+ if (value) -+ buf[1] |= (0x0001 << offset); -+ else -+ buf[1] &= ~(0x0001 << offset); -+ -+ /* Write new GPIO configuration and data register values */ -+ buf[0] |= (MAX3107_WRITE_BIT | MAX3107_GPIOCFG_REG); -+ buf[1] |= (MAX3107_WRITE_BIT | MAX3107_GPIODATA_REG); -+ /* Perform SPI transfer */ -+ if (max3107_rw(s, (u8 *)buf, NULL, 4)) { -+ dev_err(&s->spi->dev, -+ "SPI transfer for GPIO config and data write failed\n"); -+ return -EIO; -+ } -+ return 0; -+} -+ -+/* GPIO value query function */ -+static int max3107_gpio_get(struct gpio_chip *chip, unsigned offset) -+{ -+ struct max3107_port *s = container_of(chip, struct max3107_port, chip); -+ u16 buf[1]; /* Buffer for SPI transfer */ -+ -+ DBG_TRACE("enter\n"); -+ -+ if (offset >= MAX3107_GPIO_COUNT) { -+ dev_err(&s->spi->dev, "Invalid GPIO\n"); -+ return -EINVAL; -+ } -+ -+ /* Read current GPIO data register */ -+ buf[0] = MAX3107_GPIODATA_REG; -+ /* Perform SPI transfer */ -+ if (max3107_rw(s, (u8 *)buf, (u8 *)buf, 2)) { -+ dev_err(&s->spi->dev, -+ "SPI transfer for GPIO data read failed\n"); -+ return -EIO; -+ } -+ buf[0] &= MAX3107_SPI_RX_DATA_MASK; -+ -+ /* Return value */ -+ return buf[0] & (0x0001 << offset); -+} -+ -+/* GPIO value set function */ -+static void max3107_gpio_set(struct gpio_chip *chip, unsigned offset, int value) -+{ -+ struct max3107_port *s = container_of(chip, struct max3107_port, chip); -+ u16 buf[2]; /* Buffer for SPI transfers */ -+ -+ DBG_TRACE("enter\n"); -+ -+ if (offset >= MAX3107_GPIO_COUNT) { -+ dev_err(&s->spi->dev, "Invalid GPIO\n"); -+ return; -+ } -+ -+ /* Read current GPIO configuration registers*/ -+ buf[0] = MAX3107_GPIODATA_REG; -+ buf[1] = MAX3107_GPIOCFG_REG; -+ /* Perform SPI transfer */ -+ if (max3107_rw(s, (u8 *)buf, (u8 *)buf, 4)) { -+ dev_err(&s->spi->dev, -+ "SPI transfer for GPIO data and config read failed\n"); -+ return; -+ } -+ buf[0] &= MAX3107_SPI_RX_DATA_MASK; -+ buf[1] &= MAX3107_SPI_RX_DATA_MASK; -+ -+ if (!(buf[1] & (0x0001 << offset))) { -+ /* Configured as input, can't set value */ -+ dev_warn(&s->spi->dev, -+ "Trying to set value for input GPIO\n"); -+ return; -+ } -+ -+ /* Set value */ -+ if (value) -+ buf[0] |= (0x0001 << offset); -+ else -+ buf[0] &= ~(0x0001 << offset); -+ -+ /* Write new GPIO data register value */ -+ buf[0] |= (MAX3107_WRITE_BIT | MAX3107_GPIODATA_REG); -+ /* Perform SPI transfer */ -+ if (max3107_rw(s, (u8 *)buf, NULL, 2)) { -+ dev_err(&s->spi->dev, -+ "SPI transfer for GPIO data write failed\n"); -+ } -+} -+ -+/* Platform data */ -+static struct max3107_plat max3107_plat_data = { -+ .loopback = 0, -+ .ext_clk = 1, -+#ifdef CONFIG_MAX3107_LOW_POWER -+ .max3107_hw_suspend = &max3107_hw_susp, -+#endif /* CONFIG_MAX3107_LOW_POWER */ -+ .polled_mode = 0, -+ .poll_time = 0, -+}; -+ -+/* Port functions */ -+static struct uart_ops max3107_ops = { -+ .tx_empty = max3107_tx_empty, -+ .set_mctrl = max3107_set_mctrl, -+ .get_mctrl = max3107_get_mctrl, -+ .stop_tx = max3107_stop_tx, -+ .start_tx = max3107_start_tx, -+ .stop_rx = max3107_stop_rx, -+ .enable_ms = max3107_enable_ms, -+ .break_ctl = max3107_break_ctl, -+ .startup = max3107_startup, -+ .shutdown = max3107_shutdown, -+ .set_termios = max3107_set_termios, -+ .type = max3107_type, -+ .release_port = max3107_release_port, -+ .request_port = max3107_request_port, -+ .config_port = max3107_config_port, -+ .verify_port = max3107_verify_port, -+}; -+ -+/* UART driver data */ -+static struct uart_driver max3107_uart_driver = { -+ .owner = THIS_MODULE, -+ .driver_name = "ttyMAX", -+ .dev_name = "ttyMAX", -+ .major = MAX3107_MAJOR, -+ .minor = MAX3107_MINOR, -+ .nr = 1, -+}; -+ -+/* GPIO chip data */ -+static struct gpio_chip max3107_gpio_chip = { -+ .owner = THIS_MODULE, -+ .get_direction = max3107_gpio_get_direction, -+ .direction_input = max3107_gpio_direction_in, -+ .direction_output = max3107_gpio_direction_out, -+ .get = max3107_gpio_get, -+ .set = max3107_gpio_set, -+ .can_sleep = 1, -+ .base = MAX3107_GPIO_BASE, -+ .ngpio = MAX3107_GPIO_COUNT, -+}; -+ -+/* Device probe function */ -+static int __devinit max3107_probe(struct spi_device *spi) -+{ -+ struct max3107_port *s; -+ struct max3107_plat *pdata = &max3107_plat_data; -+ u16 buf[2]; /* Buffer for SPI transfers */ -+ int retval; -+ -+ DBG_TRACE("enter\n"); -+ -+ /* Reset the chip */ -+ if (gpio_request(MAX3107_RESET_GPIO, "max3107")) { -+ printk(KERN_ERR "Requesting RESET GPIO failed\n"); -+ return -EIO; -+ } -+ if (gpio_direction_output(MAX3107_RESET_GPIO, 0)) { -+ printk(KERN_ERR "Setting RESET GPIO to 0 failed\n"); -+ gpio_free(MAX3107_RESET_GPIO); -+ return -EIO; -+ } -+ msleep(MAX3107_RESET_DELAY); -+ if (gpio_direction_output(MAX3107_RESET_GPIO, 1)) { -+ printk(KERN_ERR "Setting RESET GPIO to 1 failed\n"); -+ gpio_free(MAX3107_RESET_GPIO); -+ return -EIO; -+ } -+ gpio_free(MAX3107_RESET_GPIO); -+ msleep(MAX3107_WAKEUP_DELAY); -+ -+ /* Allocate port structure */ -+ s = kzalloc(sizeof(*s), GFP_KERNEL); -+ if (!s) { -+ printk(KERN_ERR "Allocating port structure failed\n"); -+ return -ENOMEM; -+ } -+ -+ /* Initialize shared data lock */ -+ spin_lock_init(&s->data_lock); -+ -+ /* SPI intializations */ -+ dev_set_drvdata(&spi->dev, s); -+ spi->mode = SPI_MODE_0; -+ spi->dev.platform_data = pdata; -+ spi->bits_per_word = 16; -+ s->ext_clk = pdata->ext_clk; -+ s->loopback = pdata->loopback; -+ spi_setup(spi); -+ s->spi = spi; -+ -+ /* Check REV ID to ensure we are talking to what we expect */ -+ buf[0] = MAX3107_REVID_REG; -+ if (max3107_rw(s, (u8 *)buf, (u8 *)buf, 2)) { -+ dev_err(&s->spi->dev, "SPI transfer for REVID read failed\n"); -+ return -EIO; -+ } -+ if ((buf[0] & MAX3107_SPI_RX_DATA_MASK) != MAX3107_REVID1 && -+ (buf[0] & MAX3107_SPI_RX_DATA_MASK) != MAX3107_REVID2) { -+ dev_err(&s->spi->dev, "REVID %x does not match\n", -+ (buf[0] & MAX3107_SPI_RX_DATA_MASK) ); -+ return -ENODEV; -+ } -+ -+ /* Disable all interrupts */ -+ buf[0] = (MAX3107_WRITE_BIT | MAX3107_IRQEN_REG | 0x0000); -+ buf[0] |= 0x0000; -+ -+ /* Configure clock source */ -+ buf[1] = (MAX3107_WRITE_BIT | MAX3107_CLKSRC_REG); -+ if (s->ext_clk) { -+ /* External clock */ -+ buf[1] |= MAX3107_CLKSRC_EXTCLK_BIT; -+ } -+ /* PLL bypass */ -+ buf[1] |= MAX3107_CLKSRC_PLLBYP_BIT; -+ -+ /* Perform SPI transfer */ -+ if (max3107_rw(s, (u8 *)buf, NULL, 4)) { -+ dev_err(&s->spi->dev, "SPI transfer for init failed\n"); -+ return -EIO; -+ } -+ -+ -+ /* Register UART driver */ -+ retval = uart_register_driver(&max3107_uart_driver); -+ if (retval) { -+ dev_err(&s->spi->dev, "Registering UART driver failed\n"); -+ return retval; -+ } -+ -+ /* Initialize UART port data */ -+ s->port.fifosize = 128; -+ s->port.ops = &max3107_ops; -+ s->port.line = 0; -+ s->port.dev = &spi->dev; -+ s->port.uartclk = 9600; -+ s->port.flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF; -+ s->port.irq = s->spi->irq; -+ /* Use PORT_MAX3100 since we are at least int the same serie */ -+ s->port.type = PORT_MAX3100; -+ -+ /* Add UART port */ -+ retval = uart_add_one_port(&max3107_uart_driver, &s->port); -+ if (retval < 0) { -+ dev_err(&s->spi->dev, "Adding UART port failed\n"); -+ return retval; -+ } -+ -+ /* Initialize GPIO chip data */ -+ s->chip = max3107_gpio_chip; -+ s->chip.label = spi->modalias; -+ s->chip.dev = &spi->dev; -+ -+ /* Add GPIO chip */ -+ retval = gpiochip_add(&s->chip); -+ if (retval) { -+ dev_err(&s->spi->dev, "Adding GPIO chip failed\n"); -+ return retval; -+ } -+ -+ /* Go to suspend mode */ -+ max3107_hw_susp(s, 1); -+ -+ return 0; -+} -+ -+/* Driver remove function */ -+static int __devexit max3107_remove(struct spi_device *spi) -+{ -+ struct max3107_port *s = dev_get_drvdata(&spi->dev); -+ -+ DBG_TRACE("enter\n"); -+ -+ /* Remove GPIO chip */ -+ if (gpiochip_remove(&s->chip)) -+ dev_warn(&s->spi->dev, "Removing GPIO chip failed\n"); -+ -+ /* Remove port */ -+ if (uart_remove_one_port(&max3107_uart_driver, &s->port)) -+ dev_warn(&s->spi->dev, "Removing UART port failed\n"); -+ -+ /* Unregister UART driver */ -+ uart_unregister_driver(&max3107_uart_driver); -+ -+ /* Free port structure */ -+ kfree(s); -+ -+ return 0; -+} -+ -+/* Driver suspend function */ -+static int max3107_suspend(struct spi_device *spi, pm_message_t state) -+{ -+#ifdef CONFIG_PM -+ struct max3107_port *s = dev_get_drvdata(&spi->dev); -+ -+ DBG_TRACE("enter\n"); -+ -+ /* Suspend UART port */ -+ uart_suspend_port(&max3107_uart_driver, &s->port); -+ -+ /* Go to suspend mode */ -+ max3107_hw_susp(s, 1); -+#endif /* CONFIG_PM */ -+ return 0; -+} -+ -+/* Driver resume function */ -+static int max3107_resume(struct spi_device *spi) -+{ -+#ifdef CONFIG_PM -+ struct max3107_port *s = dev_get_drvdata(&spi->dev); -+ -+ DBG_TRACE("enter\n"); -+ -+ /* Resume from suspend */ -+ max3107_hw_susp(s, 0); -+ -+ /* Resume UART port */ -+ uart_resume_port(&max3107_uart_driver, &s->port); -+#endif /* CONFIG_PM */ -+ return 0; -+} -+ -+/* Spi driver data */ -+static struct spi_driver max3107_driver = { -+ .driver = { -+ .name = "max3107", -+ .bus = &spi_bus_type, -+ .owner = THIS_MODULE, -+ }, -+ .probe = max3107_probe, -+ .remove = __devexit_p(max3107_remove), -+ .suspend = max3107_suspend, -+ .resume = max3107_resume, -+}; -+ -+/* Driver init function */ -+static int __init max3107_init(void) -+{ -+ DBG_TRACE("enter\n"); -+ return spi_register_driver(&max3107_driver); -+} -+ -+/* Driver exit function */ -+static void __exit max3107_exit(void) -+{ -+ DBG_TRACE("enter\n"); -+ spi_unregister_driver(&max3107_driver); -+} -+ -+module_init(max3107_init); -+module_exit(max3107_exit); -+ -+MODULE_DESCRIPTION("MAX3107 driver"); -+MODULE_AUTHOR("Aavamobile"); -+MODULE_ALIAS("max3107-spi-uart"); -+MODULE_LICENSE("GPLv2"); -Index: linux-2.6.33/drivers/spi/mrst_spi.c -=================================================================== ---- linux-2.6.33.orig/drivers/spi/mrst_spi.c -+++ linux-2.6.33/drivers/spi/mrst_spi.c -@@ -1364,8 +1364,16 @@ static struct pci_driver mrst_spi_driver - .resume = mrst_spi_resume, - }; - -+/* -+ * spi_register_master will call scan board info, and MRST -+ * should only have one board_info registered -+ */ - static int __init mrst_spi_init(void) - { -+/*#ifdef CONFIG_SERIAL_MAX3107*/ -+/* spi_register_board_info(mrst_spi_board_info,*/ -+/* ARRAY_SIZE(mrst_spi_board_info));*/ -+/*#endif*/ - return pci_register_driver(&mrst_spi_driver); - } - -Index: linux-2.6.33/include/linux/serial_max3107.h -=================================================================== ---- /dev/null -+++ linux-2.6.33/include/linux/serial_max3107.h -@@ -0,0 +1,352 @@ -+/* -+ * max3107.h - spi uart protocol driver header for Maxim 3107 -+ * -+ * Copyright (C) Aavamobile 2009 -+ * Based on serial_max3100.h by Christian Pellegrin -+ * -+ * 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; either version 2 of the License, or -+ * (at your option) any later version. -+ */ -+ -+#ifndef _LINUX_SERIAL_MAX3107_H -+#define _LINUX_SERIAL_MAX3107_H -+ -+/* Serial definitions */ -+#define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK)) -+ -+/* Serial error status definitions */ -+#define MAX3107_PARITY_ERROR 1 -+#define MAX3107_FRAME_ERROR 2 -+#define MAX3107_OVERRUN_ERROR 4 -+#define MAX3107_ALL_ERRORS (MAX3107_PARITY_ERROR | \ -+ MAX3107_FRAME_ERROR | \ -+ MAX3107_OVERRUN_ERROR) -+ -+ -+/* TTY definitions */ -+#define MAX3107_MAJOR TTY_MAJOR -+#define MAX3107_MINOR 65 -+ -+ -+/* GPIO definitions */ -+#define MAX3107_GPIO_BASE 88 -+#define MAX3107_GPIO_COUNT 4 -+ -+ -+/* GPIO connected to chip's reset pin */ -+#define MAX3107_RESET_GPIO 87 -+ -+ -+/* Chip reset delay */ -+#define MAX3107_RESET_DELAY 10 -+ -+/* Chip wakeup delay */ -+#define MAX3107_WAKEUP_DELAY 50 -+ -+ -+/* Sleep mode definitions */ -+#define MAX3107_DISABLE_FORCED_SLEEP 0 -+#define MAX3107_ENABLE_FORCED_SLEEP 1 -+#define MAX3107_DISABLE_AUTOSLEEP 2 -+#define MAX3107_ENABLE_AUTOSLEEP 3 -+ -+ -+/* Definitions for register access with SPI transfers -+ * -+ * SPI transfer format: -+ * -+ * Master to slave bits xzzzzzzzyyyyyyyy -+ * Slave to master bits aaaaaaaabbbbbbbb -+ * -+ * where: -+ * x = 0 for reads, 1 for writes -+ * z = register address -+ * y = new register value if write, 0 if read -+ * a = unspecified -+ * b = register value if read, unspecified if write -+ */ -+ -+/* SPI speed */ -+#define MAX3107_SPI_SPEED (3125000 * 2) -+ -+/* Write bit */ -+#define MAX3107_WRITE_BIT (1 << 15) -+ -+/* SPI TX data mask */ -+#define MAX3107_SPI_RX_DATA_MASK (0x00ff) -+ -+/* SPI RX data mask */ -+#define MAX3107_SPI_TX_DATA_MASK (0x00ff) -+ -+/* Register access masks */ -+#define MAX3107_RHR_REG (0x0000) /* RX FIFO */ -+#define MAX3107_THR_REG (0x0000) /* TX FIFO */ -+#define MAX3107_IRQEN_REG (0x0100) /* IRQ enable */ -+#define MAX3107_IRQSTS_REG (0x0200) /* IRQ status */ -+#define MAX3107_LSR_IRQEN_REG (0x0300) /* LSR IRQ enable */ -+#define MAX3107_LSR_IRQSTS_REG (0x0400) /* LSR IRQ status */ -+#define MAX3107_SPCHR_IRQEN_REG (0x0500) /* Special char IRQ enable */ -+#define MAX3107_SPCHR_IRQSTS_REG (0x0600) /* Special char IRQ status */ -+#define MAX3107_STS_IRQEN_REG (0x0700) /* Status IRQ enable */ -+#define MAX3107_STS_IRQSTS_REG (0x0800) /* Status IRQ status */ -+#define MAX3107_MODE1_REG (0x0900) /* MODE1 */ -+#define MAX3107_MODE2_REG (0x0a00) /* MODE2 */ -+#define MAX3107_LCR_REG (0x0b00) /* LCR */ -+#define MAX3107_RXTO_REG (0x0c00) /* RX timeout */ -+#define MAX3107_HDPIXDELAY_REG (0x0d00) /* Auto transceiver delays */ -+#define MAX3107_IRDA_REG (0x0e00) /* IRDA settings */ -+#define MAX3107_FLOWLVL_REG (0x0f00) /* Flow control levels */ -+#define MAX3107_FIFOTRIGLVL_REG (0x1000) /* FIFO IRQ trigger levels */ -+#define MAX3107_TXFIFOLVL_REG (0x1100) /* TX FIFO level */ -+#define MAX3107_RXFIFOLVL_REG (0x1200) /* RX FIFO level */ -+#define MAX3107_FLOWCTRL_REG (0x1300) /* Flow control */ -+#define MAX3107_XON1_REG (0x1400) /* XON1 character */ -+#define MAX3107_XON2_REG (0x1500) /* XON2 character */ -+#define MAX3107_XOFF1_REG (0x1600) /* XOFF1 character */ -+#define MAX3107_XOFF2_REG (0x1700) /* XOFF2 character */ -+#define MAX3107_GPIOCFG_REG (0x1800) /* GPIO config */ -+#define MAX3107_GPIODATA_REG (0x1900) /* GPIO data */ -+#define MAX3107_PLLCFG_REG (0x1a00) /* PLL config */ -+#define MAX3107_BRGCFG_REG (0x1b00) /* Baud rate generator conf */ -+#define MAX3107_BRGDIVLSB_REG (0x1c00) /* Baud rate divisor LSB */ -+#define MAX3107_BRGDIVMSB_REG (0x1d00) /* Baud rate divisor MSB */ -+#define MAX3107_CLKSRC_REG (0x1e00) /* Clock source */ -+#define MAX3107_REVID_REG (0x1f00) /* Revision identification */ -+ -+/* IRQ register bits */ -+#define MAX3107_IRQ_LSR_BIT (1 << 0) /* LSR interrupt */ -+#define MAX3107_IRQ_SPCHR_BIT (1 << 1) /* Special char interrupt */ -+#define MAX3107_IRQ_STS_BIT (1 << 2) /* Status interrupt */ -+#define MAX3107_IRQ_RXFIFO_BIT (1 << 3) /* RX FIFO interrupt */ -+#define MAX3107_IRQ_TXFIFO_BIT (1 << 4) /* TX FIFO interrupt */ -+#define MAX3107_IRQ_TXEMPTY_BIT (1 << 5) /* TX FIFO empty interrupt */ -+#define MAX3107_IRQ_RXEMPTY_BIT (1 << 6) /* RX FIFO empty interrupt */ -+#define MAX3107_IRQ_CTS_BIT (1 << 7) /* CTS interrupt */ -+ -+/* LSR register bits */ -+#define MAX3107_LSR_RXTO_BIT (1 << 0) /* RX timeout */ -+#define MAX3107_LSR_RXOVR_BIT (1 << 1) /* RX overrun */ -+#define MAX3107_LSR_RXPAR_BIT (1 << 2) /* RX parity error */ -+#define MAX3107_LSR_FRERR_BIT (1 << 3) /* Frame error */ -+#define MAX3107_LSR_RXBRK_BIT (1 << 4) /* RX break */ -+#define MAX3107_LSR_RXNOISE_BIT (1 << 5) /* RX noise */ -+#define MAX3107_LSR_UNDEF6_BIT (1 << 6) /* Undefined/not used */ -+#define MAX3107_LSR_CTS_BIT (1 << 7) /* CTS pin state */ -+ -+/* Special character register bits */ -+#define MAX3107_SPCHR_XON1_BIT (1 << 0) /* XON1 character */ -+#define MAX3107_SPCHR_XON2_BIT (1 << 1) /* XON2 character */ -+#define MAX3107_SPCHR_XOFF1_BIT (1 << 2) /* XOFF1 character */ -+#define MAX3107_SPCHR_XOFF2_BIT (1 << 3) /* XOFF2 character */ -+#define MAX3107_SPCHR_BREAK_BIT (1 << 4) /* RX break */ -+#define MAX3107_SPCHR_MULTIDROP_BIT (1 << 5) /* 9-bit multidrop addr char */ -+#define MAX3107_SPCHR_UNDEF6_BIT (1 << 6) /* Undefined/not used */ -+#define MAX3107_SPCHR_UNDEF7_BIT (1 << 7) /* Undefined/not used */ -+ -+/* Status register bits */ -+#define MAX3107_STS_GPIO0_BIT (1 << 0) /* GPIO 0 interrupt */ -+#define MAX3107_STS_GPIO1_BIT (1 << 1) /* GPIO 1 interrupt */ -+#define MAX3107_STS_GPIO2_BIT (1 << 2) /* GPIO 2 interrupt */ -+#define MAX3107_STS_GPIO3_BIT (1 << 3) /* GPIO 3 interrupt */ -+#define MAX3107_STS_UNDEF4_BIT (1 << 4) /* Undefined/not used */ -+#define MAX3107_STS_CLKREADY_BIT (1 << 5) /* Clock ready */ -+#define MAX3107_STS_SLEEP_BIT (1 << 6) /* Sleep interrupt */ -+#define MAX3107_STS_UNDEF7_BIT (1 << 7) /* Undefined/not used */ -+ -+/* MODE1 register bits */ -+#define MAX3107_MODE1_RXDIS_BIT (1 << 0) /* RX disable */ -+#define MAX3107_MODE1_TXDIS_BIT (1 << 1) /* TX disable */ -+#define MAX3107_MODE1_TXHIZ_BIT (1 << 2) /* TX pin three-state */ -+#define MAX3107_MODE1_RTSHIZ_BIT (1 << 3) /* RTS pin three-state */ -+#define MAX3107_MODE1_TRNSCVCTRL_BIT (1 << 4) /* Transceiver ctrl enable */ -+#define MAX3107_MODE1_FORCESLEEP_BIT (1 << 5) /* Force sleep mode */ -+#define MAX3107_MODE1_AUTOSLEEP_BIT (1 << 6) /* Auto sleep enable */ -+#define MAX3107_MODE1_IRQSEL_BIT (1 << 7) /* IRQ pin enable */ -+ -+/* MODE2 register bits */ -+#define MAX3107_MODE2_RST_BIT (1 << 0) /* Chip reset */ -+#define MAX3107_MODE2_FIFORST_BIT (1 << 1) /* FIFO reset */ -+#define MAX3107_MODE2_RXTRIGINV_BIT (1 << 2) /* RX FIFO INT invert */ -+#define MAX3107_MODE2_RXEMPTINV_BIT (1 << 3) /* RX FIFO empty INT invert */ -+#define MAX3107_MODE2_SPCHR_BIT (1 << 4) /* Special chr detect enable */ -+#define MAX3107_MODE2_LOOPBACK_BIT (1 << 5) /* Internal loopback enable */ -+#define MAX3107_MODE2_MULTIDROP_BIT (1 << 6) /* 9-bit multidrop enable */ -+#define MAX3107_MODE2_ECHOSUPR_BIT (1 << 7) /* ECHO suppression enable */ -+ -+/* LCR register bits */ -+#define MAX3107_LCR_LENGTH0_BIT (1 << 0) /* Word length bit 0 */ -+#define MAX3107_LCR_LENGTH1_BIT (1 << 1) /* Word length bit 1 -+ * -+ * Word length bits table: -+ * 00 -> 5 bit words -+ * 01 -> 6 bit words -+ * 10 -> 7 bit words -+ * 11 -> 8 bit words -+ */ -+#define MAX3107_LCR_STOPLEN_BIT (1 << 2) /* STOP length bit -+ * -+ * STOP length bit table: -+ * 0 -> 1 stop bit -+ * 1 -> 1-1.5 stop bits if -+ * word length is 5, -+ * 2 stop bits otherwise -+ */ -+#define MAX3107_LCR_PARITY_BIT (1 << 3) /* Parity bit enable */ -+#define MAX3107_LCR_EVENPARITY_BIT (1 << 4) /* Even parity bit enable */ -+#define MAX3107_LCR_FORCEPARITY_BIT (1 << 5) /* 9-bit multidrop parity */ -+#define MAX3107_LCR_TXBREAK_BIT (1 << 6) /* TX break enable */ -+#define MAX3107_LCR_RTS_BIT (1 << 7) /* RTS pin control */ -+#define MAX3107_LCR_WORD_LEN_5 (0x0000) -+#define MAX3107_LCR_WORD_LEN_6 (0x0001) -+#define MAX3107_LCR_WORD_LEN_7 (0x0002) -+#define MAX3107_LCR_WORD_LEN_8 (0x0003) -+ -+ -+/* IRDA register bits */ -+#define MAX3107_IRDA_IRDAEN_BIT (1 << 0) /* IRDA mode enable */ -+#define MAX3107_IRDA_SIR_BIT (1 << 1) /* SIR mode enable */ -+#define MAX3107_IRDA_SHORTIR_BIT (1 << 2) /* Short SIR mode enable */ -+#define MAX3107_IRDA_MIR_BIT (1 << 3) /* MIR mode enable */ -+#define MAX3107_IRDA_RXINV_BIT (1 << 4) /* RX logic inversion enable */ -+#define MAX3107_IRDA_TXINV_BIT (1 << 5) /* TX logic inversion enable */ -+#define MAX3107_IRDA_UNDEF6_BIT (1 << 6) /* Undefined/not used */ -+#define MAX3107_IRDA_UNDEF7_BIT (1 << 7) /* Undefined/not used */ -+ -+/* Flow control trigger level register masks */ -+#define MAX3107_FLOWLVL_HALT_MASK (0x000f) /* Flow control halt level */ -+#define MAX3107_FLOWLVL_RES_MASK (0x00f0) /* Flow control resume level */ -+#define MAX3107_FLOWLVL_HALT(words) ((words/8) & 0x000f) -+#define MAX3107_FLOWLVL_RES(words) (((words/8) & 0x000f) << 4) -+ -+/* FIFO interrupt trigger level register masks */ -+#define MAX3107_FIFOTRIGLVL_TX_MASK (0x000f) /* TX FIFO trigger level */ -+#define MAX3107_FIFOTRIGLVL_RX_MASK (0x00f0) /* RX FIFO trigger level */ -+#define MAX3107_FIFOTRIGLVL_TX(words) ((words/8) & 0x000f) -+#define MAX3107_FIFOTRIGLVL_RX(words) (((words/8) & 0x000f) << 4) -+ -+/* Flow control register bits */ -+#define MAX3107_FLOWCTRL_AUTORTS_BIT (1 << 0) /* Auto RTS flow ctrl enable */ -+#define MAX3107_FLOWCTRL_AUTOCTS_BIT (1 << 1) /* Auto CTS flow ctrl enable */ -+#define MAX3107_FLOWCTRL_GPIADDR_BIT (1 << 2) /* Enables that GPIO inputs -+ * are used in conjunction with -+ * XOFF2 for definition of -+ * special character */ -+#define MAX3107_FLOWCTRL_SWFLOWEN_BIT (1 << 3) /* Auto SW flow ctrl enable */ -+#define MAX3107_FLOWCTRL_SWFLOW0_BIT (1 << 4) /* SWFLOW bit 0 */ -+#define MAX3107_FLOWCTRL_SWFLOW1_BIT (1 << 5) /* SWFLOW bit 1 -+ * -+ * SWFLOW bits 1 & 0 table: -+ * 00 -> no transmitter flow -+ * control -+ * 01 -> receiver compares -+ * XON2 and XOFF2 -+ * and controls -+ * transmitter -+ * 10 -> receiver compares -+ * XON1 and XOFF1 -+ * and controls -+ * transmitter -+ * 11 -> receiver compares -+ * XON1, XON2, XOFF1 and -+ * XOFF2 and controls -+ * transmitter -+ */ -+#define MAX3107_FLOWCTRL_SWFLOW2_BIT (1 << 6) /* SWFLOW bit 2 */ -+#define MAX3107_FLOWCTRL_SWFLOW3_BIT (1 << 7) /* SWFLOW bit 3 -+ * -+ * SWFLOW bits 3 & 2 table: -+ * 00 -> no received flow -+ * control -+ * 01 -> transmitter generates -+ * XON2 and XOFF2 -+ * 10 -> transmitter generates -+ * XON1 and XOFF1 -+ * 11 -> transmitter generates -+ * XON1, XON2, XOFF1 and -+ * XOFF2 -+ */ -+ -+/* GPIO configuration register bits */ -+#define MAX3107_GPIOCFG_GP0OUT_BIT (1 << 0) /* GPIO 0 output enable */ -+#define MAX3107_GPIOCFG_GP1OUT_BIT (1 << 1) /* GPIO 1 output enable */ -+#define MAX3107_GPIOCFG_GP2OUT_BIT (1 << 2) /* GPIO 2 output enable */ -+#define MAX3107_GPIOCFG_GP3OUT_BIT (1 << 3) /* GPIO 3 output enable */ -+#define MAX3107_GPIOCFG_GP0OD_BIT (1 << 4) /* GPIO 0 open-drain enable */ -+#define MAX3107_GPIOCFG_GP1OD_BIT (1 << 5) /* GPIO 1 open-drain enable */ -+#define MAX3107_GPIOCFG_GP2OD_BIT (1 << 6) /* GPIO 2 open-drain enable */ -+#define MAX3107_GPIOCFG_GP3OD_BIT (1 << 7) /* GPIO 3 open-drain enable */ -+ -+/* GPIO DATA register bits */ -+#define MAX3107_GPIODATA_GP0OUT_BIT (1 << 0) /* GPIO 0 output value */ -+#define MAX3107_GPIODATA_GP1OUT_BIT (1 << 1) /* GPIO 1 output value */ -+#define MAX3107_GPIODATA_GP2OUT_BIT (1 << 2) /* GPIO 2 output value */ -+#define MAX3107_GPIODATA_GP3OUT_BIT (1 << 3) /* GPIO 3 output value */ -+#define MAX3107_GPIODATA_GP0IN_BIT (1 << 4) /* GPIO 0 input value */ -+#define MAX3107_GPIODATA_GP1IN_BIT (1 << 5) /* GPIO 1 input value */ -+#define MAX3107_GPIODATA_GP2IN_BIT (1 << 6) /* GPIO 2 input value */ -+#define MAX3107_GPIODATA_GP3IN_BIT (1 << 7) /* GPIO 3 input value */ -+ -+/* PLL configuration register masks */ -+#define MAX3107_PLLCFG_PREDIV_MASK (0x003f) /* PLL predivision value */ -+#define MAX3107_PLLCFG_PLLFACTOR_MASK (0x00c0) /* PLL multiplication factor */ -+ -+/* Baud rate generator configuration register masks and bits */ -+#define MAX3107_BRGCFG_FRACT_MASK (0x000f) /* Fractional portion of -+ * Baud rate generator divisor -+ */ -+#define MAX3107_BRGCFG_2XMODE_BIT (1 << 4) /* Double baud rate */ -+#define MAX3107_BRGCFG_4XMODE_BIT (1 << 5) /* Quadruple baud rate */ -+#define MAX3107_BRGCFG_UNDEF6_BIT (1 << 6) /* Undefined/not used */ -+#define MAX3107_BRGCFG_UNDEF7_BIT (1 << 7) /* Undefined/not used */ -+ -+/* Clock source register bits */ -+#define MAX3107_CLKSRC_INTOSC_BIT (1 << 0) /* Internal osc enable */ -+#define MAX3107_CLKSRC_CRYST_BIT (1 << 1) /* Crystal osc enable */ -+#define MAX3107_CLKSRC_PLL_BIT (1 << 2) /* PLL enable */ -+#define MAX3107_CLKSRC_PLLBYP_BIT (1 << 3) /* PLL bypass */ -+#define MAX3107_CLKSRC_EXTCLK_BIT (1 << 4) /* External clock enable */ -+#define MAX3107_CLKSRC_UNDEF5_BIT (1 << 5) /* Undefined/not used */ -+#define MAX3107_CLKSRC_UNDEF6_BIT (1 << 6) /* Undefined/not used */ -+#define MAX3107_CLKSRC_CLK2RTS_BIT (1 << 7) /* Baud clk to RTS pin */ -+ -+ -+/* HW definitions */ -+#define MAX3107_RX_FIFO_SIZE 128 -+#define MAX3107_TX_FIFO_SIZE 128 -+#define MAX3107_REVID1 0x00a0 -+#define MAX3107_REVID2 0x00a1 -+ -+ -+/* Baud rate generator configuration values for external clock */ -+#define MAX3107_BRG_B300 (0x0A9400 | 0x05) -+#define MAX3107_BRG_B600 (0x054A00 | 0x03) -+#define MAX3107_BRG_B1200 (0x02A500 | 0x01) -+#define MAX3107_BRG_B2400 (0x015200 | 0x09) -+#define MAX3107_BRG_B4800 (0x00A900 | 0x04) -+#define MAX3107_BRG_B9600 (0x005400 | 0x0A) -+#define MAX3107_BRG_B19200 (0x002A00 | 0x05) -+#define MAX3107_BRG_B38400 (0x001500 | 0x03) -+#define MAX3107_BRG_B57600 (0x000E00 | 0x02) -+#define MAX3107_BRG_B115200 (0x000700 | 0x01) -+#define MAX3107_BRG_B230400 (0x000300 | 0x08) -+#define MAX3107_BRG_B460800 (0x000100 | 0x0c) -+#define MAX3107_BRG_B921600 (0x000100 | 0x1c) -+ -+/* Baud rate generator configuration values for internal clock */ -+#define MAX3107_BRG_IB300 (0x008000 | 0x00) -+#define MAX3107_BRG_IB600 (0x004000 | 0x00) -+#define MAX3107_BRG_IB1200 (0x002000 | 0x00) -+#define MAX3107_BRG_IB2400 (0x001000 | 0x00) -+#define MAX3107_BRG_IB4800 (0x000800 | 0x00) -+#define MAX3107_BRG_IB9600 (0x000400 | 0x00) -+#define MAX3107_BRG_IB19200 (0x000200 | 0x00) -+#define MAX3107_BRG_IB38400 (0x000100 | 0x00) -+#define MAX3107_BRG_IB57600 (0x000000 | 0x0B) -+#define MAX3107_BRG_IB115200 (0x000000 | 0x05) -+#define MAX3107_BRG_IB230400 (0x000000 | 0x03) -+#define MAX3107_BRG_IB460800 (0x000000 | 0x00) -+#define MAX3107_BRG_IB921600 (0x000000 | 0x00) -+ -+#endif /* _LINUX_SERIAL_MAX3107_H */ -Index: linux-2.6.33/include/drm/drm_mode.h -=================================================================== ---- linux-2.6.33.orig/include/drm/drm_mode.h -+++ linux-2.6.33/include/drm/drm_mode.h -@@ -160,9 +160,9 @@ struct drm_mode_get_encoder { - #define DRM_MODE_CONNECTOR_DisplayPort 10 - #define DRM_MODE_CONNECTOR_HDMIA 11 - #define DRM_MODE_CONNECTOR_HDMIB 12 --#define DRM_MODE_CONNECTOR_TV 13 -+#define DRM_MODE_CONNECTOR_TV 15 - #define DRM_MODE_CONNECTOR_eDP 14 --#define DRM_MODE_CONNECTOR_MIPI 15 -+#define DRM_MODE_CONNECTOR_MIPI 13 - - struct drm_mode_get_connector { - -Index: linux-2.6.33/drivers/spi/hh2serial.c -=================================================================== ---- linux-2.6.33.orig/drivers/spi/hh2serial.c -+++ linux-2.6.33/drivers/spi/hh2serial.c -@@ -1,7 +1,17 @@ -+/****************************************************************************** -+ -+ Copyright (c) 2009 -+ Infineon Technologies AG -+ Am Campeon 1-12; 81726 Munich, Germany -+ -+ For licensing information, see the file 'LICENSE' in the root folder of -+ this software module. -+ -+******************************************************************************/ - /* -- * HH2 SPI Serial driver -+ * HH2 SPI Serial driver Version 0.2 Beta - * -- * Copyright (C) 2009 Markus Burvall (Markus.Burvall@swedenconnectivity.com) -+ * Written by: 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 -@@ -10,15 +20,10 @@ - */ - - --#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 - -+/*#define HH2SERIAL_SHOW_ERRORS*/ - - #include <linux/kernel.h> - #include <linux/module.h> -@@ -66,6 +71,7 @@ struct hh2serial_dev { - atomic_t tty_need_read; - atomic_t spi_irq_pending; - int mthread_up; -+ int hhRxBufferBytes; - }; - - static const char driver_name[] = "hh2serial"; -@@ -89,13 +95,7 @@ static struct hh2serial_dev priv0; - #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] */ -@@ -192,9 +192,7 @@ int hh2serial_spi_get_rx_len(struct hh2s - buf_ptr = x.rx_buf; - - #ifdef HH2SERIAL_ENABLE_DEBUG -- printk(KERN_INFO "hh2serial RD:%02X, %02X\n", -- *buf_ptr, -- buf_ptr[1]); -+ printk(KERN_INFO "hh2serial RD:%02X, %02X\n", *buf_ptr, buf_ptr[1]); - #endif - - #ifndef HH2SERIAL_SPI_16BIT -@@ -203,33 +201,56 @@ int hh2serial_spi_get_rx_len(struct hh2s - ret = *buf_ptr & GPSS_TCNT; - - /* Check buffer overrun or underrun errors */ -+#ifdef HH2SERIAL_SHOW_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"); -- -+#endif -+ if (*buf_ptr & GPSS_REMPTY) -+ { -+ hh2serial->hhRxBufferBytes = HH2SERIAL_SPI_MAX_BYTES; -+#ifdef HH2SERIAL_ENABLE_DEBUG -+ printk(KERN_INFO "hh2serial HH2 rx empty!\n"); -+#endif -+ } - #else - /* 16 bit second byte is status register */ - /* Available bytes */ - ret = buf_ptr[1] & GPSS_TCNT; - - /* Check buffer overrun or underrun errors */ -+#ifdef HH2SERIAL_SHOW_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 -+ -+ if (buf_ptr[1] & GPSS_REMPTY) -+ { -+ hh2serial->hhRxBufferBytes = HH2SERIAL_SPI_MAX_BYTES; -+#ifdef HH2SERIAL_ENABLE_DEBUG -+ printk(KERN_INFO "hh2serial HH2 rx empty!\n"); -+#endif -+ } -+#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); -+ printk(KERN_INFO "hh2serial SR:%02X, rx len %d\n", buf_ptr[1], ret); - #endif - } -+ else -+ { -+#ifdef HH2SERIAL_SHOW_ERRORS -+printk(KERN_INFO "hh2serial Rd_status, spi_sync failed: %d\n",ret); -+#endif -+ ret = 0; -+ } - - kfree(local_buf); - return ret; -@@ -332,11 +353,22 @@ int hh2serial_spi_read(struct hh2serial_ - available_rd = *buf_ptr & GPSS_TCNT; - - /* Check buffer overrun or underrun errors */ -+#ifdef HH2SERIAL_SHOW_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"); -+#endif -+ -+ if (*buf_ptr & GPSS_REMPTY) -+ { -+ hh2serial->hhRxBufferBytes = HH2SERIAL_SPI_MAX_BYTES; -+#ifdef HH2SERIAL_ENABLE_DEBUG -+ printk(KERN_INFO "hh2serial HH2 rx empty!\n"); -+#endif -+ -+ } - #else - /* 16 bit second byte is status register */ - /* Every other byte is status register */ -@@ -345,6 +377,7 @@ int hh2serial_spi_read(struct hh2serial_ - available_rd = (buf_ptr[len_inc_hdr-1] & GPSS_TCNT) - 1; - - /* Check buffer overrun or underrun errors */ -+#ifdef HH2SERIAL_SHOW_ERRORS - if (buf_ptr[len_inc_hdr-1] & GPSS_TERR) - printk(KERN_INFO "hh2serial HH2 transmitter underrun!\n"); - -@@ -352,6 +385,14 @@ int hh2serial_spi_read(struct hh2serial_ - printk(KERN_INFO "hh2serial HH2 receiver overrun!\n"); - #endif - -+ if (buf_ptr[len_inc_hdr-1] & GPSS_REMPTY) -+ { -+ hh2serial->hhRxBufferBytes = HH2SERIAL_SPI_MAX_BYTES; -+#ifdef HH2SERIAL_ENABLE_DEBUG -+ printk(KERN_INFO "hh2serial HH2 rx empty!\n"); -+#endif -+ } -+#endif - - #ifdef HH2SERIAL_ENABLE_DEBUG - printk(KERN_INFO "hh2serial_spi_read len inc hdr wr:%d, avail rd %d, cs_change:%d\n", -@@ -388,6 +429,13 @@ int hh2serial_spi_read(struct hh2serial_ - #endif - - } -+ else -+ { -+#ifdef HH2SERIAL_SHOW_ERRORS -+printk(KERN_INFO "hh2serial spi_read, spi_sync failed: %d\n",status); -+#endif -+ -+ } - - kfree(local_buf); - return status; -@@ -435,8 +483,8 @@ int hh2serial_spi_write(struct hh2serial - 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); -+ /* Allocate and make room for 1 byte header(RX and TX) */ -+ local_buf = kzalloc(HH2SERIAL_BUFSIZE+2, GFP_KERNEL); - if (!local_buf) - return -ENOMEM; - -@@ -453,7 +501,6 @@ int hh2serial_spi_write(struct hh2serial - 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; -@@ -495,24 +542,55 @@ int hh2serial_spi_write(struct hh2serial - available_rd = *buf_ptr & GPSS_TCNT; - - /* Check buffer overrun or underrun errors */ -+#ifdef HH2SERIAL_SHOW_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"); -+#endif -+ if (*buf_ptr & GPSS_REMPTY) -+ { -+ /* Buffer was empty but len bytes has been written after that */ -+ hh2serial->hhRxBufferBytes = HH2SERIAL_SPI_MAX_BYTES-len; -+#ifdef HH2SERIAL_ENABLE_DEBUG -+ printk(KERN_INFO "hh2serial HH2 rx empty!\n"); -+#endif -+ } -+ else -+ { -+ hh2serial->hhRxBufferBytes -= len; -+ } - #else -+ /* FIXME_Only last status is interesting or? */ -+ /* Might have to check every status register to se if empty */ - /* 16 bit second byte is status register */ - /* Available bytes */ -- available_rd = buf_ptr[1] & GPSS_TCNT; -+ available_rd = buf_ptr[len_inc_hdr-1] & GPSS_TCNT; - - /* Check buffer overrun or underrun errors */ -- if (buf_ptr[1] & GPSS_TERR) -+#ifdef HH2SERIAL_SHOW_ERRORS -+ if (buf_ptr[len_inc_hdr-1] & GPSS_TERR) - printk(KERN_INFO "hh2serial HH2 transmitter underrun!\n"); - -- if (buf_ptr[1] & GPSS_RERR) -+ if (buf_ptr[len_inc_hdr-1] & GPSS_RERR) - printk(KERN_INFO "hh2serial HH2 receiver overrun!\n"); - #endif - -+ if (buf_ptr[len_inc_hdr-1] & GPSS_REMPTY) -+ { -+ /* Buffer was empty but one byte has been written after that */ -+ hh2serial->hhRxBufferBytes = HH2SERIAL_SPI_MAX_BYTES-1; -+#ifdef HH2SERIAL_ENABLE_DEBUG -+ printk(KERN_INFO "hh2serial HH2 rx empty!\n"); -+#endif -+ } -+ else -+ { -+ /* Only 8 bit of every 16 is data */ -+ hh2serial->hhRxBufferBytes -= (len/2); -+ } -+#endif - - #ifdef HH2SERIAL_ENABLE_DEBUG - printk(KERN_INFO "hh2serial_spi_write:%02X, %02X\n", -@@ -526,9 +604,14 @@ int hh2serial_spi_write(struct hh2serial - - *spiAvailData = available_rd; - -- - } -+ else -+ { -+#ifdef HH2SERIAL_SHOW_ERRORS -+printk(KERN_INFO "hh2serial spi_write, spi_sync failed: %d\n",status); -+#endif - -+ } - - - kfree(local_buf); -@@ -616,61 +699,77 @@ static inline void hh2serial_write_circ_ - #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++) { -+ while (left || (rxlen > 0)) { - -- obuf[i] = (u8)xmit->buf[xmit->tail]; -- -- xmit->tail = (xmit->tail + 1) & -- (UART_XMIT_SIZE - 1); -- } --#ifndef HH2SERIAL_SPI_16BIT -+ if (left) -+ { -+ /* FIXME len = MIN(left , hhRxBufferBytes) -+ if len 0 is then only read status register and read */ -+ -+ len = (left >= priv->hhRxBufferBytes) ? priv->hhRxBufferBytes : left; -+ -+ -+ if (len > 0) -+ { -+ 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 -+ -+ /* FIXME check status */ -+ hh2serial_spi_write(priv, (u8 *)obuf, -+ &rxlen, len); -+ -+ #else -+ /* len * 2 since 16 bits instead of 8 bits */ -+ /* FIXME check status */ -+ hh2serial_spi_write(priv, (u8 *)obuf, -+ &rxlen, len*2); -+ -+ #endif -+ left -= len; -+ } -+ else /* Read rx len */ -+ { -+ #ifdef HH2SERIAL_SHOW_ERRORS -+ printk(KERN_INFO "hh2serial wr buf2spi, rxBuf full?\n"); -+ #endif -+ rxlen = hh2serial_spi_get_rx_len(priv); - -- 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 (rxlen > 0) -+ { - -- if (j) -- hh2serial_write2tty(priv, valid_str, j); -- -- priv->port.icount.tx += len; -- } -+ 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 -@@ -793,7 +892,7 @@ static int hh2serial_main_thread(void *_ - /* Read from tty send to spi */ - #ifdef HH2SERIAL_ENABLE_DEBUG - printk(KERN_INFO "hh2serial: Read from tty send to spi\n"); --#endif -+#endif - /* Read from tty send to spi */ - /* Receive data from spi send to UART */ - -@@ -1153,11 +1252,13 @@ static int hh2serial_startup(struct uart - struct hh2serial_dev *priv = container_of(port, struct hh2serial_dev, port); - FUNC_ENTER(); - -+ /* Initialize RxBuffer to 0 */ -+ priv->hhRxBufferBytes = 0; - #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", -+ printk(KERN_INFO "hh2serial Failed to start poll thread: %ld", - PTR_ERR(priv->poll_thread)); - } - #endif |