bluetooth: Reset BT stack when wcnss chip resets

Deregister and re-register the smd transport device on wcnss reset.

Change-Id: I5c61e6a6e0a97d300f92f2ba0c1a87bd6dc22c87
Signed-off-by: Sunny Kapdi <sunnyk@codeaurora.org>
This commit is contained in:
Sunny Kapdi
2012-02-01 13:52:27 -08:00
parent 71db8dfe5b
commit 02eab14842

View File

@@ -25,6 +25,7 @@
#include <linux/string.h> #include <linux/string.h>
#include <linux/skbuff.h> #include <linux/skbuff.h>
#include <linux/wakelock.h> #include <linux/wakelock.h>
#include <linux/workqueue.h>
#include <linux/uaccess.h> #include <linux/uaccess.h>
#include <net/bluetooth/bluetooth.h> #include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h> #include <net/bluetooth/hci_core.h>
@@ -47,6 +48,7 @@ static DEFINE_MUTEX(hci_smd_enable);
static int hcismd_set_enable(const char *val, struct kernel_param *kp); static int hcismd_set_enable(const char *val, struct kernel_param *kp);
module_param_call(hcismd_set, hcismd_set_enable, NULL, &hcismd_set, 0644); module_param_call(hcismd_set, hcismd_set_enable, NULL, &hcismd_set, 0644);
static void hci_dev_restart(struct work_struct *worker);
struct hci_smd_data { struct hci_smd_data {
struct hci_dev *hdev; struct hci_dev *hdev;
@@ -312,6 +314,7 @@ static void hci_smd_notify_event(void *data, unsigned int event)
{ {
struct hci_dev *hdev = hs.hdev; struct hci_dev *hdev = hs.hdev;
struct hci_smd_data *hsmd = &hs; struct hci_smd_data *hsmd = &hs;
struct work_struct *reset_worker;
int len = 0; int len = 0;
if (!hdev) { if (!hdev) {
@@ -335,6 +338,13 @@ static void hci_smd_notify_event(void *data, unsigned int event)
case SMD_EVENT_CLOSE: case SMD_EVENT_CLOSE:
BT_INFO("Closing HCI-SMD channel :%s", EVENT_CHANNEL); BT_INFO("Closing HCI-SMD channel :%s", EVENT_CHANNEL);
hci_smd_close(hdev); hci_smd_close(hdev);
reset_worker = kzalloc(sizeof(*reset_worker), GFP_ATOMIC);
if (!reset_worker) {
BT_ERR("Out of memory");
break;
}
INIT_WORK(reset_worker, hci_dev_restart);
schedule_work(reset_worker);
break; break;
default: default:
break; break;
@@ -464,6 +474,15 @@ static void hci_smd_deregister_dev(struct hci_smd_data *hsmd)
} }
} }
static void hci_dev_restart(struct work_struct *worker)
{
mutex_lock(&hci_smd_enable);
hci_smd_deregister_dev(&hs);
hci_smd_register_dev(&hs);
mutex_unlock(&hci_smd_enable);
kfree(worker);
}
static int hcismd_set_enable(const char *val, struct kernel_param *kp) static int hcismd_set_enable(const char *val, struct kernel_param *kp)
{ {
int ret = 0; int ret = 0;