From eb5fa3022b9bffdc91f919bb64faa682d8bec5d7 Mon Sep 17 00:00:00 2001 From: zhihui wu Date: Thu, 20 Aug 2015 14:33:54 -0700 Subject: [PATCH] angler: bluetooth: Fix kernel panic(PC is at msm_serial_hs_rx_work). The issue happens in a rare condication that bluesleep try to enable uart clock to trigger high speed uart to receive data when high speed uart has already been shutdown.Since high speed uart has been shutdown, tty port has already been released too. So this will cause NULL pointer (tty) in msm_serial_hs_rx_work. The patch ensures the port is valid when trying to enable uart clock. So high speed uart will not receive data after uart port has shutdown. Kernel panic: [ 291.755022] Unable to handle kernel NULL pointer dereference at virtual address 00000318 [ 291.762082] pgd = ffffffc00007d000 [ 291.341551] core_set_license: Invalid cal block to send [ 291.765466] [00000318] *pgd=000000001021c003 [ 291.769718] , *pmd=000000001021d003, *pte=00e00000f9000407 [ 291.769735] Internal error: Oops: 96000005 [#1] PREEMPT SMP [ 291.775275] Modules linked in: [ 291.778319] CPU: 3 PID: 190 Comm: msm_serial_hs_0 Tainted: G W 3.10.49-gcd59634 #37 [ 291.786822] task: ffffffc0b71db100 ti: ffffffc0b6e1c000 task.ti: ffffffc0b6e1c000 [ 291.794295] PC is at msm_serial_hs_rx_work+0x530/0x744 [ 291.799409] LR is at msm_serial_hs_rx_work+0x458/0x744 [ 291.804529] pc : [] lr : [] pstate: 600001c5 BUG=22979844 Signed-off-by: ping wang Change-Id: I853bc5efa9e9a6d9eb03c3f4aec2c20032b96839 Signed-off-by: Francisco Franco --- drivers/bluetooth/bluesleep.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/bluetooth/bluesleep.c b/drivers/bluetooth/bluesleep.c index 3c1e98e71359..a5546c38cb28 100644 --- a/drivers/bluetooth/bluesleep.c +++ b/drivers/bluetooth/bluesleep.c @@ -170,8 +170,12 @@ static void hsuart_power(int on) if (test_bit(BT_SUSPEND, &flags)) return; if (on) { - msm_hs_request_clock_on(bsi->uport); - msm_hs_set_mctrl(bsi->uport, TIOCM_RTS); + // make sure port is active before enable it. + if(bsi->uport->state->port.count) + { + msm_hs_request_clock_on(bsi->uport); + msm_hs_set_mctrl(bsi->uport, TIOCM_RTS); + } } else { msm_hs_set_mctrl(bsi->uport, 0); msm_hs_request_clock_off(bsi->uport);