On Mon, Nov 08, 2021 at 11:28:32AM +0100, 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> Should this go to stable? Acked-by: Heikki Krogerus@xxxxxxxxxxxxxxx > --- > 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; > 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; > break; > default: > break; thanks, -- heikki