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:
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user