Permalink
Switch branches/tags
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
122 lines (107 sloc) 3.55 KB
From 07118aa84d167a2bdb38f2d896a34cb03c7937e9 Mon Sep 17 00:00:00 2001
From: Florent Revest <revestflo@gmail.com>
Date: Tue, 14 Feb 2017 16:53:03 +0100
Subject: [PATCH] bluesleep: Use kernel's HCI events instead of
/proc/bluetooth/sleep/ write to interface with BlueZ instead of Bluedroid
---
drivers/bluetooth/bluesleep.c | 31 +++++++++++++++++++++++++++++++
drivers/bluetooth/hci_ldisc.c | 4 ++++
include/net/bluetooth/hci.h | 1 +
net/bluetooth/hci_sock.c | 4 ++++
4 files changed, 40 insertions(+)
diff --git a/drivers/bluetooth/bluesleep.c b/drivers/bluetooth/bluesleep.c
index d6750ff43270..c64ef06d1b04 100644
--- a/drivers/bluetooth/bluesleep.c
+++ b/drivers/bluetooth/bluesleep.c
@@ -54,6 +54,7 @@
#include <linux/platform_data/msm_serial_hs.h>
#include <net/bluetooth/bluetooth.h>
+#include <net/bluetooth/hci_core.h> /* event notifications */
#define BT_SLEEP_DBG
#ifndef BT_SLEEP_DBG
@@ -513,6 +514,36 @@ static void bluesleep_stop(void)
wake_lock_timeout(&bsi->wake_lock, HZ / 8);
}
+/**
+ * Handles HCI device events.
+ * @param this Not used.
+ * @param event The event that occurred.
+ * @param data The HCI device associated with the event.
+ * @return <code>NOTIFY_DONE</code>.
+ */
+void bluesleep_hci_event(unsigned long event)
+{
+ switch (event) {
+ case HCI_DEV_REG:
+ has_lpm_enabled = true;
+ bsi->uport = msm_hs_get_uart_port(BT_PORT_ID);
+ /* if bluetooth started, start bluesleep*/
+ bluesleep_start();
+ break;
+ case HCI_DEV_UNREG:
+ bluesleep_stop();
+ /* flush pending works */
+ flush_delayed_work(&uart_awake_wq);
+ has_lpm_enabled = false;
+ bsi->uport = NULL;
+ /* if bluetooth stopped, stop bluesleep also */
+ break;
+ case HCI_DEV_WRITE:
+ bluesleep_outgoing_data();
+ break;
+ }
+}
+
static int bluesleep_write_proc_btwrite(struct file *file,
const char __user * buffer,
size_t count, loff_t * ppos)
diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c
index 5c9a73f02664..f21432799e0f 100644
--- a/drivers/bluetooth/hci_ldisc.c
+++ b/drivers/bluetooth/hci_ldisc.c
@@ -248,6 +248,8 @@ static int hci_uart_close(struct hci_dev *hdev)
return 0;
}
+void bluesleep_hci_event(unsigned long event);
+
/* Send frames from HCI layer */
static int hci_uart_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
{
@@ -258,6 +260,8 @@ static int hci_uart_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
BT_DBG("%s: type %d len %d", hdev->name, bt_cb(skb)->pkt_type, skb->len);
+ bluesleep_hci_event(HCI_DEV_WRITE);
+
hu->proto->enqueue(hu, skb);
hci_uart_tx_wakeup(hu);
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index d95da83cb1b0..54be456bcc9c 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -44,6 +44,7 @@
#define HCI_DEV_DOWN 4
#define HCI_DEV_SUSPEND 5
#define HCI_DEV_RESUME 6
+#define HCI_DEV_WRITE 7
/* HCI notify events */
#define HCI_NOTIFY_CONN_ADD 1
diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c
index a5cf13bf289d..c5b77df9eb52 100644
--- a/net/bluetooth/hci_sock.c
+++ b/net/bluetooth/hci_sock.c
@@ -152,6 +152,8 @@ static bool is_filtered_packet(struct sock *sk, struct sk_buff *skb)
return false;
}
+void bluesleep_hci_event(unsigned long event);
+
/* Send frame to RAW socket */
void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb)
{
@@ -394,6 +396,8 @@ void hci_sock_dev_event(struct hci_dev *hdev, int event)
{
struct hci_ev_si_device ev;
+ bluesleep_hci_event(event);
+
BT_DBG("hdev %s event %d", hdev->name, event);
/* Send event to monitor */
--
2.11.0