| From 7ad22a92186d9f8efdc6a689291bc24ec6c6cb92 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Wed, 29 Aug 2018 10:36:50 +0800 |
| Subject: usb: mtu3: disable vbus rise/fall interrupts of ltssm |
| |
| From: Chunfeng Yun <chunfeng.yun@mediatek.com> |
| |
| [ Upstream commit 0eae49582b4dee1a0e96007e1dea5122db98371a ] |
| |
| The vbus rise & fall interrupts are used to enable and disable |
| U3 function of device automatically, this cause some issues when |
| class driver is initialized as deactivated, and will skip over |
| software-controlled connect by pullup(), but UDC wants to keep |
| disconnect until usb_gadget_activate() is called which calls |
| pullup() if needed. So we disable vbus rise & fall interrupts |
| and just use pullup() to enable & disable U3 function, and reset |
| mtu3 state when disconnect instead when vbus fall. |
| |
| Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/usb/mtu3/mtu3_core.c | 4 ++-- |
| drivers/usb/mtu3/mtu3_gadget.c | 22 ++++++++++++++-------- |
| 2 files changed, 16 insertions(+), 10 deletions(-) |
| |
| diff --git a/drivers/usb/mtu3/mtu3_core.c b/drivers/usb/mtu3/mtu3_core.c |
| index 48d10a61e271c..8606935201326 100644 |
| --- a/drivers/usb/mtu3/mtu3_core.c |
| +++ b/drivers/usb/mtu3/mtu3_core.c |
| @@ -185,8 +185,8 @@ static void mtu3_intr_enable(struct mtu3 *mtu) |
| |
| if (mtu->is_u3_ip) { |
| /* Enable U3 LTSSM interrupts */ |
| - value = HOT_RST_INTR | WARM_RST_INTR | VBUS_RISE_INTR | |
| - VBUS_FALL_INTR | ENTER_U3_INTR | EXIT_U3_INTR; |
| + value = HOT_RST_INTR | WARM_RST_INTR | |
| + ENTER_U3_INTR | EXIT_U3_INTR; |
| mtu3_writel(mbase, U3D_LTSSM_INTR_ENABLE, value); |
| } |
| |
| diff --git a/drivers/usb/mtu3/mtu3_gadget.c b/drivers/usb/mtu3/mtu3_gadget.c |
| index 5c60a8c5a0b5c..bbcd3332471dc 100644 |
| --- a/drivers/usb/mtu3/mtu3_gadget.c |
| +++ b/drivers/usb/mtu3/mtu3_gadget.c |
| @@ -585,6 +585,17 @@ static const struct usb_gadget_ops mtu3_gadget_ops = { |
| .udc_stop = mtu3_gadget_stop, |
| }; |
| |
| +static void mtu3_state_reset(struct mtu3 *mtu) |
| +{ |
| + mtu->address = 0; |
| + mtu->ep0_state = MU3D_EP0_STATE_SETUP; |
| + mtu->may_wakeup = 0; |
| + mtu->u1_enable = 0; |
| + mtu->u2_enable = 0; |
| + mtu->delayed_status = false; |
| + mtu->test_mode = false; |
| +} |
| + |
| static void init_hw_ep(struct mtu3 *mtu, struct mtu3_ep *mep, |
| u32 epnum, u32 is_in) |
| { |
| @@ -702,6 +713,7 @@ void mtu3_gadget_disconnect(struct mtu3 *mtu) |
| spin_lock(&mtu->lock); |
| } |
| |
| + mtu3_state_reset(mtu); |
| usb_gadget_set_state(&mtu->g, USB_STATE_NOTATTACHED); |
| } |
| |
| @@ -712,12 +724,6 @@ void mtu3_gadget_reset(struct mtu3 *mtu) |
| /* report disconnect, if we didn't flush EP state */ |
| if (mtu->g.speed != USB_SPEED_UNKNOWN) |
| mtu3_gadget_disconnect(mtu); |
| - |
| - mtu->address = 0; |
| - mtu->ep0_state = MU3D_EP0_STATE_SETUP; |
| - mtu->may_wakeup = 0; |
| - mtu->u1_enable = 0; |
| - mtu->u2_enable = 0; |
| - mtu->delayed_status = false; |
| - mtu->test_mode = false; |
| + else |
| + mtu3_state_reset(mtu); |
| } |
| -- |
| 2.20.1 |
| |