summaryrefslogtreecommitdiff
path: root/drivers/extcon
diff options
context:
space:
mode:
authorChanwoo Choi <cw00.choi@samsung.com>2018-06-14 11:16:29 +0900
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2018-09-09 19:55:56 +0200
commitc0a8e047734ce3dcce51715108ff666829fa539e (patch)
tree11032923e85c38720899894657c80abe456f1a6e /drivers/extcon
parent3f9481902f0b65292addc62771e2c6f59149044d (diff)
extcon: Release locking when sending the notification of connector state
commit 8a9dbb779fe882325b9a0238494a7afaff2eb444 upstream. Previously, extcon used the spinlock before calling the notifier_call_chain to prevent the scheduled out of task and to prevent the notification delay. When spinlock is locked for sending the notification, deadlock issue occured on the side of extcon consumer device. To fix this issue, extcon consumer device should always use the work. it is always not reasonable to use work. To fix this issue on extcon consumer device, release locking when sending the notification of connector state. Fixes: ab11af049f88 ("extcon: Add the synchronization extcon APIs to support the notification") Cc: stable@vger.kernel.org Cc: Roger Quadros <rogerq@ti.com> Cc: Kishon Vijay Abraham I <kishon@ti.com> Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/extcon')
-rw-r--r--drivers/extcon/extcon.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/drivers/extcon/extcon.c b/drivers/extcon/extcon.c
index 35e9fb885486..95e96f04bf6f 100644
--- a/drivers/extcon/extcon.c
+++ b/drivers/extcon/extcon.c
@@ -433,8 +433,8 @@ int extcon_sync(struct extcon_dev *edev, unsigned int id)
return index;
spin_lock_irqsave(&edev->lock, flags);
-
state = !!(edev->state & BIT(index));
+ spin_unlock_irqrestore(&edev->lock, flags);
/*
* Call functions in a raw notifier chain for the specific one
@@ -448,6 +448,7 @@ int extcon_sync(struct extcon_dev *edev, unsigned int id)
*/
raw_notifier_call_chain(&edev->nh_all, state, edev);
+ spin_lock_irqsave(&edev->lock, flags);
/* This could be in interrupt handler */
prop_buf = (char *)get_zeroed_page(GFP_ATOMIC);
if (!prop_buf) {