Hi, On 11/8/21 11:28, Ondrej Jirman wrote: > The code that enables either BC_LVL or COMP_CHNG interrupt in tcpm_set_cc > wrongly assumes that the interrupt is unmasked by writing 1 to the apropriate > bit in the mask register. In fact, interrupts are enabled when the mask > is 0, so the tcpm_set_cc enables interrupt for COMP_CHNG when it expects > BC_LVL interrupt to be enabled. > > This causes inability of the driver to recognize cable unplug events > in host mode (unplug is recognized only via a COMP_CHNG interrupt). > > In device mode this bug was masked by simultaneous triggering of the VBUS > change interrupt, because of loss of VBUS when the port peer is providing > power. > > Fixes: 48242e30532b ("usb: typec: fusb302: Revert "Resolve fixed power role contract setup"") > Signed-off-by: Ondrej Jirman <megous@xxxxxxxxxx> > Cc: Hans de Goede <hdegoede@xxxxxxxxxx> Thanks, patch looks good to me: Reviewed-by: Hans de Goede <hdegoede@xxxxxxxxxx> Regards, Hans > --- > drivers/usb/typec/tcpm/fusb302.c | 6 ++++-- > 1 file changed, 4 insertions(+), 2 deletions(-) > > diff --git a/drivers/usb/typec/tcpm/fusb302.c b/drivers/usb/typec/tcpm/fusb302.c > index 7a2a17866a823..72f9001b07921 100644 > --- a/drivers/usb/typec/tcpm/fusb302.c > +++ b/drivers/usb/typec/tcpm/fusb302.c > @@ -669,25 +669,27 @@ static int tcpm_set_cc(struct tcpc_dev *dev, enum typec_cc_status cc) > ret = fusb302_i2c_mask_write(chip, FUSB_REG_MASK, > FUSB_REG_MASK_BC_LVL | > FUSB_REG_MASK_COMP_CHNG, > - FUSB_REG_MASK_COMP_CHNG); > + FUSB_REG_MASK_BC_LVL); > if (ret < 0) { > fusb302_log(chip, "cannot set SRC interrupt, ret=%d", > ret); > goto done; > } > chip->intr_comp_chng = true; > + chip->intr_bc_lvl = false; FWIW this is not necessary because the fusb302_set_toggling(chip, TOGGLING_MODE_OFF) already does this, but it makes the code more clear, so lets keep it. > break; > case TYPEC_CC_RD: > ret = fusb302_i2c_mask_write(chip, FUSB_REG_MASK, > FUSB_REG_MASK_BC_LVL | > FUSB_REG_MASK_COMP_CHNG, > - FUSB_REG_MASK_BC_LVL); > + FUSB_REG_MASK_COMP_CHNG); > if (ret < 0) { > fusb302_log(chip, "cannot set SRC interrupt, ret=%d", > ret); > goto done; > } > chip->intr_bc_lvl = true; > + chip->intr_comp_chng = false; Idem. > break; > default: > break; > Regards, Hans