From 38145ed12ed9935377fec40e0c3f50fbdda1e148 Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Wed, 10 Jun 2020 11:37:41 +0800 Subject: usb: chipidea: udc: fix the ENDIAN issue Fix the ENDIAN issue when assign dTD entry. Reported-by: kbuild test robot Signed-off-by: Peter Chen --- drivers/usb/chipidea/udc.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c index db0cfde0cc3c..ff9de91d98ca 100644 --- a/drivers/usb/chipidea/udc.c +++ b/drivers/usb/chipidea/udc.c @@ -473,9 +473,10 @@ static void ci_add_buffer_entry(struct td_node *node, struct scatterlist *s) int empty_td_slot_index = (CI_MAX_BUF_SIZE - node->td_remaining_size) / CI_HDRC_PAGE_SIZE; int i; + u32 token; - node->ptr->token += - cpu_to_le32(sg_dma_len(s) << __ffs(TD_TOTAL_BYTES)); + token = le32_to_cpu(node->ptr->token) + (sg_dma_len(s) << __ffs(TD_TOTAL_BYTES)); + node->ptr->token = cpu_to_le32(token); for (i = empty_td_slot_index; i < TD_PAGE_COUNT; i++) { u32 page = (u32) sg_dma_address(s) + -- cgit v1.2.3 From 62b9825827518843f0f93dec6730ddcde14eb5b2 Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Mon, 17 Feb 2020 09:26:43 +0800 Subject: usb: chipidea: add query_available_role interface The glue layer may need to know current available role to do some setting, eg, the wakeup setting. So we add ci_hdrc_query_available_role for that. Signed-off-by: Peter Chen --- drivers/usb/chipidea/core.c | 27 +++++++++++++++++++++++++++ include/linux/usb/chipidea.h | 2 ++ 2 files changed, 29 insertions(+) (limited to 'drivers/usb') diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index 9a7c53d09ab4..87ae3c8686a7 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c @@ -877,6 +877,33 @@ void ci_hdrc_remove_device(struct platform_device *pdev) } EXPORT_SYMBOL_GPL(ci_hdrc_remove_device); +/** + * ci_hdrc_query_available_role: get runtime available operation mode + * + * The glue layer can get current operation mode (host/peripheral/otg) + * This function should be called after ci core device has created. + * + * @pdev: the platform device of ci core. + * + * Return runtime usb_dr_mode. + */ +enum usb_dr_mode ci_hdrc_query_available_role(struct platform_device *pdev) +{ + struct ci_hdrc *ci = platform_get_drvdata(pdev); + + if (!ci) + return USB_DR_MODE_UNKNOWN; + if (ci->roles[CI_ROLE_HOST] && ci->roles[CI_ROLE_GADGET]) + return USB_DR_MODE_OTG; + else if (ci->roles[CI_ROLE_HOST]) + return USB_DR_MODE_HOST; + else if (ci->roles[CI_ROLE_GADGET]) + return USB_DR_MODE_PERIPHERAL; + else + return USB_DR_MODE_UNKNOWN; +} +EXPORT_SYMBOL_GPL(ci_hdrc_query_available_role); + static inline void ci_role_destroy(struct ci_hdrc *ci) { ci_hdrc_gadget_destroy(ci); diff --git a/include/linux/usb/chipidea.h b/include/linux/usb/chipidea.h index 54167a2d28ea..025b41687ce9 100644 --- a/include/linux/usb/chipidea.h +++ b/include/linux/usb/chipidea.h @@ -99,5 +99,7 @@ struct platform_device *ci_hdrc_add_device(struct device *dev, struct ci_hdrc_platform_data *platdata); /* Remove ci hdrc device */ void ci_hdrc_remove_device(struct platform_device *pdev); +/* Get current available role */ +enum usb_dr_mode ci_hdrc_query_available_role(struct platform_device *pdev); #endif -- cgit v1.2.3 From d6f93d21001e4388a25b0b922e02e64bc6004d2f Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Tue, 28 Jul 2020 14:12:11 +0800 Subject: usb: chipidea: imx: get available runtime dr mode for wakeup setting If runtime dr_mode is not dual-role, it doesn't need to enable ID wakeup interrupt. If runtime dr_mode is host, it doesn't need to enable VBUS wakeup interrupt. With these changes, the user will not get the unexpected wakeup for single role use case. For example, the host-only use case at Micro-AB port, the controller should not be waken up by only plug in Micro-AB cable or the Micro-B cable with host. Signed-off-by: Peter Chen --- drivers/usb/chipidea/ci_hdrc_imx.c | 4 ++++ drivers/usb/chipidea/ci_hdrc_imx.h | 1 + drivers/usb/chipidea/usbmisc_imx.c | 4 ++-- 3 files changed, 7 insertions(+), 2 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c b/drivers/usb/chipidea/ci_hdrc_imx.c index 5ae16368a0c7..c39e2b615ac6 100644 --- a/drivers/usb/chipidea/ci_hdrc_imx.c +++ b/drivers/usb/chipidea/ci_hdrc_imx.c @@ -462,6 +462,10 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev) if (!IS_ERR(pdata.vbus_extcon.edev) || of_property_read_bool(np, "usb-role-switch")) data->usbmisc_data->ext_vbus = 1; + + /* usbmisc needs to know dr mode to choose wakeup setting */ + data->usbmisc_data->available_role = + ci_hdrc_query_available_role(data->ci_pdev); } ret = imx_usbmisc_init_post(data->usbmisc_data); diff --git a/drivers/usb/chipidea/ci_hdrc_imx.h b/drivers/usb/chipidea/ci_hdrc_imx.h index 727d02b6dbd3..99f846119c00 100644 --- a/drivers/usb/chipidea/ci_hdrc_imx.h +++ b/drivers/usb/chipidea/ci_hdrc_imx.h @@ -25,6 +25,7 @@ struct imx_usbmisc_data { unsigned int ext_id:1; /* ID from exteranl event */ unsigned int ext_vbus:1; /* Vbus from exteranl event */ struct usb_phy *usb_phy; + enum usb_dr_mode available_role; /* runtime usb dr mode */ }; int imx_usbmisc_init(struct imx_usbmisc_data *data); diff --git a/drivers/usb/chipidea/usbmisc_imx.c b/drivers/usb/chipidea/usbmisc_imx.c index f136876cb4a3..ae8f0f37e799 100644 --- a/drivers/usb/chipidea/usbmisc_imx.c +++ b/drivers/usb/chipidea/usbmisc_imx.c @@ -367,10 +367,10 @@ static u32 usbmisc_wakeup_setting(struct imx_usbmisc_data *data) { u32 wakeup_setting = MX6_USB_OTG_WAKEUP_BITS; - if (data->ext_id) + if (data->ext_id || data->available_role != USB_DR_MODE_OTG) wakeup_setting &= ~MX6_BM_ID_WAKEUP; - if (data->ext_vbus) + if (data->ext_vbus || data->available_role == USB_DR_MODE_HOST) wakeup_setting &= ~MX6_BM_VBUS_WAKEUP; return wakeup_setting; -- cgit v1.2.3