On Sun, Jun 26, 2016 at 12:28:22AM -0700, Stephen Boyd wrote: > We're currently emulating the vbus and id interrupts in the OTGSC > read API, but we also need to make sure that if we're handling > the events with extcon that we don't enable the interrupts for > those events in the hardware. Therefore, properly emulate this > register if we're using extcon, but don't enable the interrupts. > This allows me to get my cable connect/disconnect working > properly without getting spurious interrupts on my device that > uses an extcon for these two events. > > Cc: Peter Chen <peter.chen@xxxxxxx> > Cc: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx> > Cc: "Ivan T. Ivanov" <iivanov.xz@xxxxxxxxx> > Fixes: 3ecb3e09b042 ("usb: chipidea: Use extcon framework for VBUS and ID detect") > Signed-off-by: Stephen Boyd <stephen.boyd@xxxxxxxxxx> > --- > drivers/usb/chipidea/otg.c | 46 +++++++++++++++++++++++++++++++++++++++----- > include/linux/usb/chipidea.h | 2 ++ > 2 files changed, 43 insertions(+), 5 deletions(-) > > diff --git a/drivers/usb/chipidea/otg.c b/drivers/usb/chipidea/otg.c > index 763a8332b009..b6a88bea4cac 100644 > --- a/drivers/usb/chipidea/otg.c > +++ b/drivers/usb/chipidea/otg.c > @@ -44,12 +44,15 @@ u32 hw_read_otgsc(struct ci_hdrc *ci, u32 mask) > else > val &= ~OTGSC_BSVIS; > > - cable->changed = false; > - > if (cable->state) > val |= OTGSC_BSV; > else > val &= ~OTGSC_BSV; > + > + if (cable->enabled) > + val |= OTGSC_BSVIE; > + else > + val &= ~OTGSC_BSVIE; > } > > cable = &ci->platdata->id_extcon; > @@ -59,15 +62,18 @@ u32 hw_read_otgsc(struct ci_hdrc *ci, u32 mask) > else > val &= ~OTGSC_IDIS; > > - cable->changed = false; > - > if (cable->state) > val |= OTGSC_ID; > else > val &= ~OTGSC_ID; > + > + if (cable->enabled) > + val |= OTGSC_IDIE; > + else > + val &= ~OTGSC_IDIE; > } > > - return val; > + return val & mask; > } > > /** > @@ -77,6 +83,36 @@ u32 hw_read_otgsc(struct ci_hdrc *ci, u32 mask) > */ > void hw_write_otgsc(struct ci_hdrc *ci, u32 mask, u32 data) > { > + struct ci_hdrc_cable *cable; > + > + cable = &ci->platdata->vbus_extcon; > + if (!IS_ERR(cable->edev)) { > + if (data & mask & OTGSC_BSVIS) > + cable->changed = false; > + > + /* Don't enable vbus interrupt if using external notifier */ > + if (data & mask & OTGSC_BSVIE) { > + cable->enabled = true; > + data &= ~OTGSC_BSVIE; > + } else if (mask & OTGSC_BSVIE) { > + cable->enabled = false; > + } > + } > + > + cable = &ci->platdata->id_extcon; > + if (!IS_ERR(cable->edev)) { > + if (data & mask & OTGSC_IDIS) > + cable->changed = false; > + > + /* Don't enable id interrupt if using external notifier */ > + if (data & mask & OTGSC_IDIE) { > + cable->enabled = true; > + data &= ~OTGSC_IDIE; > + } else if (mask & OTGSC_IDIE) { > + cable->enabled = false; > + } > + } > + > hw_write(ci, OP_OTGSC, mask | OTGSC_INT_STATUS_BITS, data); > } > > diff --git a/include/linux/usb/chipidea.h b/include/linux/usb/chipidea.h > index 5dd75fa47dd8..f9be467d6695 100644 > --- a/include/linux/usb/chipidea.h > +++ b/include/linux/usb/chipidea.h > @@ -14,6 +14,7 @@ struct ci_hdrc; > * struct ci_hdrc_cable - structure for external connector cable state tracking > * @state: current state of the line > * @changed: set to true when extcon event happen > + * @enabled: set to true if we've enabled the vbus or id interrupt > * @edev: device which generate events > * @ci: driver state of the chipidea device > * @nb: hold event notification callback > @@ -22,6 +23,7 @@ struct ci_hdrc; > struct ci_hdrc_cable { > bool state; > bool changed; > + bool enabled; > struct extcon_dev *edev; > struct ci_hdrc *ci; > struct notifier_block nb; > -- Acked-by: Peter Chen <peter.chen@xxxxxxx> -- Best Regards, Peter Chen -- To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html