Skip to content

Commit

Permalink
extcon: Fix extcon_cable_get_state() from getting old state after not…
Browse files Browse the repository at this point in the history
…ification

Currently the extcon code notifiers the interested listeners
before it updates the extcon state with the new state.
This will cause the listeners that use extcon_cable_get_state()
to get the stale state and loose the new state.

Fix this by first changing the extcon state variable and then
notifying listeners.

Signed-off-by: Roger Quadros <rogerq@ti.com>
Tested-by: Ivan T. Ivanov <ivan.ivanov@linaro.org>
Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
  • Loading branch information
Roger Quadros authored and Chanwoo Choi committed Jul 31, 2015
1 parent be052cc commit f7a8981
Showing 1 changed file with 10 additions and 5 deletions.
15 changes: 10 additions & 5 deletions drivers/extcon/extcon.c
Original file line number Diff line number Diff line change
Expand Up @@ -275,20 +275,25 @@ int extcon_update_state(struct extcon_dev *edev, u32 mask, u32 state)
spin_lock_irqsave(&edev->lock, flags);

if (edev->state != ((edev->state & ~mask) | (state & mask))) {
u32 old_state;

if (check_mutually_exclusive(edev, (edev->state & ~mask) |
(state & mask))) {
spin_unlock_irqrestore(&edev->lock, flags);
return -EPERM;
}

for (index = 0; index < edev->max_supported; index++) {
if (is_extcon_changed(edev->state, state, index, &attached))
raw_notifier_call_chain(&edev->nh[index], attached, edev);
}

old_state = edev->state;
edev->state &= ~mask;
edev->state |= state & mask;

for (index = 0; index < edev->max_supported; index++) {
if (is_extcon_changed(old_state, edev->state, index,
&attached))
raw_notifier_call_chain(&edev->nh[index],
attached, edev);
}

/* This could be in interrupt handler */
prop_buf = (char *)get_zeroed_page(GFP_ATOMIC);
if (prop_buf) {
Expand Down

0 comments on commit f7a8981

Please sign in to comment.