summaryrefslogtreecommitdiff
path: root/drivers/usb/host/xhci-mtk-sch.c
diff options
context:
space:
mode:
authorChunfeng Yun <chunfeng.yun@mediatek.com>2021-02-01 08:57:44 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2021-02-01 16:10:36 +0300
commit54f6a8af372213a254af6609758d99f7c0b6b5ad (patch)
tree3438e0b606e10275bd2c5686e30b3e6b4ddb5282 /drivers/usb/host/xhci-mtk-sch.c
parent9917f0e3cdba7b9f1a23f70e3f70b1a106be54a8 (diff)
downloadlinux-54f6a8af372213a254af6609758d99f7c0b6b5ad.tar.xz
usb: xhci-mtk: skip dropping bandwidth of unchecked endpoints
For those unchecked endpoints, we don't allocate bandwidth for them, so no need free the bandwidth, otherwise will decrease the allocated bandwidth. Meanwhile use xhci_dbg() instead of dev_dbg() to print logs and rename bw_ep_list_new as bw_ep_chk_list. Fixes: 1d69f9d901ef ("usb: xhci-mtk: fix unreleased bandwidth data") Cc: stable <stable@vger.kernel.org> Reviewed-and-tested-by: Ikjoon Jang <ikjn@chromium.org> Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com> Link: https://lore.kernel.org/r/1612159064-28413-1-git-send-email-chunfeng.yun@mediatek.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/host/xhci-mtk-sch.c')
-rw-r--r--drivers/usb/host/xhci-mtk-sch.c61
1 files changed, 33 insertions, 28 deletions
diff --git a/drivers/usb/host/xhci-mtk-sch.c b/drivers/usb/host/xhci-mtk-sch.c
index a313e75ff1c6..dee8a329076d 100644
--- a/drivers/usb/host/xhci-mtk-sch.c
+++ b/drivers/usb/host/xhci-mtk-sch.c
@@ -200,6 +200,7 @@ static struct mu3h_sch_ep_info *create_sch_ep(struct usb_device *udev,
sch_ep->sch_tt = tt;
sch_ep->ep = ep;
+ INIT_LIST_HEAD(&sch_ep->endpoint);
INIT_LIST_HEAD(&sch_ep->tt_endpoint);
return sch_ep;
@@ -374,6 +375,7 @@ static void update_bus_bw(struct mu3h_sch_bw_info *sch_bw,
sch_ep->bw_budget_table[j];
}
}
+ sch_ep->allocated = used;
}
static int check_sch_tt(struct usb_device *udev,
@@ -542,6 +544,22 @@ static int check_sch_bw(struct usb_device *udev,
return 0;
}
+static void destroy_sch_ep(struct usb_device *udev,
+ struct mu3h_sch_bw_info *sch_bw, struct mu3h_sch_ep_info *sch_ep)
+{
+ /* only release ep bw check passed by check_sch_bw() */
+ if (sch_ep->allocated)
+ update_bus_bw(sch_bw, sch_ep, 0);
+
+ list_del(&sch_ep->endpoint);
+
+ if (sch_ep->sch_tt) {
+ list_del(&sch_ep->tt_endpoint);
+ drop_tt(udev);
+ }
+ kfree(sch_ep);
+}
+
static bool need_bw_sch(struct usb_host_endpoint *ep,
enum usb_device_speed speed, int has_tt)
{
@@ -584,7 +602,7 @@ int xhci_mtk_sch_init(struct xhci_hcd_mtk *mtk)
mtk->sch_array = sch_array;
- INIT_LIST_HEAD(&mtk->bw_ep_list_new);
+ INIT_LIST_HEAD(&mtk->bw_ep_chk_list);
return 0;
}
@@ -636,29 +654,12 @@ int xhci_mtk_add_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev,
setup_sch_info(udev, ep_ctx, sch_ep);
- list_add_tail(&sch_ep->endpoint, &mtk->bw_ep_list_new);
+ list_add_tail(&sch_ep->endpoint, &mtk->bw_ep_chk_list);
return 0;
}
EXPORT_SYMBOL_GPL(xhci_mtk_add_ep_quirk);
-static void xhci_mtk_drop_ep(struct xhci_hcd_mtk *mtk, struct usb_device *udev,
- struct mu3h_sch_ep_info *sch_ep)
-{
- struct xhci_hcd *xhci = hcd_to_xhci(mtk->hcd);
- int bw_index = get_bw_index(xhci, udev, sch_ep->ep);
- struct mu3h_sch_bw_info *sch_bw = &mtk->sch_array[bw_index];
-
- update_bus_bw(sch_bw, sch_ep, 0);
- list_del(&sch_ep->endpoint);
-
- if (sch_ep->sch_tt) {
- list_del(&sch_ep->tt_endpoint);
- drop_tt(udev);
- }
- kfree(sch_ep);
-}
-
void xhci_mtk_drop_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev,
struct usb_host_endpoint *ep)
{
@@ -688,9 +689,8 @@ void xhci_mtk_drop_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev,
sch_bw = &sch_array[bw_index];
list_for_each_entry_safe(sch_ep, tmp, &sch_bw->bw_ep_list, endpoint) {
- if (sch_ep->ep == ep) {
- xhci_mtk_drop_ep(mtk, udev, sch_ep);
- }
+ if (sch_ep->ep == ep)
+ destroy_sch_ep(udev, sch_bw, sch_ep);
}
}
EXPORT_SYMBOL_GPL(xhci_mtk_drop_ep_quirk);
@@ -704,9 +704,9 @@ int xhci_mtk_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev)
struct mu3h_sch_ep_info *sch_ep, *tmp;
int bw_index, ret;
- dev_dbg(&udev->dev, "%s\n", __func__);
+ xhci_dbg(xhci, "%s() udev %s\n", __func__, dev_name(&udev->dev));
- list_for_each_entry(sch_ep, &mtk->bw_ep_list_new, endpoint) {
+ list_for_each_entry(sch_ep, &mtk->bw_ep_chk_list, endpoint) {
bw_index = get_bw_index(xhci, udev, sch_ep->ep);
sch_bw = &mtk->sch_array[bw_index];
@@ -717,7 +717,7 @@ int xhci_mtk_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev)
}
}
- list_for_each_entry_safe(sch_ep, tmp, &mtk->bw_ep_list_new, endpoint) {
+ list_for_each_entry_safe(sch_ep, tmp, &mtk->bw_ep_chk_list, endpoint) {
struct xhci_ep_ctx *ep_ctx;
struct usb_host_endpoint *ep = sch_ep->ep;
unsigned int ep_index = xhci_get_endpoint_index(&ep->desc);
@@ -746,12 +746,17 @@ EXPORT_SYMBOL_GPL(xhci_mtk_check_bandwidth);
void xhci_mtk_reset_bandwidth(struct usb_hcd *hcd, struct usb_device *udev)
{
struct xhci_hcd_mtk *mtk = hcd_to_mtk(hcd);
+ struct xhci_hcd *xhci = hcd_to_xhci(hcd);
+ struct mu3h_sch_bw_info *sch_bw;
struct mu3h_sch_ep_info *sch_ep, *tmp;
+ int bw_index;
- dev_dbg(&udev->dev, "%s\n", __func__);
+ xhci_dbg(xhci, "%s() udev %s\n", __func__, dev_name(&udev->dev));
- list_for_each_entry_safe(sch_ep, tmp, &mtk->bw_ep_list_new, endpoint) {
- xhci_mtk_drop_ep(mtk, udev, sch_ep);
+ list_for_each_entry_safe(sch_ep, tmp, &mtk->bw_ep_chk_list, endpoint) {
+ bw_index = get_bw_index(xhci, udev, sch_ep->ep);
+ sch_bw = &mtk->sch_array[bw_index];
+ destroy_sch_ep(udev, sch_bw, sch_ep);
}
xhci_reset_bandwidth(hcd, udev);