diff options
-rw-r--r-- | arch/arm/configs/msm8916-qrd_defconfig | 18 | ||||
-rw-r--r-- | drivers/tty/serial/msm_smd_tty.c | 89 |
2 files changed, 90 insertions, 17 deletions
diff --git a/arch/arm/configs/msm8916-qrd_defconfig b/arch/arm/configs/msm8916-qrd_defconfig index 8126e7338aec..43895850488b 100644 --- a/arch/arm/configs/msm8916-qrd_defconfig +++ b/arch/arm/configs/msm8916-qrd_defconfig @@ -68,6 +68,16 @@ CONFIG_INET_ESP=y # CONFIG_INET_XFRM_MODE_BEET is not set # CONFIG_INET_LRO is not set CONFIG_IPV6=y +CONFIG_BT=y +CONFIG_BT_RFCOMM=y +CONFIG_BT_RFCOMM_TTY=y +CONFIG_BT_BNEP=y +CONFIG_BT_BNEP_MC_FILTER=y +CONFIG_BT_BNEP_PROTO_FILTER=y +CONFIG_BT_HIDP=y +CONFIG_BT_HCIUART=y +CONFIG_BT_HCIUART_H4=y +CONFIG_BT_HCIUART_BCSP=y CONFIG_CFG80211=y CONFIG_NL80211_TESTMODE=y CONFIG_CFG80211_INTERNAL_REGDB=y @@ -96,15 +106,18 @@ CONFIG_DM_CRYPT=y CONFIG_NETDEVICES=y CONFIG_DUMMY=y # CONFIG_USB_NET_DRIVERS is not set -CONFIG_WCNSS_CORE=m -CONFIG_WCNSS_CORE_PRONTO=m CONFIG_ATH_CARDS=y CONFIG_ATH_DEBUG=y CONFIG_WCN36XX=m CONFIG_WCN36XX_DEBUGFS=y # CONFIG_RTL_CARDS is not set +CONFIG_INPUT_EVDEV=y +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_INPUT_MISC=y +CONFIG_INPUT_UINPUT=y CONFIG_SERIAL_MSM=y CONFIG_SERIAL_MSM_CONSOLE=y +CONFIG_SERIAL_MSM_SMD=y CONFIG_HW_RANDOM=y CONFIG_MSM_SMD_PKT=y CONFIG_SPMI=y @@ -124,6 +137,7 @@ CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y CONFIG_LOGO=y # CONFIG_LOGO_LINUX_MONO is not set # CONFIG_LOGO_LINUX_VGA16 is not set +CONFIG_HIDRAW=y # CONFIG_USB_HID is not set CONFIG_USB=y CONFIG_USB_OTG=y diff --git a/drivers/tty/serial/msm_smd_tty.c b/drivers/tty/serial/msm_smd_tty.c index 740e34c5024b..98b7dbe68f66 100644 --- a/drivers/tty/serial/msm_smd_tty.c +++ b/drivers/tty/serial/msm_smd_tty.c @@ -110,6 +110,8 @@ struct smd_tty_info { char ch_name[SMD_MAX_CH_NAME_LEN]; char dev_name[SMD_MAX_CH_NAME_LEN]; + bool swallow_first_tx_byte; + struct mutex open_lock_lha1; unsigned int open_wait; @@ -265,9 +267,16 @@ static void smd_tty_read(unsigned long param) unsigned char *ptr; int avail; struct smd_tty_info *info = (struct smd_tty_info *)param; - struct tty_struct *tty = tty_port_tty_get(&info->port); + struct smd_tty_info *info_smd = info; + + struct tty_struct *tty; unsigned long flags; + if (info == &smd_tty[2]) + info = &smd_tty[3]; + + tty = tty_port_tty_get(&info->port); + if (!tty) return; @@ -282,12 +291,14 @@ static void smd_tty_read(unsigned long param) if (test_bit(TTY_THROTTLED, &tty->flags)) break; spin_lock_irqsave(&info->ra_lock_lha3, flags); - avail = smd_read_avail(info->ch); + avail = smd_read_avail(info_smd->ch); if (avail == 0) { __pm_relax(&info->ra_wakeup_source); spin_unlock_irqrestore(&info->ra_lock_lha3, flags); break; } + if (info->swallow_first_tx_byte) + avail++; spin_unlock_irqrestore(&info->ra_lock_lha3, flags); if (avail > MAX_TTY_BUF_SIZE) @@ -300,16 +311,30 @@ static void smd_tty_read(unsigned long param) tty_kref_put(tty); return; } - - if (smd_read(info->ch, ptr, avail) != avail) { - /* shouldn't be possible since we're in interrupt - ** context here and nobody else could 'steal' our - ** characters. - */ - SMD_TTY_ERR( - "%s - Possible smd_tty_buffer mismatch for %s", - __func__, info->ch_name); - } + if (info->swallow_first_tx_byte) { + if (info == info_smd) + *ptr = 4; /* HCI EVENT */ + else + *ptr = 2; /* ACL */ + if (smd_read(info_smd->ch, ptr + 1, avail - 1) != avail - 1) { + /* shouldn't be possible since we're in interrupt + ** context here and nobody else could 'steal' our + ** characters. + */ + SMD_TTY_ERR( + "%s - Possible smd_tty_buffer mismatch for %s", + __func__, info->ch_name); + } + } else + if (smd_read(info_smd->ch, ptr, avail) != avail) { + /* shouldn't be possible since we're in interrupt + ** context here and nobody else could 'steal' our + ** characters. + */ + SMD_TTY_ERR( + "%s - Possible smd_tty_buffer mismatch for %s", + __func__, info->ch_name); + } /* * Keep system awake long enough to allow the TTY @@ -635,6 +660,22 @@ static int smd_tty_port_activate(struct tty_port *tport, goto release_wl_tl; } + if (info->swallow_first_tx_byte) { + tasklet_init(&smd_tty[2].tty_tsklt, smd_tty_read, (unsigned long)&smd_tty[2]); + + res = smd_named_open_on_edge("APPS_RIVA_BT_ACL", + SMD_APPS_WCNSS, &smd_tty[2].ch, &smd_tty[2], + smd_tty_notify); + + if (res < 0) { + SMD_TTY_INFO("%s: %s open failed %d\n", + __func__, info->ch_name, res); + goto release_wl_tl; + } + + + } + res = wait_event_interruptible_timeout(info->ch_opened_wait_queue, info->is_open, (2 * HZ)); if (res == 0) @@ -647,6 +688,8 @@ static int smd_tty_port_activate(struct tty_port *tport, SMD_TTY_INFO("%s with PID %u opened port %s", current->comm, current->pid, info->ch_name); smd_disable_read_intr(info->ch); + smd_disable_read_intr(smd_tty[2].ch); + mutex_unlock(&info->open_lock_lha1); return 0; @@ -701,6 +744,10 @@ static void smd_tty_port_shutdown(struct tty_port *tport) smd_close(info->ch); info->ch = NULL; + + if (info->swallow_first_tx_byte) + smd_close(smd_tty[2].ch); + subsystem_put(info->pil); smd_tty_remove_driver(info); @@ -727,6 +774,10 @@ static int smd_tty_write(struct tty_struct *tty, const unsigned char *buf, { struct smd_tty_info *info = tty->driver_data; int avail; + smd_channel_t *ch = info->ch; + + if (info->swallow_first_tx_byte && *buf != 1) + ch = smd_tty[2].ch; /* if we're writing to a packet channel we will ** never be able to write more data than there @@ -735,12 +786,12 @@ static int smd_tty_write(struct tty_struct *tty, const unsigned char *buf, if (is_in_reset(info)) return -ENETRESET; - avail = smd_write_avail(info->ch); + avail = smd_write_avail(ch); /* if no space, we'll have to setup a notification later to wake up the * tty framework when space becomes avaliable */ if (!avail) { - smd_enable_read_intr(info->ch); + smd_enable_read_intr(ch); return 0; } if (len > avail) @@ -748,7 +799,13 @@ static int smd_tty_write(struct tty_struct *tty, const unsigned char *buf, SMD_TTY_INFO("[WRITE]: PID %u -> port %s %x bytes", current->pid, info->ch_name, len); - return smd_write(info->ch, buf, len); + if (info->swallow_first_tx_byte) { + if (len < 2) + return 0; + return smd_write(ch, buf + 1, len - 1) + 1; + } + + return smd_write(ch, buf, len); } static int smd_tty_write_room(struct tty_struct *tty) @@ -913,6 +970,7 @@ static void smd_tty_device_init(int idx) port = &smd_tty[idx].port; tty_port_init(port); port->ops = &smd_tty_port_ops; + smd_tty[idx].swallow_first_tx_byte = idx == 3; smd_tty[idx].device_ptr = tty_port_register_device(port, smd_tty_driver, idx, NULL); init_completion(&smd_tty[idx].ch_allocated); @@ -946,6 +1004,7 @@ static int smd_tty_core_init(void) for (n = 0; n < ARRAY_SIZE(smd_configs); ++n) { idx = smd_configs[n].tty_dev_index; smd_tty[idx].edge = smd_configs[n].edge; + smd_tty[idx].swallow_first_tx_byte = idx == 3; strlcpy(smd_tty[idx].ch_name, smd_configs[n].port_name, SMD_MAX_CH_NAME_LEN); |