mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2025-12-27 18:25:05 +00:00
pi2usb9281: Prevent race condition in RMW control register
Added unlocked versions of register access, modified RMW functions to use unlocked versions and made them locked themselves. BRANCH=master BUG=chrome-os-partner:49182 TEST=DUT boots successfully Change-Id: Ifd16abc349cc731aeed78b12989595214e65cea2 Signed-off-by: Victor Prupis <vprupis@google.com> Reviewed-on: https://chromium-review.googlesource.com/377151 Commit-Ready: Shawn N <shawnn@chromium.org> Reviewed-by: Shawn N <shawnn@chromium.org>
This commit is contained in:
committed by
chrome-bot
parent
1ae3ffc608
commit
62bb88c730
@@ -61,14 +61,18 @@ static void unselect_chip(int port)
|
||||
mutex_unlock(chip->mux_lock);
|
||||
}
|
||||
|
||||
static uint8_t pi3usb9281_read(int port, uint8_t reg)
|
||||
static uint8_t pi3usb9281_do_read(int port, uint8_t reg, int with_lock)
|
||||
{
|
||||
struct pi3usb9281_config *chip = &pi3usb9281_chips[port];
|
||||
int res, val;
|
||||
|
||||
select_chip(port);
|
||||
if (with_lock)
|
||||
select_chip(port);
|
||||
|
||||
res = i2c_read8(chip->i2c_port, PI3USB9281_I2C_ADDR, reg, &val);
|
||||
unselect_chip(port);
|
||||
|
||||
if (with_lock)
|
||||
unselect_chip(port);
|
||||
|
||||
if (res)
|
||||
return 0xee;
|
||||
@@ -76,26 +80,56 @@ static uint8_t pi3usb9281_read(int port, uint8_t reg)
|
||||
return val;
|
||||
}
|
||||
|
||||
static int pi3usb9281_write(int port, uint8_t reg, uint8_t val)
|
||||
static uint8_t pi3usb9281_read_u(int port, uint8_t reg)
|
||||
{
|
||||
return pi3usb9281_do_read(port, reg, 0);
|
||||
}
|
||||
|
||||
static uint8_t pi3usb9281_read(int port, uint8_t reg)
|
||||
{
|
||||
return pi3usb9281_do_read(port, reg, 1);
|
||||
}
|
||||
|
||||
static int pi3usb9281_do_write(
|
||||
int port, uint8_t reg, uint8_t val, int with_lock)
|
||||
{
|
||||
struct pi3usb9281_config *chip = &pi3usb9281_chips[port];
|
||||
int res;
|
||||
|
||||
select_chip(port);
|
||||
if (with_lock)
|
||||
select_chip(port);
|
||||
|
||||
res = i2c_write8(chip->i2c_port, PI3USB9281_I2C_ADDR, reg, val);
|
||||
unselect_chip(port);
|
||||
|
||||
if (with_lock)
|
||||
unselect_chip(port);
|
||||
|
||||
if (res)
|
||||
CPRINTS("PI3USB9281 I2C write failed");
|
||||
return res;
|
||||
}
|
||||
|
||||
static int pi3usb9281_write(int port, uint8_t reg, uint8_t val)
|
||||
{
|
||||
return pi3usb9281_do_write(port, reg, val, 1);
|
||||
}
|
||||
|
||||
/* Write control register, taking care to correctly set reserved bits. */
|
||||
static int pi3usb9281_do_write_ctrl(int port, uint8_t ctrl, int with_lock)
|
||||
{
|
||||
return pi3usb9281_do_write(port, PI3USB9281_REG_CONTROL,
|
||||
(ctrl & PI3USB9281_CTRL_MASK) |
|
||||
PI3USB9281_CTRL_RSVD_1, with_lock);
|
||||
}
|
||||
|
||||
static int pi3usb9281_write_ctrl(int port, uint8_t ctrl)
|
||||
{
|
||||
return pi3usb9281_write(port, PI3USB9281_REG_CONTROL,
|
||||
(ctrl & PI3USB9281_CTRL_MASK) |
|
||||
PI3USB9281_CTRL_RSVD_1);
|
||||
return pi3usb9281_do_write_ctrl(port, ctrl, 1);
|
||||
}
|
||||
|
||||
static int pi3usb9281_write_ctrl_u(int port, uint8_t ctrl)
|
||||
{
|
||||
return pi3usb9281_do_write_ctrl(port, ctrl, 0);
|
||||
}
|
||||
|
||||
static int pi3usb9281_set_interrupt_mask(int port, uint8_t mask)
|
||||
@@ -190,17 +224,22 @@ static int pi3usb9281_reset(int port)
|
||||
|
||||
static int pi3usb9281_set_switch_manual(int port, int val)
|
||||
{
|
||||
uint8_t ctrl = pi3usb9281_read(port, PI3USB9281_REG_CONTROL);
|
||||
int res = EC_ERROR_UNKNOWN;
|
||||
uint8_t ctrl;
|
||||
|
||||
if (ctrl == 0xee)
|
||||
return EC_ERROR_UNKNOWN;
|
||||
select_chip(port);
|
||||
ctrl = pi3usb9281_read_u(port, PI3USB9281_REG_CONTROL);
|
||||
|
||||
if (val)
|
||||
ctrl &= ~PI3USB9281_CTRL_AUTO;
|
||||
else
|
||||
ctrl |= PI3USB9281_CTRL_AUTO;
|
||||
if (ctrl != 0xee) {
|
||||
if (val)
|
||||
ctrl &= ~PI3USB9281_CTRL_AUTO;
|
||||
else
|
||||
ctrl |= PI3USB9281_CTRL_AUTO;
|
||||
res = pi3usb9281_write_ctrl_u(port, ctrl);
|
||||
}
|
||||
|
||||
return pi3usb9281_write_ctrl(port, ctrl);
|
||||
unselect_chip(port);
|
||||
return res;
|
||||
}
|
||||
|
||||
static int pi3usb9281_set_pins(int port, uint8_t val)
|
||||
@@ -210,17 +249,22 @@ static int pi3usb9281_set_pins(int port, uint8_t val)
|
||||
|
||||
static int pi3usb9281_set_switches(int port, int open)
|
||||
{
|
||||
uint8_t ctrl = pi3usb9281_read(port, PI3USB9281_REG_CONTROL);
|
||||
int res = EC_ERROR_UNKNOWN;
|
||||
uint8_t ctrl;
|
||||
|
||||
if (ctrl == 0xee)
|
||||
return EC_ERROR_UNKNOWN;
|
||||
select_chip(port);
|
||||
ctrl = pi3usb9281_read_u(port, PI3USB9281_REG_CONTROL);
|
||||
|
||||
if (open)
|
||||
ctrl &= ~PI3USB9281_CTRL_SWITCH_AUTO;
|
||||
else
|
||||
ctrl |= PI3USB9281_CTRL_SWITCH_AUTO;
|
||||
if (ctrl != 0xee) {
|
||||
if (open)
|
||||
ctrl &= ~PI3USB9281_CTRL_SWITCH_AUTO;
|
||||
else
|
||||
ctrl |= PI3USB9281_CTRL_SWITCH_AUTO;
|
||||
res = pi3usb9281_write_ctrl_u(port, ctrl);
|
||||
}
|
||||
|
||||
return pi3usb9281_write_ctrl(port, ctrl);
|
||||
unselect_chip(port);
|
||||
return res;
|
||||
}
|
||||
|
||||
void usb_charger_set_switches(int port, enum usb_switch setting)
|
||||
|
||||
Reference in New Issue
Block a user