• Hans de Goede's avatar
    power: supply: bq27xxx: Fix bq27xxx_battery_update() race condition · 5c34c0ae
    Hans de Goede authored
    bq27xxx_battery_update() assumes / requires that it is only run once,
    not multiple times at the same time. But there are 3 possible callers:
    
    1. bq27xxx_battery_poll() delayed_work item handler
    2. bq27xxx_battery_irq_handler_thread() I2C IRQ handler
    3. bq27xxx_battery_setup()
    
    And there is no protection against these racing with each other,
    fix this race condition by making all callers take di->lock:
    
    - Rename bq27xxx_battery_update() to bq27xxx_battery_update_unlocked()
    
    - Add new bq27xxx_battery_update() which takes di->lock and then calls
      bq27xxx_battery_update_unlocked()
    
    - Make stale cache check code in bq27xxx_battery_get_property(), which
      already takes di->lock directly to check the jiffies, call
      bq27xxx_battery_update_unlocked() instead of messing with
      the delayed_work item
    
    - Make bq27xxx_battery_update_unlocked() mod the delayed-work item
      so that the next poll is delayed to poll_interval milliseconds after
      the last update independent of the source of the update
    
    Fixes: 740b755a ("bq27x00: Poll battery state")
    Signed-off-by: default avatarHans de Goede <hdegoede@redhat.com>
    Signed-off-by: default avatarSebastian Reichel <sebastian.reichel@collabora.com>
    5c34c0ae
bq27xxx_battery.c 60.4 KB