From 3c1bbedc12aa43525964db5801ac5a6967596b05 Mon Sep 17 00:00:00 2001 From: Franz-Josef Haider Date: Wed, 20 Sep 2017 10:22:00 +0200 Subject: [PATCH] (hybris)[f5121] Use bluesleep with bluetooth driver. JB#39272 Signed-off-by: Matti Kosola --- drivers/bluetooth/bcm43xx.c | 36 +++++++++++++++++++++++++----- drivers/bluetooth/bcm43xx.h | 29 ++++++++++++++++++++++++ drivers/bluetooth/bluesleep.c | 6 ++++- drivers/bluetooth/hci_ldisc.c | 15 +++++++++++++ drivers/tty/serial/msm_serial_hs.c | 15 +++++++++++++ 5 files changed, 94 insertions(+), 7 deletions(-) create mode 100644 drivers/bluetooth/bcm43xx.h diff --git a/drivers/bluetooth/bcm43xx.c b/drivers/bluetooth/bcm43xx.c index 3c6d1d05b3bde..8d02d5e094606 100644 --- a/drivers/bluetooth/bcm43xx.c +++ b/drivers/bluetooth/bcm43xx.c @@ -27,6 +27,8 @@ #include #include #include +#include +#include #ifdef CONFIG_BT_MSM_SLEEP #include #endif @@ -45,7 +47,25 @@ struct bcm43xx_data { static struct bcm43xx_data *bcm43xx_my_data; static struct rfkill *bt_rfkill; -static bool bt_enabled; +static DEFINE_RWLOCK(bcm43xx_lock); + +bool bcm43xx_may_use_bluesleep(void) +{ + read_lock(&bcm43xx_lock); + + if(!gpio_get_value(bcm43xx_my_data->reg_on_gpio)) { + read_unlock(&bcm43xx_lock); + pr_info("bluesleep may not be used"); + return false; + } + + return true; +} + +void bcm43xx_done_accessing_bluesleep(void) +{ + read_unlock(&bcm43xx_lock); +} static int bcm43xx_bt_rfkill_set_power(void *data, bool blocked) { @@ -62,10 +82,12 @@ static int bcm43xx_bt_rfkill_set_power(void *data, bool blocked) regOnGpio); return 0; } + write_lock(&bcm43xx_lock); gpio_set_value(bcm43xx_my_data->reg_on_gpio, 1); + write_unlock(&bcm43xx_lock); -#if defined(CONFIG_BT_MSM_SLEEP) && !defined(CONFIG_LINE_DISCIPLINE_DRIVER) - bluesleep_start(1); +#if defined(CONFIG_BT_MSM_SLEEP) + bluesleep_start(0); #endif } else { if (!regOnGpio) { @@ -73,13 +95,14 @@ static int bcm43xx_bt_rfkill_set_power(void *data, bool blocked) regOnGpio); return 0; } + write_lock(&bcm43xx_lock); gpio_set_value(bcm43xx_my_data->reg_on_gpio, 0); + write_unlock(&bcm43xx_lock); -#if defined(CONFIG_BT_MSM_SLEEP) && !defined(CONFIG_LINE_DISCIPLINE_DRIVER) +#if defined(CONFIG_BT_MSM_SLEEP) bluesleep_stop(); #endif } - bt_enabled = !blocked; return 0; } @@ -156,6 +179,8 @@ static int bcm43xx_bluetooth_probe(struct platform_device *pdev) struct device_node *of_node = pdev->dev.of_node; dev_dbg(&pdev->dev, "bcm43xx bluetooth driver being loaded\n"); + rwlock_init(&bcm43xx_lock); + if (!of_node) { dev_err(&pdev->dev, "%s(): of_node is null\n", __func__); ret = -EPERM; @@ -245,7 +270,6 @@ static struct platform_driver bcm43xx_bluetooth_platform_driver = { static int __init bcm43xx_bluetooth_init(void) { - bt_enabled = false; return platform_driver_register(&bcm43xx_bluetooth_platform_driver); } diff --git a/drivers/bluetooth/bcm43xx.h b/drivers/bluetooth/bcm43xx.h new file mode 100644 index 0000000000000..02a86228fbef5 --- /dev/null +++ b/drivers/bluetooth/bcm43xx.h @@ -0,0 +1,29 @@ +/* + * Bluetooth Broadcomm access policy + * + * Copyright (C) 2017 Jolla Oy + * + * 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 + * + */ + +#ifndef _BCM43XX_H +#define _BCM43XX_H + +bool bcm43xx_may_use_bluesleep(void); +void bcm43xx_done_accessing_bluesleep(void); + +#endif + diff --git a/drivers/bluetooth/bluesleep.c b/drivers/bluetooth/bluesleep.c index e02f760e41c44..e30951e91073c 100644 --- a/drivers/bluetooth/bluesleep.c +++ b/drivers/bluetooth/bluesleep.c @@ -80,7 +80,8 @@ #define HS_UART_OFF 0 #define BT_PORT_ID 0 -#define BT_BLUEDROID_SUPPORT 1 +/* this define currently has no effect */ +#define BT_BLUEDROID_SUPPORT 0 enum { DEBUG_USER_STATE = 1U << 0, DEBUG_SUSPEND = 1U << 1, @@ -670,6 +671,9 @@ static int bluesleep_probe(struct platform_device *pdev) bsi->uport = msm_hs_get_uart_port(BT_PORT_ID); + /* otherwise we get an unbalanced irq enable */ + /* when bluetooth is enabled for the first time. */ + disable_irq(bsi->host_wake_irq); atomic_set(&bsi->wakeup_irq_disabled, 1); return 0; diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c index c5975ca87ec14..2bfe95bbed0dc 100644 --- a/drivers/bluetooth/hci_ldisc.c +++ b/drivers/bluetooth/hci_ldisc.c @@ -44,6 +44,9 @@ #include #include +#include + +#include "bcm43xx.h" #include "hci_uart.h" #define VERSION "2.2" @@ -147,8 +150,20 @@ static void hci_uart_write_work(struct work_struct *work) while ((skb = hci_uart_dequeue(hu))) { int len; + if(!bcm43xx_may_use_bluesleep()) { + /* device has been shutdown */ + clear_bit(HCI_UART_SENDING, &hu->tx_state); + return; + } + set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); + + bluesleep_outgoing_data(); + len = tty->ops->write(tty, skb->data, skb->len); + + bcm43xx_done_accessing_bluesleep(); + hdev->stat.byte_tx += len; skb_pull(skb, len); diff --git a/drivers/tty/serial/msm_serial_hs.c b/drivers/tty/serial/msm_serial_hs.c index ec839aa8edade..6fbbf9544f1d9 100644 --- a/drivers/tty/serial/msm_serial_hs.c +++ b/drivers/tty/serial/msm_serial_hs.c @@ -69,6 +69,7 @@ #ifdef CONFIG_BT_MSM_SLEEP #include +#include <../drivers/bluetooth/bcm43xx.h> #endif #include "msm_serial_hs_hwreg.h" @@ -309,6 +310,11 @@ static int msm_hs_ioctl(struct uart_port *uport, unsigned int cmd, if (!msm_uport) return -ENODEV; + if(!bcm43xx_may_use_bluesleep()) { + /* the device has been rfkill-ed */ + return -ENODEV; + } + switch (cmd) { case MSM_ENABLE_UART_CLOCK: { ret = msm_hs_request_clock_on(&msm_uport->uport); @@ -343,6 +349,8 @@ static int msm_hs_ioctl(struct uart_port *uport, unsigned int cmd, } } + bcm43xx_done_accessing_bluesleep(); + return ret; } @@ -1445,7 +1453,14 @@ static void msm_hs_submit_tx_locked(struct uart_port *uport) /* Notify the bluesleep driver of outgoing data, if available. */ #if defined(CONFIG_BT_MSM_SLEEP) && !defined(CONFIG_LINE_DISCIPLINE_DRIVER) + if(!bcm43xx_may_use_bluesleep()) { + /* device has been shutdown */ + return; + } + bluesleep_outgoing_data(); + + bcm43xx_done_accessing_bluesleep(); #endif MSM_HS_DBG("%s:Enqueue Tx Cmd, ret %d\n", __func__, ret);