]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
usb: chipidea: add CI_HDRC_HAS_SHORT_PKT_LIMIT flag
authorXu Yang <xu.yang_2@nxp.com>
Mon, 23 Sep 2024 08:12:01 +0000 (16:12 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 14 Dec 2024 19:04:07 +0000 (20:04 +0100)
[ Upstream commit ec841b8d73cff37f8960e209017efe1eb2fb21f2 ]

Currently, the imx deivice controller has below limitations:

1. can't generate short packet interrupt if IOC not set in dTD. So if one
   request span more than one dTDs and only the last dTD set IOC, the usb
   request will pending there if no more data comes.
2. the controller can't accurately deliver data to differtent usb requests
   in some cases due to short packet. For example: one usb request span 3
   dTDs, then if the controller received a short packet the next packet
   will go to 2nd dTD of current request rather than the first dTD of next
   request.
3. can't build a bus packet use multiple dTDs. For example: controller
   needs to send one packet of 512 bytes use dTD1 (200 bytes) + dTD2
   (312 bytes), actually the host side will see 200 bytes short packet.

Based on these limits, add CI_HDRC_HAS_SHORT_PKT_LIMIT flag and use it on
imx platforms.

Signed-off-by: Xu Yang <xu.yang_2@nxp.com>
Acked-by: Peter Chen <peter.chen@kernel.org>
Link: https://lore.kernel.org/r/20240923081203.2851768-1-xu.yang_2@nxp.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/usb/chipidea/ci.h
drivers/usb/chipidea/ci_hdrc_imx.c
drivers/usb/chipidea/core.c
include/linux/usb/chipidea.h

index 2a38e1eb65466c82a6eb9e4f2feba8fc59ee7dfc..e4b003d060c260874fbca4d4df2e786214b068ba 100644 (file)
@@ -260,6 +260,7 @@ struct ci_hdrc {
        bool                            b_sess_valid_event;
        bool                            imx28_write_fix;
        bool                            has_portsc_pec_bug;
+       bool                            has_short_pkt_limit;
        bool                            supports_runtime_pm;
        bool                            in_lpm;
        bool                            wakeup_int;
index c64ab0e07ea030cc7f23120fea1d211408955918..17b3ac2ac8a1e89550b51e941e766e520e36a09b 100644 (file)
@@ -342,6 +342,7 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
        struct ci_hdrc_platform_data pdata = {
                .name           = dev_name(&pdev->dev),
                .capoffset      = DEF_CAPOFFSET,
+               .flags          = CI_HDRC_HAS_SHORT_PKT_LIMIT,
                .notify_event   = ci_hdrc_imx_notify_event,
        };
        int ret;
index 835bf2428dc6eccee263b05024d42885884cd94d..5aa16dbfc289ce59bf5385a0e3a3749a6bf0dd6e 100644 (file)
@@ -1076,6 +1076,8 @@ static int ci_hdrc_probe(struct platform_device *pdev)
                CI_HDRC_SUPPORTS_RUNTIME_PM);
        ci->has_portsc_pec_bug = !!(ci->platdata->flags &
                CI_HDRC_HAS_PORTSC_PEC_MISSED);
+       ci->has_short_pkt_limit = !!(ci->platdata->flags &
+               CI_HDRC_HAS_SHORT_PKT_LIMIT);
        platform_set_drvdata(pdev, ci);
 
        ret = hw_device_init(ci, base);
index 5a7f96684ea226e2de0512e7f3246f1712dc6cd7..ebdfef124b2bc02433b45c27d032f56eba704263 100644 (file)
@@ -65,6 +65,7 @@ struct ci_hdrc_platform_data {
 #define CI_HDRC_PHY_VBUS_CONTROL       BIT(16)
 #define CI_HDRC_HAS_PORTSC_PEC_MISSED  BIT(17)
 #define CI_HDRC_FORCE_VBUS_ACTIVE_ALWAYS       BIT(18)
+#define        CI_HDRC_HAS_SHORT_PKT_LIMIT     BIT(19)
        enum usb_dr_mode        dr_mode;
 #define CI_HDRC_CONTROLLER_RESET_EVENT         0
 #define CI_HDRC_CONTROLLER_STOPPED_EVENT       1