From aa5ab36aeda54853944b4c666348cd6592b0024b Mon Sep 17 00:00:00 2001 From: Tang Bin Date: Mon, 6 Apr 2020 13:55:30 +0800 Subject: usb: host: ehci-tegra: Remove superfluous dev_err() message The platform_get_irq() can print error message,so remove the redundant dev_err() here. Signed-off-by: Tang Bin Acked-by: Thierry Reding Link: https://lore.kernel.org/r/20200406055530.10860-1-tangbin@cmss.chinamobile.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-tegra.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/usb/host') diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c index 10d51daa6a1b..e077b2ca53c5 100644 --- a/drivers/usb/host/ehci-tegra.c +++ b/drivers/usb/host/ehci-tegra.c @@ -480,7 +480,6 @@ static int tegra_ehci_probe(struct platform_device *pdev) irq = platform_get_irq(pdev, 0); if (!irq) { - dev_err(&pdev->dev, "Failed to get IRQ\n"); err = -ENODEV; goto cleanup_phy; } -- cgit v1.2.3-59-g8ed1b From 48ce9e4119ce24131d188746118e948e9e97fc1d Mon Sep 17 00:00:00 2001 From: Madhuparna Bhowmik Date: Sat, 4 Apr 2020 23:11:02 +0530 Subject: usb: host: u132-hcd: Remove u132_static_list and list head u132_list u132_static_list is a global list protected by u132_module_lock. It is read in the u132_hcd_exit() function without holding the lock thus may lead to data race. However, it turns out that this list isn't used for anything useful and thus it is okay to get rid of it. Thus, remove the u132_static_list from u132-hcd module. Also remove struct list_head u132_list from struct u132. Found by Linux Driver Verification project (linuxtesting.org). Suggested-by: Alan Stern Signed-off-by: Madhuparna Bhowmik Link: https://lore.kernel.org/r/20200404174102.19862-1-madhuparnabhowmik10@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/u132-hcd.c | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'drivers/usb/host') diff --git a/drivers/usb/host/u132-hcd.c b/drivers/usb/host/u132-hcd.c index e9209e3e6248..995bc52d2d22 100644 --- a/drivers/usb/host/u132-hcd.c +++ b/drivers/usb/host/u132-hcd.c @@ -81,7 +81,6 @@ static DECLARE_WAIT_QUEUE_HEAD(u132_hcd_wait); static struct mutex u132_module_lock; static int u132_exiting; static int u132_instances; -static struct list_head u132_static_list; /* * end of the global variables protected by u132_module_lock */ @@ -177,7 +176,6 @@ struct u132_ring { }; struct u132 { struct kref kref; - struct list_head u132_list; struct mutex sw_lock; struct mutex scheduler_lock; struct u132_platform_data *board; @@ -254,7 +252,6 @@ static void u132_hcd_delete(struct kref *kref) struct usb_hcd *hcd = u132_to_hcd(u132); u132->going += 1; mutex_lock(&u132_module_lock); - list_del_init(&u132->u132_list); u132_instances -= 1; mutex_unlock(&u132_module_lock); dev_warn(&u132->platform_dev->dev, "FREEING the hcd=%p and thus the u13" @@ -3089,7 +3086,6 @@ static int u132_probe(struct platform_device *pdev) retval = 0; hcd->rsrc_start = 0; mutex_lock(&u132_module_lock); - list_add_tail(&u132->u132_list, &u132_static_list); u132->sequence_num = ++u132_instances; mutex_unlock(&u132_module_lock); u132_u132_init_kref(u132); @@ -3192,7 +3188,6 @@ static struct platform_driver u132_platform_driver = { static int __init u132_hcd_init(void) { int retval; - INIT_LIST_HEAD(&u132_static_list); u132_instances = 0; u132_exiting = 0; mutex_init(&u132_module_lock); @@ -3213,14 +3208,9 @@ static int __init u132_hcd_init(void) module_init(u132_hcd_init); static void __exit u132_hcd_exit(void) { - struct u132 *u132; - struct u132 *temp; mutex_lock(&u132_module_lock); u132_exiting += 1; mutex_unlock(&u132_module_lock); - list_for_each_entry_safe(u132, temp, &u132_static_list, u132_list) { - platform_device_unregister(u132->platform_dev); - } platform_driver_unregister(&u132_platform_driver); printk(KERN_INFO "u132-hcd driver deregistered\n"); wait_event(u132_hcd_wait, u132_instances == 0); -- cgit v1.2.3-59-g8ed1b From 3e45ed3cc14894a4d5114127ebdc62296521f365 Mon Sep 17 00:00:00 2001 From: Nishad Kamdar Date: Sat, 4 Apr 2020 14:51:40 +0530 Subject: USB: host: Use the correct style for SPDX License Identifier This patch corrects the SPDX License Identifier style in header files related to USB host controller drivers. For C header files Documentation/process/license-rules.rst mandates C-like comments (opposed to C source files where C++ style should be used). Changes made by using a script provided by Joe Perches here: https://lkml.org/lkml/2019/2/7/46. Suggested-by: Joe Perches Signed-off-by: Nishad Kamdar Link: https://lore.kernel.org/r/20200404092135.GA4522@nishad Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-fsl.h | 2 +- drivers/usb/host/ehci.h | 2 +- drivers/usb/host/fhci.h | 2 +- drivers/usb/host/imx21-hcd.h | 2 +- drivers/usb/host/ohci.h | 2 +- drivers/usb/host/r8a66597.h | 2 +- drivers/usb/host/xhci-debugfs.h | 2 +- drivers/usb/host/xhci-ext-caps.h | 2 +- drivers/usb/host/xhci-mtk.h | 2 +- drivers/usb/host/xhci-mvebu.h | 2 +- drivers/usb/host/xhci-plat.h | 2 +- drivers/usb/host/xhci-rcar.h | 2 +- drivers/usb/host/xhci-trace.h | 2 +- drivers/usb/host/xhci.h | 2 +- 14 files changed, 14 insertions(+), 14 deletions(-) (limited to 'drivers/usb/host') diff --git a/drivers/usb/host/ehci-fsl.h b/drivers/usb/host/ehci-fsl.h index 9d18c6e6ab27..c95341d472f4 100644 --- a/drivers/usb/host/ehci-fsl.h +++ b/drivers/usb/host/ehci-fsl.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* Copyright (C) 2005-2010,2012 Freescale Semiconductor, Inc. * Copyright (c) 2005 MontaVista Software */ diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index 229b3de319e6..eabf22a78eae 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (c) 2001-2002 by David Brownell */ diff --git a/drivers/usb/host/fhci.h b/drivers/usb/host/fhci.h index 2ce5031d866d..81fbc019a9b3 100644 --- a/drivers/usb/host/fhci.h +++ b/drivers/usb/host/fhci.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Freescale QUICC Engine USB Host Controller Driver * diff --git a/drivers/usb/host/imx21-hcd.h b/drivers/usb/host/imx21-hcd.h index 7b9cf0a38d6e..96d16752a73e 100644 --- a/drivers/usb/host/imx21-hcd.h +++ b/drivers/usb/host/imx21-hcd.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Macros and prototypes for i.MX21 * diff --git a/drivers/usb/host/ohci.h b/drivers/usb/host/ohci.h index 27c26ca10bfd..b85a39588f9d 100644 --- a/drivers/usb/host/ohci.h +++ b/drivers/usb/host/ohci.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-1.0+ +/* SPDX-License-Identifier: GPL-1.0+ */ /* * OHCI HCD (Host Controller Driver) for USB. * diff --git a/drivers/usb/host/r8a66597.h b/drivers/usb/host/r8a66597.h index 51973a923526..ab081475c113 100644 --- a/drivers/usb/host/r8a66597.h +++ b/drivers/usb/host/r8a66597.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +/* SPDX-License-Identifier: GPL-2.0 */ /* * R8A66597 HCD (Host Controller Driver) * diff --git a/drivers/usb/host/xhci-debugfs.h b/drivers/usb/host/xhci-debugfs.h index f7a4e2492b00..56db635fcd6e 100644 --- a/drivers/usb/host/xhci-debugfs.h +++ b/drivers/usb/host/xhci-debugfs.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +/* SPDX-License-Identifier: GPL-2.0 */ /* * xhci-debugfs.h - xHCI debugfs interface * diff --git a/drivers/usb/host/xhci-ext-caps.h b/drivers/usb/host/xhci-ext-caps.h index 268328c20681..fa59b242cd51 100644 --- a/drivers/usb/host/xhci-ext-caps.h +++ b/drivers/usb/host/xhci-ext-caps.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +/* SPDX-License-Identifier: GPL-2.0 */ /* * xHCI host controller driver * diff --git a/drivers/usb/host/xhci-mtk.h b/drivers/usb/host/xhci-mtk.h index acd56517215a..a93cfe817904 100644 --- a/drivers/usb/host/xhci-mtk.h +++ b/drivers/usb/host/xhci-mtk.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (c) 2015 MediaTek Inc. * Author: diff --git a/drivers/usb/host/xhci-mvebu.h b/drivers/usb/host/xhci-mvebu.h index ca0a3a5721dd..3be021793cc8 100644 --- a/drivers/usb/host/xhci-mvebu.h +++ b/drivers/usb/host/xhci-mvebu.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (C) 2014 Marvell * diff --git a/drivers/usb/host/xhci-plat.h b/drivers/usb/host/xhci-plat.h index 5681723fc9cd..b49f6447bd3a 100644 --- a/drivers/usb/host/xhci-plat.h +++ b/drivers/usb/host/xhci-plat.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +/* SPDX-License-Identifier: GPL-2.0 */ /* * xhci-plat.h - xHCI host controller driver platform Bus Glue. * diff --git a/drivers/usb/host/xhci-rcar.h b/drivers/usb/host/xhci-rcar.h index 012744a63a49..048ad3b8a6c7 100644 --- a/drivers/usb/host/xhci-rcar.h +++ b/drivers/usb/host/xhci-rcar.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +/* SPDX-License-Identifier: GPL-2.0 */ /* * drivers/usb/host/xhci-rcar.h * diff --git a/drivers/usb/host/xhci-trace.h b/drivers/usb/host/xhci-trace.h index b19582b2a72c..627abd236dbe 100644 --- a/drivers/usb/host/xhci-trace.h +++ b/drivers/usb/host/xhci-trace.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +/* SPDX-License-Identifier: GPL-2.0 */ /* * xHCI host controller driver * diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 3289bb516201..fb50f0e82d08 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +/* SPDX-License-Identifier: GPL-2.0 */ /* * xHCI host controller driver -- cgit v1.2.3-59-g8ed1b From cfee546166583fa1a51f657e2f84d866a3552710 Mon Sep 17 00:00:00 2001 From: Jason Yan Date: Mon, 20 Apr 2020 12:26:22 +0800 Subject: usb: pci-quirks: use true,false for bool variables Fix the following coccicheck warning: drivers/usb/host/pci-quirks.c:532:1-27: WARNING: Assignment of 0/1 to bool variable drivers/usb/host/pci-quirks.c:208:1-20: WARNING: Assignment of 0/1 to bool variable drivers/usb/host/pci-quirks.c:232:2-21: WARNING: Assignment of 0/1 to bool variable drivers/usb/host/pci-quirks.c:235:2-21: WARNING: Assignment of 0/1 to bool variable Signed-off-by: Jason Yan Link: https://lore.kernel.org/r/20200420042622.18564-1-yanaijie@huawei.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/pci-quirks.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/usb/host') diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c index beb2efa71341..92150ecdb036 100644 --- a/drivers/usb/host/pci-quirks.c +++ b/drivers/usb/host/pci-quirks.c @@ -205,7 +205,7 @@ static void usb_amd_find_chipset_info(void) { unsigned long flags; struct amd_chipset_info info; - info.need_pll_quirk = 0; + info.need_pll_quirk = false; spin_lock_irqsave(&amd_lock, flags); @@ -229,10 +229,10 @@ static void usb_amd_find_chipset_info(void) case AMD_CHIPSET_SB800: case AMD_CHIPSET_HUDSON2: case AMD_CHIPSET_BOLTON: - info.need_pll_quirk = 1; + info.need_pll_quirk = true; break; default: - info.need_pll_quirk = 0; + info.need_pll_quirk = false; break; } @@ -529,7 +529,7 @@ void usb_amd_dev_put(void) amd_chipset.nb_type = 0; memset(&amd_chipset.sb_type, 0, sizeof(amd_chipset.sb_type)); amd_chipset.isoc_reqs = 0; - amd_chipset.need_pll_quirk = 0; + amd_chipset.need_pll_quirk = false; spin_unlock_irqrestore(&amd_lock, flags); -- cgit v1.2.3-59-g8ed1b From 15518726d60a39c7a517fff1a374dab403637a2a Mon Sep 17 00:00:00 2001 From: Tang Bin Date: Fri, 8 May 2020 22:40:24 +0800 Subject: USB: host: ehci-mxc: Use the defined variable to simplify code Use the defined variable "dev" to make the code cleaner. And delete an extra blank line. Signed-off-by: Zhang Shengju Signed-off-by: Tang Bin Acked-by: Alan Stern Link: https://lore.kernel.org/r/20200508144024.7836-1-tangbin@cmss.chinamobile.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-mxc.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'drivers/usb/host') diff --git a/drivers/usb/host/ehci-mxc.c b/drivers/usb/host/ehci-mxc.c index c9f91e6c72b6..09e01397f987 100644 --- a/drivers/usb/host/ehci-mxc.c +++ b/drivers/usb/host/ehci-mxc.c @@ -36,12 +36,12 @@ static const struct ehci_driver_overrides ehci_mxc_overrides __initconst = { static int ehci_mxc_drv_probe(struct platform_device *pdev) { - struct mxc_usbh_platform_data *pdata = dev_get_platdata(&pdev->dev); + struct device *dev = &pdev->dev; + struct mxc_usbh_platform_data *pdata = dev_get_platdata(dev); struct usb_hcd *hcd; struct resource *res; int irq, ret; struct ehci_mxc_priv *priv; - struct device *dev = &pdev->dev; struct ehci_hcd *ehci; if (!pdata) { @@ -56,7 +56,7 @@ static int ehci_mxc_drv_probe(struct platform_device *pdev) return -ENOMEM; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - hcd->regs = devm_ioremap_resource(&pdev->dev, res); + hcd->regs = devm_ioremap_resource(dev, res); if (IS_ERR(hcd->regs)) { ret = PTR_ERR(hcd->regs); goto err_alloc; @@ -69,14 +69,14 @@ static int ehci_mxc_drv_probe(struct platform_device *pdev) priv = (struct ehci_mxc_priv *) ehci->priv; /* enable clocks */ - priv->usbclk = devm_clk_get(&pdev->dev, "ipg"); + priv->usbclk = devm_clk_get(dev, "ipg"); if (IS_ERR(priv->usbclk)) { ret = PTR_ERR(priv->usbclk); goto err_alloc; } clk_prepare_enable(priv->usbclk); - priv->ahbclk = devm_clk_get(&pdev->dev, "ahb"); + priv->ahbclk = devm_clk_get(dev, "ahb"); if (IS_ERR(priv->ahbclk)) { ret = PTR_ERR(priv->ahbclk); goto err_clk_ahb; @@ -84,13 +84,12 @@ static int ehci_mxc_drv_probe(struct platform_device *pdev) clk_prepare_enable(priv->ahbclk); /* "dr" device has its own clock on i.MX51 */ - priv->phyclk = devm_clk_get(&pdev->dev, "phy"); + priv->phyclk = devm_clk_get(dev, "phy"); if (IS_ERR(priv->phyclk)) priv->phyclk = NULL; if (priv->phyclk) clk_prepare_enable(priv->phyclk); - /* call platform specific init function */ if (pdata->init) { ret = pdata->init(pdev); -- cgit v1.2.3-59-g8ed1b From 09806eba8279376de481c74bc1a2090283db757d Mon Sep 17 00:00:00 2001 From: Tang Bin Date: Fri, 8 May 2020 22:21:36 +0800 Subject: USB: EHCI: ehci-mv: Fix unused assignment in mv_ehci_probe() Delete unused initialized value, because 'retval' will be assigined by the function mv_ehci_enable(). And delete the extra blank lines. Signed-off-by: Zhang Shengju Signed-off-by: Tang Bin Acked-by: Alan Stern Link: https://lore.kernel.org/r/20200508142136.4232-1-tangbin@cmss.chinamobile.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-mv.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers/usb/host') diff --git a/drivers/usb/host/ehci-mv.c b/drivers/usb/host/ehci-mv.c index 1300c457d9ed..8f692fe17f45 100644 --- a/drivers/usb/host/ehci-mv.c +++ b/drivers/usb/host/ehci-mv.c @@ -108,7 +108,7 @@ static int mv_ehci_probe(struct platform_device *pdev) struct ehci_hcd *ehci; struct ehci_hcd_mv *ehci_mv; struct resource *r; - int retval = -ENODEV; + int retval; u32 offset; u32 status; @@ -143,8 +143,6 @@ static int mv_ehci_probe(struct platform_device *pdev) goto err_put_hcd; } - - r = platform_get_resource(pdev, IORESOURCE_MEM, 0); ehci_mv->base = devm_ioremap_resource(&pdev->dev, r); if (IS_ERR(ehci_mv->base)) { -- cgit v1.2.3-59-g8ed1b From c856b4b0fdb5044bca4c0acf9a66f3b5cc01a37a Mon Sep 17 00:00:00 2001 From: Tang Bin Date: Fri, 8 May 2020 19:43:05 +0800 Subject: USB: EHCI: ehci-mv: fix error handling in mv_ehci_probe() If the function platform_get_irq() failed, the negative value returned will not be detected here. So fix error handling in mv_ehci_probe(). And when get irq failed, the function platform_get_irq() logs an error message, so remove redundant message here. Signed-off-by: Zhang Shengju Signed-off-by: Tang Bin Link: https://lore.kernel.org/r/20200508114305.15740-1-tangbin@cmss.chinamobile.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-mv.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/usb/host') diff --git a/drivers/usb/host/ehci-mv.c b/drivers/usb/host/ehci-mv.c index 8f692fe17f45..0d61f43c29dc 100644 --- a/drivers/usb/host/ehci-mv.c +++ b/drivers/usb/host/ehci-mv.c @@ -167,9 +167,8 @@ static int mv_ehci_probe(struct platform_device *pdev) hcd->regs = ehci_mv->op_regs; hcd->irq = platform_get_irq(pdev, 0); - if (!hcd->irq) { - dev_err(&pdev->dev, "Cannot get irq."); - retval = -ENODEV; + if (hcd->irq < 0) { + retval = hcd->irq; goto err_disable_clk; } -- cgit v1.2.3-59-g8ed1b From b919e077cccfbb77beb98809568b2fb0b4d113ec Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Wed, 6 May 2020 13:56:25 +0000 Subject: USB: ohci-sm501: fix error return code in ohci_hcd_sm501_drv_probe() Fix to return a negative error code from the error handling case instead of 0, as done elsewhere in this function. Fixes: 7d9e6f5aebe8 ("usb: host: ohci-sm501: init genalloc for local memory") Signed-off-by: Wei Yongjun Acked-by: Alan Stern Link: https://lore.kernel.org/r/20200506135625.106910-1-weiyongjun1@huawei.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ohci-sm501.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers/usb/host') diff --git a/drivers/usb/host/ohci-sm501.c b/drivers/usb/host/ohci-sm501.c index c158cda9e4b9..cff965240327 100644 --- a/drivers/usb/host/ohci-sm501.c +++ b/drivers/usb/host/ohci-sm501.c @@ -157,9 +157,10 @@ static int ohci_hcd_sm501_drv_probe(struct platform_device *pdev) * the call to usb_hcd_setup_local_mem() below does just that. */ - if (usb_hcd_setup_local_mem(hcd, mem->start, - mem->start - mem->parent->start, - resource_size(mem)) < 0) + retval = usb_hcd_setup_local_mem(hcd, mem->start, + mem->start - mem->parent->start, + resource_size(mem)); + if (retval < 0) goto err5; retval = usb_add_hcd(hcd, irq, IRQF_SHARED); if (retval) -- cgit v1.2.3-59-g8ed1b From 1036e760d852f224265c677806089278c77ff5b2 Mon Sep 17 00:00:00 2001 From: Al Cooper Date: Tue, 12 May 2020 11:00:17 -0400 Subject: usb: xhci: xhci-plat: Add support for Broadcom STB SoC's Add support for Broadcom STB SoC's to the xhci platform driver Signed-off-by: Al Cooper Acked-by: Mathias Nyman Reviewed-by: Florian Fainelli Link: https://lore.kernel.org/r/20200512150019.25903-4-alcooperx@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-plat.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'drivers/usb/host') diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c index 1d4f6f85f0fe..44406d0eb317 100644 --- a/drivers/usb/host/xhci-plat.c +++ b/drivers/usb/host/xhci-plat.c @@ -112,6 +112,10 @@ static const struct xhci_plat_priv xhci_plat_renesas_rcar_gen3 = { SET_XHCI_PLAT_PRIV_FOR_RCAR(XHCI_RCAR_FIRMWARE_NAME_V3) }; +static const struct xhci_plat_priv xhci_plat_brcm = { + .quirks = XHCI_RESET_ON_RESUME, +}; + static const struct of_device_id usb_xhci_of_match[] = { { .compatible = "generic-xhci", @@ -147,6 +151,12 @@ static const struct of_device_id usb_xhci_of_match[] = { }, { .compatible = "renesas,rcar-gen3-xhci", .data = &xhci_plat_renesas_rcar_gen3, + }, { + .compatible = "brcm,xhci-brcm-v2", + .data = &xhci_plat_brcm, + }, { + .compatible = "brcm,bcm7445-xhci", + .data = &xhci_plat_brcm, }, {}, }; -- cgit v1.2.3-59-g8ed1b From 9df231511bd64387cd43a85d2955fd8d8ff04e0e Mon Sep 17 00:00:00 2001 From: Al Cooper Date: Tue, 12 May 2020 11:00:18 -0400 Subject: usb: ehci: Add new EHCI driver for Broadcom STB SoC's Add a new EHCI driver for Broadcom STB SoC's. A new EHCI driver was created instead of adding support to the existing ehci platform driver because of the code required to work around bugs in the EHCI controller. The primary workaround is for a bug where the Core violates the SOF interval between the first two SOFs transmitted after resume. This only happens if the resume occurs near the end of a microframe. The fix is to intercept the ehci-hcd request to complete RESUME and align it to the start of the next microframe. Signed-off-by: Al Cooper Reviewed-by: Andy Shevchenko Reviewed-by: Florian Fainelli Acked-by: Alan Stern Link: https://lore.kernel.org/r/20200512150019.25903-5-alcooperx@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-brcm.c | 280 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 280 insertions(+) create mode 100644 drivers/usb/host/ehci-brcm.c (limited to 'drivers/usb/host') diff --git a/drivers/usb/host/ehci-brcm.c b/drivers/usb/host/ehci-brcm.c new file mode 100644 index 000000000000..3e0ebe8cc649 --- /dev/null +++ b/drivers/usb/host/ehci-brcm.c @@ -0,0 +1,280 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (c) 2020, Broadcom */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ehci.h" + +#define hcd_to_ehci_priv(h) ((struct brcm_priv *)hcd_to_ehci(h)->priv) + +struct brcm_priv { + struct clk *clk; +}; + +/* + * ehci_brcm_wait_for_sof + * Wait for start of next microframe, then wait extra delay microseconds + */ +static inline void ehci_brcm_wait_for_sof(struct ehci_hcd *ehci, u32 delay) +{ + u32 frame_idx = ehci_readl(ehci, &ehci->regs->frame_index); + u32 val; + int res; + + /* Wait for next microframe (every 125 usecs) */ + res = readl_relaxed_poll_timeout(&ehci->regs->frame_index, val, + val != frame_idx, 1, 130); + if (res) + ehci_err(ehci, "Error waiting for SOF\n"); + udelay(delay); +} + +/* + * ehci_brcm_hub_control + * The EHCI controller has a bug where it can violate the SOF + * interval between the first two SOF's transmitted after resume + * if the resume occurs near the end of the microframe. This causees + * the controller to detect babble on the suspended port and + * will eventually cause the controller to reset the port. + * The fix is to Intercept the echi-hcd request to complete RESUME and + * align it to the start of the next microframe. + * See SWLINUX-1909 for more details + */ +static int ehci_brcm_hub_control( + struct usb_hcd *hcd, + u16 typeReq, + u16 wValue, + u16 wIndex, + char *buf, + u16 wLength) +{ + struct ehci_hcd *ehci = hcd_to_ehci(hcd); + int ports = HCS_N_PORTS(ehci->hcs_params); + u32 __iomem *status_reg; + unsigned long flags; + int retval, irq_disabled = 0; + + status_reg = &ehci->regs->port_status[(wIndex & 0xff) - 1]; + + /* + * RESUME is cleared when GetPortStatus() is called 20ms after start + * of RESUME + */ + if ((typeReq == GetPortStatus) && + (wIndex && wIndex <= ports) && + ehci->reset_done[wIndex-1] && + time_after_eq(jiffies, ehci->reset_done[wIndex-1]) && + (ehci_readl(ehci, status_reg) & PORT_RESUME)) { + + /* + * to make sure we are not interrupted until RESUME bit + * is cleared, disable interrupts on current CPU + */ + ehci_dbg(ehci, "SOF alignment workaround\n"); + irq_disabled = 1; + local_irq_save(flags); + ehci_brcm_wait_for_sof(ehci, 5); + } + retval = ehci_hub_control(hcd, typeReq, wValue, wIndex, buf, wLength); + if (irq_disabled) + local_irq_restore(flags); + return retval; +} + +static int ehci_brcm_reset(struct usb_hcd *hcd) +{ + struct ehci_hcd *ehci = hcd_to_ehci(hcd); + int len; + + ehci->big_endian_mmio = 1; + + ehci->caps = (void __iomem *)hcd->regs; + len = HC_LENGTH(ehci, ehci_readl(ehci, &ehci->caps->hc_capbase)); + ehci->regs = (void __iomem *)(hcd->regs + len); + + /* This fixes the lockup during reboot due to prior interrupts */ + ehci_writel(ehci, CMD_RESET, &ehci->regs->command); + mdelay(10); + + /* + * SWLINUX-1705: Avoid OUT packet underflows during high memory + * bus usage + * port_status[0x0f] = Broadcom-proprietary USB_EHCI_INSNREG00 @ 0x90 + */ + ehci_writel(ehci, 0x00800040, &ehci->regs->port_status[0x10]); + ehci_writel(ehci, 0x00000001, &ehci->regs->port_status[0x12]); + + return ehci_setup(hcd); +} + +static struct hc_driver __read_mostly ehci_brcm_hc_driver; + +static const struct ehci_driver_overrides brcm_overrides __initconst = { + .reset = ehci_brcm_reset, + .extra_priv_size = sizeof(struct brcm_priv), +}; + +static int ehci_brcm_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct resource *res_mem; + struct brcm_priv *priv; + struct usb_hcd *hcd; + int irq; + int err; + + err = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32)); + if (err) + return err; + + irq = platform_get_irq(pdev, 0); + if (irq <= 0) + return irq ? irq : -EINVAL; + + /* Hook the hub control routine to work around a bug */ + ehci_brcm_hc_driver.hub_control = ehci_brcm_hub_control; + + /* initialize hcd */ + hcd = usb_create_hcd(&ehci_brcm_hc_driver, dev, dev_name(dev)); + if (!hcd) + return -ENOMEM; + + platform_set_drvdata(pdev, hcd); + priv = hcd_to_ehci_priv(hcd); + + priv->clk = devm_clk_get_optional(dev, NULL); + if (IS_ERR(priv->clk)) { + err = PTR_ERR(priv->clk); + goto err_hcd; + } + + err = clk_prepare_enable(priv->clk); + if (err) + goto err_hcd; + + hcd->regs = devm_platform_get_and_ioremap_resource(pdev, 0, &res_mem); + if (IS_ERR(hcd->regs)) { + err = PTR_ERR(hcd->regs); + goto err_clk; + } + hcd->rsrc_start = res_mem->start; + hcd->rsrc_len = resource_size(res_mem); + err = usb_add_hcd(hcd, irq, IRQF_SHARED); + if (err) + goto err_clk; + + device_wakeup_enable(hcd->self.controller); + device_enable_async_suspend(hcd->self.controller); + + return 0; + +err_clk: + clk_disable_unprepare(priv->clk); +err_hcd: + usb_put_hcd(hcd); + + return err; +} + +static int ehci_brcm_remove(struct platform_device *dev) +{ + struct usb_hcd *hcd = platform_get_drvdata(dev); + struct brcm_priv *priv = hcd_to_ehci_priv(hcd); + + usb_remove_hcd(hcd); + clk_disable_unprepare(priv->clk); + usb_put_hcd(hcd); + return 0; +} + +static int __maybe_unused ehci_brcm_suspend(struct device *dev) +{ + int ret; + struct usb_hcd *hcd = dev_get_drvdata(dev); + struct brcm_priv *priv = hcd_to_ehci_priv(hcd); + bool do_wakeup = device_may_wakeup(dev); + + ret = ehci_suspend(hcd, do_wakeup); + if (ret) + return ret; + clk_disable_unprepare(priv->clk); + return 0; +} + +static int __maybe_unused ehci_brcm_resume(struct device *dev) +{ + struct usb_hcd *hcd = dev_get_drvdata(dev); + struct ehci_hcd *ehci = hcd_to_ehci(hcd); + struct brcm_priv *priv = hcd_to_ehci_priv(hcd); + int err; + + err = clk_prepare_enable(priv->clk); + if (err) + return err; + /* + * SWLINUX-1705: Avoid OUT packet underflows during high memory + * bus usage + * port_status[0x0f] = Broadcom-proprietary USB_EHCI_INSNREG00 + * @ 0x90 + */ + ehci_writel(ehci, 0x00800040, &ehci->regs->port_status[0x10]); + ehci_writel(ehci, 0x00000001, &ehci->regs->port_status[0x12]); + + ehci_resume(hcd, false); + + pm_runtime_disable(dev); + pm_runtime_set_active(dev); + pm_runtime_enable(dev); + + return 0; +} + +static SIMPLE_DEV_PM_OPS(ehci_brcm_pm_ops, ehci_brcm_suspend, + ehci_brcm_resume); + +static const struct of_device_id brcm_ehci_of_match[] = { + { .compatible = "brcm,ehci-brcm-v2", }, + { .compatible = "brcm,bcm7445-ehci", }, + {} +}; + +static struct platform_driver ehci_brcm_driver = { + .probe = ehci_brcm_probe, + .remove = ehci_brcm_remove, + .shutdown = usb_hcd_platform_shutdown, + .driver = { + .name = "ehci-brcm", + .pm = &ehci_brcm_pm_ops, + .of_match_table = brcm_ehci_of_match, + } +}; + +static int __init ehci_brcm_init(void) +{ + if (usb_disabled()) + return -ENODEV; + + ehci_init_driver(&ehci_brcm_hc_driver, &brcm_overrides); + return platform_driver_register(&ehci_brcm_driver); +} +module_init(ehci_brcm_init); + +static void __exit ehci_brcm_exit(void) +{ + platform_driver_unregister(&ehci_brcm_driver); +} +module_exit(ehci_brcm_exit); + +MODULE_ALIAS("platform:ehci-brcm"); +MODULE_DESCRIPTION("EHCI Broadcom STB driver"); +MODULE_AUTHOR("Al Cooper"); +MODULE_LICENSE("GPL"); -- cgit v1.2.3-59-g8ed1b From c33f4f24b888236b725a9972e0fe5ac6575c68ec Mon Sep 17 00:00:00 2001 From: Al Cooper Date: Tue, 12 May 2020 11:00:19 -0400 Subject: usb: host: Add ability to build new Broadcom STB USB drivers Add the build system changes needed to get the Broadcom STB XHCI, EHCI and OHCI functionality working. The OHCI support does not require anything unique to Broadcom so the standard ohci-platform driver is being used. Also update MAINTAINERS. Signed-off-by: Al Cooper Reviewed-by: Florian Fainelli Link: https://lore.kernel.org/r/20200512150019.25903-6-alcooperx@gmail.com Signed-off-by: Greg Kroah-Hartman --- MAINTAINERS | 8 ++++++++ drivers/usb/host/Kconfig | 20 ++++++++++++++++++++ drivers/usb/host/Makefile | 1 + 3 files changed, 29 insertions(+) (limited to 'drivers/usb/host') diff --git a/MAINTAINERS b/MAINTAINERS index e93b7b9deeea..f71212eb845e 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3481,6 +3481,14 @@ S: Supported F: Documentation/devicetree/bindings/i2c/brcm,brcmstb-i2c.yaml F: drivers/i2c/busses/i2c-brcmstb.c +BROADCOM BRCMSTB USB EHCI DRIVER +M: Al Cooper +L: linux-usb@vger.kernel.org +L: bcm-kernel-feedback-list@broadcom.com +S: Maintained +F: Documentation/devicetree/bindings/usb/brcm,bcm7445-ehci.yaml +F: drivers/usb/host/ehci-brcm.* + BROADCOM BRCMSTB USB2 and USB3 PHY DRIVER M: Al Cooper L: linux-kernel@vger.kernel.org diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 55bdfdf11e4c..973386bbb522 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -97,6 +97,26 @@ config USB_XHCI_TEGRA endif # USB_XHCI_HCD +config USB_EHCI_BRCMSTB + tristate + +config USB_BRCMSTB + tristate "Broadcom STB USB support" + depends on (ARCH_BRCMSTB && PHY_BRCM_USB) || COMPILE_TEST + select USB_OHCI_HCD_PLATFORM if USB_OHCI_HCD + select USB_EHCI_BRCMSTB if USB_EHCI_HCD + select USB_XHCI_PLATFORM if USB_XHCI_HCD + help + Enables support for XHCI, EHCI and OHCI host controllers + found in Broadcom STB SoC's. + + To compile these drivers as modules, choose M here: the + modules will be called ohci-platform.ko, ehci-brcm.ko and + xhci-plat-hcd.ko + + Disabling this will keep the controllers and corresponding + PHYs powered down. + config USB_EHCI_HCD tristate "EHCI HCD (USB 2.0) support" depends on HAS_DMA && HAS_IOMEM diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile index b191361257cc..8782956e89ae 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile @@ -49,6 +49,7 @@ obj-$(CONFIG_USB_EHCI_HCD_STI) += ehci-st.o obj-$(CONFIG_USB_EHCI_EXYNOS) += ehci-exynos.o obj-$(CONFIG_USB_EHCI_HCD_AT91) += ehci-atmel.o obj-$(CONFIG_USB_EHCI_TEGRA) += ehci-tegra.o +obj-$(CONFIG_USB_EHCI_BRCMSTB) += ehci-brcm.o obj-$(CONFIG_USB_OXU210HP_HCD) += oxu210hp-hcd.o obj-$(CONFIG_USB_ISP116X_HCD) += isp116x-hcd.o -- cgit v1.2.3-59-g8ed1b From ff4c65ca48f08f4781accfb1d224acd7c897070e Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Thu, 14 May 2020 17:50:36 +0530 Subject: usb: hci: add hc_driver as argument for usb_hcd_pci_probe usb_hcd_pci_probe expects users to call this with driver_data set as hc_driver, that limits the possibility of using the driver_data for driver data. Add hc_driver as argument to usb_hcd_pci_probe and modify the callers ehci/ohci/xhci/uhci to pass hc_driver as argument and freeup the driver_data used Tested xhci driver on Dragon-board RB3, compile tested ehci, ohci and uhci. [For all but the xHCI parts] [For the xhci part] Suggested-by: Mathias Nyman Acked-by: Alan Stern Acked-by: Mathias Nyman Signed-off-by: Vinod Koul Link: https://lore.kernel.org/r/20200514122039.300417-2-vkoul@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hcd-pci.c | 7 ++++--- drivers/usb/host/ehci-pci.c | 6 ++---- drivers/usb/host/ohci-pci.c | 9 ++++++--- drivers/usb/host/uhci-pci.c | 8 ++++++-- drivers/usb/host/xhci-pci.c | 14 +++++--------- include/linux/usb/hcd.h | 3 ++- 6 files changed, 25 insertions(+), 22 deletions(-) (limited to 'drivers/usb/host') diff --git a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c index f0a259937da8..1547aa6e5314 100644 --- a/drivers/usb/core/hcd-pci.c +++ b/drivers/usb/core/hcd-pci.c @@ -159,6 +159,7 @@ static void ehci_wait_for_companions(struct pci_dev *pdev, struct usb_hcd *hcd, * usb_hcd_pci_probe - initialize PCI-based HCDs * @dev: USB Host Controller being probed * @id: pci hotplug id connecting controller to HCD framework + * @driver: USB HC driver handle * Context: !in_interrupt() * * Allocates basic PCI resources for this USB host controller, and @@ -169,9 +170,9 @@ static void ehci_wait_for_companions(struct pci_dev *pdev, struct usb_hcd *hcd, * * Return: 0 if successful. */ -int usb_hcd_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) +int usb_hcd_pci_probe(struct pci_dev *dev, const struct pci_device_id *id, + const struct hc_driver *driver) { - struct hc_driver *driver; struct usb_hcd *hcd; int retval; int hcd_irq = 0; @@ -181,7 +182,7 @@ int usb_hcd_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) if (!id) return -EINVAL; - driver = (struct hc_driver *)id->driver_data; + if (!driver) return -EINVAL; diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c index 1a48ab1bd3b2..3c3820ad9092 100644 --- a/drivers/usb/host/ehci-pci.c +++ b/drivers/usb/host/ehci-pci.c @@ -360,23 +360,21 @@ static int ehci_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) { if (is_bypassed_id(pdev)) return -ENODEV; - return usb_hcd_pci_probe(pdev, id); + return usb_hcd_pci_probe(pdev, id, &ehci_pci_hc_driver); } static void ehci_pci_remove(struct pci_dev *pdev) { pci_clear_mwi(pdev); - usb_hcd_pci_remove(pdev); + usb_hcd_pci_remove(pdev); } /* PCI driver selection metadata; PCI hotplugging uses this */ static const struct pci_device_id pci_ids [] = { { /* handle any USB 2.0 EHCI controller */ PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_EHCI, ~0), - .driver_data = (unsigned long) &ehci_pci_hc_driver, }, { PCI_VDEVICE(STMICRO, PCI_DEVICE_ID_STMICRO_USB_HOST), - .driver_data = (unsigned long) &ehci_pci_hc_driver, }, { /* end: all zeroes */ } }; diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c index 22117a6aeb4a..585222af24ff 100644 --- a/drivers/usb/host/ohci-pci.c +++ b/drivers/usb/host/ohci-pci.c @@ -277,21 +277,24 @@ static const struct ohci_driver_overrides pci_overrides __initconst = { static const struct pci_device_id pci_ids[] = { { /* handle any USB OHCI controller */ PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_OHCI, ~0), - .driver_data = (unsigned long) &ohci_pci_hc_driver, }, { /* The device in the ConneXT I/O hub has no class reg */ PCI_VDEVICE(STMICRO, PCI_DEVICE_ID_STMICRO_USB_OHCI), - .driver_data = (unsigned long) &ohci_pci_hc_driver, }, { /* end: all zeroes */ } }; MODULE_DEVICE_TABLE (pci, pci_ids); +static int ohci_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) +{ + return usb_hcd_pci_probe(dev, id, &ohci_pci_hc_driver); +} + /* pci driver glue; this is a "new style" PCI driver module */ static struct pci_driver ohci_pci_driver = { .name = hcd_name, .id_table = pci_ids, - .probe = usb_hcd_pci_probe, + .probe = ohci_pci_probe, .remove = usb_hcd_pci_remove, .shutdown = usb_hcd_pci_shutdown, diff --git a/drivers/usb/host/uhci-pci.c b/drivers/usb/host/uhci-pci.c index 957c87efc746..9b88745d247f 100644 --- a/drivers/usb/host/uhci-pci.c +++ b/drivers/usb/host/uhci-pci.c @@ -287,17 +287,21 @@ static const struct hc_driver uhci_driver = { static const struct pci_device_id uhci_pci_ids[] = { { /* handle any USB UHCI controller */ PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_UHCI, ~0), - .driver_data = (unsigned long) &uhci_driver, }, { /* end: all zeroes */ } }; MODULE_DEVICE_TABLE(pci, uhci_pci_ids); +static int uhci_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) +{ + return usb_hcd_pci_probe(dev, id, &uhci_driver); +} + static struct pci_driver uhci_pci_driver = { .name = hcd_name, .id_table = uhci_pci_ids, - .probe = usb_hcd_pci_probe, + .probe = uhci_pci_probe, .remove = usb_hcd_pci_remove, .shutdown = uhci_shutdown, diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index 766b74723e64..b6c2f5c530e3 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -327,11 +327,8 @@ static int xhci_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) { int retval; struct xhci_hcd *xhci; - struct hc_driver *driver; struct usb_hcd *hcd; - driver = (struct hc_driver *)id->driver_data; - /* Prevent runtime suspending between USB-2 and USB-3 initialization */ pm_runtime_get_noresume(&dev->dev); @@ -341,7 +338,7 @@ static int xhci_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) * to say USB 2.0, but I'm not sure what the implications would be in * the other parts of the HCD code. */ - retval = usb_hcd_pci_probe(dev, id); + retval = usb_hcd_pci_probe(dev, id, &xhci_pci_hc_driver); if (retval) goto put_runtime_pm; @@ -349,8 +346,8 @@ static int xhci_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) /* USB 2.0 roothub is stored in the PCI device now. */ hcd = dev_get_drvdata(&dev->dev); xhci = hcd_to_xhci(hcd); - xhci->shared_hcd = usb_create_shared_hcd(driver, &dev->dev, - pci_name(dev), hcd); + xhci->shared_hcd = usb_create_shared_hcd(&xhci_pci_hc_driver, &dev->dev, + pci_name(dev), hcd); if (!xhci->shared_hcd) { retval = -ENOMEM; goto dealloc_usb2_hcd; @@ -544,10 +541,9 @@ static void xhci_pci_shutdown(struct usb_hcd *hcd) /*-------------------------------------------------------------------------*/ /* PCI driver selection metadata; PCI hotplugging uses this */ -static const struct pci_device_id pci_ids[] = { { +static const struct pci_device_id pci_ids[] = { /* handle any USB 3.0 xHCI controller */ - PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_XHCI, ~0), - .driver_data = (unsigned long) &xhci_pci_hc_driver, + { PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_XHCI, ~0), }, { /* end: all zeroes */ } }; diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h index e12105ed3834..3dbb42c637c1 100644 --- a/include/linux/usb/hcd.h +++ b/include/linux/usb/hcd.h @@ -479,7 +479,8 @@ extern void usb_hcd_platform_shutdown(struct platform_device *dev); struct pci_dev; struct pci_device_id; extern int usb_hcd_pci_probe(struct pci_dev *dev, - const struct pci_device_id *id); + const struct pci_device_id *id, + const struct hc_driver *driver); extern void usb_hcd_pci_remove(struct pci_dev *dev); extern void usb_hcd_pci_shutdown(struct pci_dev *dev); -- cgit v1.2.3-59-g8ed1b From 8bd5741e3145e40c1e4f422fa5f1b9d7fe0644b3 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Thu, 14 May 2020 17:50:37 +0530 Subject: usb: renesas-xhci: Add the renesas xhci driver This add a new driver for renesas xhci which is basically a firmware loader for uPD720201 and uPD720202 w/o ROM. The xhci-pci driver will invoke this driver for loading/unloading on relevant devices. This patch adds a firmware loader for the uPD720201K8-711-BAC-A and uPD720202K8-711-BAA-A variant. Both of these chips are listed in Renesas' R19UH0078EJ0500 Rev.5.00 "User's Manual: Hardware" as devices which need the firmware loader on page 2 in order to work as they "do not support the External ROM". The "Firmware Download Sequence" is describe in chapter "7.1 FW Download Interface" R19UH0078EJ0500 Rev.5.00 page 131. The firmware "K2013080.mem" is available from a USB3.0 Host to PCIe Adapter (PP2U-E card) "Firmware download" archive. An alternative version can be sourced from Netgear's WNDR4700 GPL archives. The release notes of the PP2U-E's "Firmware Download" ver 2.0.1.3 (2012-06-15) state that the firmware is for the following devices: - uPD720201 ES 2.0 sample whose revision ID is 2. - uPD720201 ES 2.1 sample & CS sample & Mass product, ID is 3. - uPD720202 ES 2.0 sample & CS sample & Mass product, ID is 2. [vkoul: fixed comments: used macros for timeout count and delay removed renesas_fw_alive_check cleaned renesas_fw_callback removed recursion for renesas_fw_download add register defines and field names move to a separate file make fw loader as sync probe so that we execute in probe and prevent race make xhci-pci-renesas a seprate module] Signed-off-by: Christian Lamparter Signed-off-by: Bjorn Andersson Signed-off-by: Vinod Koul Link: https://lore.kernel.org/r/20200514122039.300417-3-vkoul@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/Kconfig | 9 + drivers/usb/host/Makefile | 1 + drivers/usb/host/xhci-pci-renesas.c | 365 ++++++++++++++++++++++++++++++++++++ drivers/usb/host/xhci-pci.h | 28 +++ 4 files changed, 403 insertions(+) create mode 100644 drivers/usb/host/xhci-pci-renesas.c create mode 100644 drivers/usb/host/xhci-pci.h (limited to 'drivers/usb/host') diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 973386bbb522..20137be083a8 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -42,6 +42,15 @@ config USB_XHCI_PCI depends on USB_PCI default y +config USB_XHCI_PCI_RENESAS + tristate "Support for additional Renesas xHCI controller with firwmare" + depends on USB_XHCI_PCI + ---help--- + Say 'Y' to enable the support for the Renesas xHCI controller with + firwmare. Make sure you have the firwmare for the device and + installed on your system for this device to work. + If unsure, say 'N'. + config USB_XHCI_PLATFORM tristate "Generic xHCI driver for a platform device" select USB_XHCI_RCAR if ARCH_RENESAS diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile index 8782956e89ae..bc731332fed9 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile @@ -72,6 +72,7 @@ obj-$(CONFIG_USB_UHCI_HCD) += uhci-hcd.o obj-$(CONFIG_USB_FHCI_HCD) += fhci.o obj-$(CONFIG_USB_XHCI_HCD) += xhci-hcd.o obj-$(CONFIG_USB_XHCI_PCI) += xhci-pci.o +obj-$(CONFIG_USB_XHCI_PCI_RENESAS) += xhci-pci-renesas.o obj-$(CONFIG_USB_XHCI_PLATFORM) += xhci-plat-hcd.o obj-$(CONFIG_USB_XHCI_HISTB) += xhci-histb.o obj-$(CONFIG_USB_XHCI_MTK) += xhci-mtk.o diff --git a/drivers/usb/host/xhci-pci-renesas.c b/drivers/usb/host/xhci-pci-renesas.c new file mode 100644 index 000000000000..88341d79b651 --- /dev/null +++ b/drivers/usb/host/xhci-pci-renesas.c @@ -0,0 +1,365 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (C) 2019-2020 Linaro Limited */ + +#include +#include +#include +#include +#include +#include + +#include "xhci.h" +#include "xhci-trace.h" +#include "xhci-pci.h" + +#define RENESAS_FW_VERSION 0x6C +#define RENESAS_ROM_CONFIG 0xF0 +#define RENESAS_FW_STATUS 0xF4 +#define RENESAS_FW_STATUS_MSB 0xF5 +#define RENESAS_ROM_STATUS 0xF6 +#define RENESAS_ROM_STATUS_MSB 0xF7 +#define RENESAS_DATA0 0xF8 +#define RENESAS_DATA1 0xFC + +#define RENESAS_FW_VERSION_FIELD GENMASK(23, 7) +#define RENESAS_FW_VERSION_OFFSET 8 + +#define RENESAS_FW_STATUS_DOWNLOAD_ENABLE BIT(0) +#define RENESAS_FW_STATUS_LOCK BIT(1) +#define RENESAS_FW_STATUS_RESULT GENMASK(6, 4) + #define RENESAS_FW_STATUS_INVALID 0 + #define RENESAS_FW_STATUS_SUCCESS BIT(4) + #define RENESAS_FW_STATUS_ERROR BIT(5) +#define RENESAS_FW_STATUS_SET_DATA0 BIT(8) +#define RENESAS_FW_STATUS_SET_DATA1 BIT(9) + +#define RENESAS_ROM_STATUS_ACCESS BIT(0) +#define RENESAS_ROM_STATUS_ERASE BIT(1) +#define RENESAS_ROM_STATUS_RELOAD BIT(2) +#define RENESAS_ROM_STATUS_RESULT GENMASK(6, 4) + #define RENESAS_ROM_STATUS_NO_RESULT 0 + #define RENESAS_ROM_STATUS_SUCCESS BIT(4) + #define RENESAS_ROM_STATUS_ERROR BIT(5) +#define RENESAS_ROM_STATUS_SET_DATA0 BIT(8) +#define RENESAS_ROM_STATUS_SET_DATA1 BIT(9) +#define RENESAS_ROM_STATUS_ROM_EXISTS BIT(15) + +#define RENESAS_ROM_ERASE_MAGIC 0x5A65726F +#define RENESAS_ROM_WRITE_MAGIC 0x53524F4D + +#define RENESAS_RETRY 10000 +#define RENESAS_DELAY 10 + +static int renesas_fw_download_image(struct pci_dev *dev, + const u32 *fw, size_t step) +{ + size_t i; + int err; + u8 fw_status; + bool data0_or_data1; + + /* + * The hardware does alternate between two 32-bit pages. + * (This is because each row of the firmware is 8 bytes). + * + * for even steps we use DATA0, for odd steps DATA1. + */ + data0_or_data1 = (step & 1) == 1; + + /* step+1. Read "Set DATAX" and confirm it is cleared. */ + for (i = 0; i < RENESAS_RETRY; i++) { + err = pci_read_config_byte(dev, RENESAS_FW_STATUS_MSB, + &fw_status); + if (err) { + dev_err(&dev->dev, "Read Status failed: %d\n", + pcibios_err_to_errno(err)); + return pcibios_err_to_errno(err); + } + if (!(fw_status & BIT(data0_or_data1))) + break; + + udelay(RENESAS_DELAY); + } + if (i == RENESAS_RETRY) { + dev_err(&dev->dev, "Timeout for Set DATAX step: %zd\n", step); + return -ETIMEDOUT; + } + + /* + * step+2. Write FW data to "DATAX". + * "LSB is left" => force little endian + */ + err = pci_write_config_dword(dev, data0_or_data1 ? + RENESAS_DATA1 : RENESAS_DATA0, + (__force u32)cpu_to_le32(fw[step])); + if (err) { + dev_err(&dev->dev, "Write to DATAX failed: %d\n", + pcibios_err_to_errno(err)); + return pcibios_err_to_errno(err); + } + + udelay(100); + + /* step+3. Set "Set DATAX". */ + err = pci_write_config_byte(dev, RENESAS_FW_STATUS_MSB, + BIT(data0_or_data1)); + if (err) { + dev_err(&dev->dev, "Write config for DATAX failed: %d\n", + pcibios_err_to_errno(err)); + return pcibios_err_to_errno(err); + } + + return 0; +} + +static int renesas_fw_verify(const void *fw_data, + size_t length) +{ + u16 fw_version_pointer; + u16 fw_version; + + /* + * The Firmware's Data Format is describe in + * "6.3 Data Format" R19UH0078EJ0500 Rev.5.00 page 124 + */ + + /* + * The bootrom chips of the big brother have sizes up to 64k, let's + * assume that's the biggest the firmware can get. + */ + if (length < 0x1000 || length >= 0x10000) { + pr_err("firmware is size %zd is not (4k - 64k).", + length); + return -EINVAL; + } + + /* The First 2 bytes are fixed value (55aa). "LSB on Left" */ + if (get_unaligned_le16(fw_data) != 0x55aa) { + pr_err("no valid firmware header found."); + return -EINVAL; + } + + /* verify the firmware version position and print it. */ + fw_version_pointer = get_unaligned_le16(fw_data + 4); + if (fw_version_pointer + 2 >= length) { + pr_err("fw ver pointer is outside of the firmware image"); + return -EINVAL; + } + + fw_version = get_unaligned_le16(fw_data + fw_version_pointer); + pr_err("got firmware version: %02x.", fw_version); + + return 0; +} + +static int renesas_fw_check_running(struct pci_dev *pdev) +{ + int err; + u8 fw_state; + + /* + * Test if the device is actually needing the firmware. As most + * BIOSes will initialize the device for us. If the device is + * initialized. + */ + err = pci_read_config_byte(pdev, RENESAS_FW_STATUS, &fw_state); + if (err) + return pcibios_err_to_errno(err); + + /* + * Check if "FW Download Lock" is locked. If it is and the FW is + * ready we can simply continue. If the FW is not ready, we have + * to give up. + */ + if (fw_state & RENESAS_FW_STATUS_LOCK) { + dev_dbg(&pdev->dev, "FW Download Lock is engaged."); + + if (fw_state & RENESAS_FW_STATUS_SUCCESS) + return 0; + + dev_err(&pdev->dev, + "FW Download Lock is set and FW is not ready. Giving Up."); + return -EIO; + } + + /* + * Check if "FW Download Enable" is set. If someone (us?) tampered + * with it and it can't be reset, we have to give up too... and + * ask for a forgiveness and a reboot. + */ + if (fw_state & RENESAS_FW_STATUS_DOWNLOAD_ENABLE) { + dev_err(&pdev->dev, + "FW Download Enable is stale. Giving Up (poweroff/reboot needed)."); + return -EIO; + } + + /* Otherwise, Check the "Result Code" Bits (6:4) and act accordingly */ + switch (fw_state & RENESAS_FW_STATUS_RESULT) { + case 0: /* No result yet */ + dev_dbg(&pdev->dev, "FW is not ready/loaded yet."); + + /* tell the caller, that this device needs the firmware. */ + return 1; + + case RENESAS_FW_STATUS_SUCCESS: /* Success, device should be working. */ + dev_dbg(&pdev->dev, "FW is ready."); + return 0; + + case RENESAS_FW_STATUS_ERROR: /* Error State */ + dev_err(&pdev->dev, + "hardware is in an error state. Giving up (poweroff/reboot needed)."); + return -ENODEV; + + default: /* All other states are marked as "Reserved states" */ + dev_err(&pdev->dev, + "hardware is in an invalid state %lx. Giving up (poweroff/reboot needed).", + (fw_state & RENESAS_FW_STATUS_RESULT) >> 4); + return -EINVAL; + } +} + +static int renesas_fw_download(struct pci_dev *pdev, + const struct firmware *fw) +{ + const u32 *fw_data = (const u32 *)fw->data; + size_t i; + int err; + u8 fw_status; + + /* + * For more information and the big picture: please look at the + * "Firmware Download Sequence" in "7.1 FW Download Interface" + * of R19UH0078EJ0500 Rev.5.00 page 131 + */ + + /* + * 0. Set "FW Download Enable" bit in the + * "FW Download Control & Status Register" at 0xF4 + */ + err = pci_write_config_byte(pdev, RENESAS_FW_STATUS, + RENESAS_FW_STATUS_DOWNLOAD_ENABLE); + if (err) + return pcibios_err_to_errno(err); + + /* 1 - 10 follow one step after the other. */ + for (i = 0; i < fw->size / 4; i++) { + err = renesas_fw_download_image(pdev, fw_data, i); + if (err) { + dev_err(&pdev->dev, + "Firmware Download Step %zd failed at position %zd bytes with (%d).", + i, i * 4, err); + return err; + } + } + + /* + * This sequence continues until the last data is written to + * "DATA0" or "DATA1". Naturally, we wait until "SET DATA0/1" + * is cleared by the hardware beforehand. + */ + for (i = 0; i < RENESAS_RETRY; i++) { + err = pci_read_config_byte(pdev, RENESAS_FW_STATUS_MSB, + &fw_status); + if (err) + return pcibios_err_to_errno(err); + if (!(fw_status & (BIT(0) | BIT(1)))) + break; + + udelay(RENESAS_DELAY); + } + if (i == RENESAS_RETRY) + dev_warn(&pdev->dev, "Final Firmware Download step timed out."); + + /* + * 11. After finishing writing the last data of FW, the + * System Software must clear "FW Download Enable" + */ + err = pci_write_config_byte(pdev, RENESAS_FW_STATUS, 0); + if (err) + return pcibios_err_to_errno(err); + + /* 12. Read "Result Code" and confirm it is good. */ + for (i = 0; i < RENESAS_RETRY; i++) { + err = pci_read_config_byte(pdev, RENESAS_FW_STATUS, &fw_status); + if (err) + return pcibios_err_to_errno(err); + if (fw_status & RENESAS_FW_STATUS_SUCCESS) + break; + + udelay(RENESAS_DELAY); + } + if (i == RENESAS_RETRY) { + /* Timed out / Error - let's see if we can fix this */ + err = renesas_fw_check_running(pdev); + switch (err) { + case 0: /* + * we shouldn't end up here. + * maybe it took a little bit longer. + * But all should be well? + */ + break; + + case 1: /* (No result yet! */ + dev_err(&pdev->dev, "FW Load timedout"); + return -ETIMEDOUT; + + default: + return err; + } + } + + return 0; +} + +static int renesas_load_fw(struct pci_dev *pdev, const struct firmware *fw) +{ + int err = 0; + + err = renesas_fw_download(pdev, fw); + if (err) + dev_err(&pdev->dev, "firmware failed to download (%d).", err); + return err; +} + +int renesas_xhci_check_request_fw(struct pci_dev *pdev, + const struct pci_device_id *id) +{ + struct xhci_driver_data *driver_data = + (struct xhci_driver_data *)id->driver_data; + const char *fw_name = driver_data->firmware; + const struct firmware *fw; + int err; + + err = renesas_fw_check_running(pdev); + /* Continue ahead, if the firmware is already running. */ + if (err == 0) + return 0; + + if (err != 1) + return err; + + pci_dev_get(pdev); + err = request_firmware(&fw, fw_name, &pdev->dev); + pci_dev_put(pdev); + if (err) { + dev_err(&pdev->dev, "request_firmware failed: %d\n", err); + return err; + } + + err = renesas_fw_verify(fw->data, fw->size); + if (err) + goto exit; + + err = renesas_load_fw(pdev, fw); +exit: + release_firmware(fw); + return err; +} +EXPORT_SYMBOL_GPL(renesas_xhci_check_request_fw); + +void renesas_xhci_pci_exit(struct pci_dev *dev) +{ +} +EXPORT_SYMBOL_GPL(renesas_xhci_pci_exit); + +MODULE_LICENSE("GPL v2"); diff --git a/drivers/usb/host/xhci-pci.h b/drivers/usb/host/xhci-pci.h new file mode 100644 index 000000000000..4d749556e350 --- /dev/null +++ b/drivers/usb/host/xhci-pci.h @@ -0,0 +1,28 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (C) 2019-2020 Linaro Limited */ + +#ifndef XHCI_PCI_H +#define XHCI_PCI_H + +#if IS_ENABLED(CONFIG_USB_XHCI_PCI_RENESAS) +int renesas_xhci_check_request_fw(struct pci_dev *dev, + const struct pci_device_id *id); +void renesas_xhci_pci_exit(struct pci_dev *dev); + +#else +int renesas_xhci_check_request_fw(struct pci_dev *dev, + const struct pci_device_id *id) +{ + return 0; +} + +void renesas_xhci_pci_exit(struct pci_dev *dev) { }; + +#endif + +struct xhci_driver_data { + u64 quirks; + const char *firmware; +}; + +#endif -- cgit v1.2.3-59-g8ed1b From a66d21d7dba84deeaf3b296c43eafc11094b6f09 Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Thu, 14 May 2020 17:50:38 +0530 Subject: usb: xhci: Add support for Renesas controller with memory Some rensas controller like uPD720201 and uPD720202 need firmware to be loaded. Add these devices in table and invoke renesas firmware loader functions to check and load the firmware into device memory when required. Signed-off-by: Vinod Koul Link: https://lore.kernel.org/r/20200514122039.300417-4-vkoul@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-pci.c | 35 ++++++++++++++++++++++++++++++++++- drivers/usb/host/xhci.h | 1 + 2 files changed, 35 insertions(+), 1 deletion(-) (limited to 'drivers/usb/host') diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index b6c2f5c530e3..ef513c2fb843 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -15,6 +15,7 @@ #include "xhci.h" #include "xhci-trace.h" +#include "xhci-pci.h" #define SSIC_PORT_NUM 2 #define SSIC_PORT_CFG2 0x880c @@ -87,7 +88,16 @@ static int xhci_pci_reinit(struct xhci_hcd *xhci, struct pci_dev *pdev) static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) { - struct pci_dev *pdev = to_pci_dev(dev); + struct pci_dev *pdev = to_pci_dev(dev); + struct xhci_driver_data *driver_data; + const struct pci_device_id *id; + + id = pci_match_id(pdev->driver->id_table, pdev); + + if (id && id->driver_data) { + driver_data = (struct xhci_driver_data *)id->driver_data; + xhci->quirks |= driver_data->quirks; + } /* Look for vendor-specific quirks */ if (pdev->vendor == PCI_VENDOR_ID_FRESCO_LOGIC && @@ -328,6 +338,14 @@ static int xhci_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) int retval; struct xhci_hcd *xhci; struct usb_hcd *hcd; + struct xhci_driver_data *driver_data; + + driver_data = (struct xhci_driver_data *)id->driver_data; + if (driver_data && driver_data->quirks & XHCI_RENESAS_FW_QUIRK) { + retval = renesas_xhci_check_request_fw(dev, id); + if (retval) + return retval; + } /* Prevent runtime suspending between USB-2 and USB-3 initialization */ pm_runtime_get_noresume(&dev->dev); @@ -389,6 +407,9 @@ static void xhci_pci_remove(struct pci_dev *dev) struct xhci_hcd *xhci; xhci = hcd_to_xhci(pci_get_drvdata(dev)); + if (xhci->quirks & XHCI_RENESAS_FW_QUIRK) + renesas_xhci_pci_exit(dev); + xhci->xhc_state |= XHCI_STATE_REMOVING; if (xhci->quirks & XHCI_DEFAULT_PM_RUNTIME_ALLOW) @@ -540,14 +561,26 @@ static void xhci_pci_shutdown(struct usb_hcd *hcd) /*-------------------------------------------------------------------------*/ +static const struct xhci_driver_data reneses_data = { + .quirks = XHCI_RENESAS_FW_QUIRK, + .firmware = "renesas_usb_fw.mem", +}; + /* PCI driver selection metadata; PCI hotplugging uses this */ static const struct pci_device_id pci_ids[] = { + { PCI_DEVICE(0x1912, 0x0014), + .driver_data = (unsigned long)&reneses_data, + }, + { PCI_DEVICE(0x1912, 0x0015), + .driver_data = (unsigned long)&reneses_data, + }, /* handle any USB 3.0 xHCI controller */ { PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_XHCI, ~0), }, { /* end: all zeroes */ } }; MODULE_DEVICE_TABLE(pci, pci_ids); +MODULE_FIRMWARE("renesas_usb_fw.mem"); /* pci driver glue; this is a "new style" PCI driver module */ static struct pci_driver xhci_pci_driver = { diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 38fc2fe7a036..2c6c4f8d1ee1 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1873,6 +1873,7 @@ struct xhci_hcd { #define XHCI_DEFAULT_PM_RUNTIME_ALLOW BIT_ULL(33) #define XHCI_RESET_PLL_ON_DISCONNECT BIT_ULL(34) #define XHCI_SNPS_BROKEN_SUSPEND BIT_ULL(35) +#define XHCI_RENESAS_FW_QUIRK BIT_ULL(36) unsigned int num_active_eps; unsigned int limit_active_eps; -- cgit v1.2.3-59-g8ed1b From 2478be82de44bee4346eb1f48d4cfa28cd99d2d0 Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Thu, 14 May 2020 17:50:39 +0530 Subject: usb: renesas-xhci: Add ROM loader for uPD720201 uPD720201 supports ROM and allows software to program the ROM and boot from it. Add support for detecting if ROM is present, if so load the ROM if not programmed earlier. Signed-off-by: Vinod Koul Link: https://lore.kernel.org/r/20200514122039.300417-5-vkoul@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-pci-renesas.c | 294 +++++++++++++++++++++++++++++++++++- 1 file changed, 287 insertions(+), 7 deletions(-) (limited to 'drivers/usb/host') diff --git a/drivers/usb/host/xhci-pci-renesas.c b/drivers/usb/host/xhci-pci-renesas.c index 88341d79b651..f7d2445d30ec 100644 --- a/drivers/usb/host/xhci-pci-renesas.c +++ b/drivers/usb/host/xhci-pci-renesas.c @@ -50,13 +50,33 @@ #define RENESAS_RETRY 10000 #define RENESAS_DELAY 10 +#define ROM_VALID_01 0x2013 +#define ROM_VALID_02 0x2026 + +static int renesas_verify_fw_version(struct pci_dev *pdev, u32 version) +{ + switch (version) { + case ROM_VALID_01: + case ROM_VALID_02: + return 0; + } + dev_err(&pdev->dev, "FW has invalid version :%d\n", version); + return -EINVAL; +} + static int renesas_fw_download_image(struct pci_dev *dev, - const u32 *fw, size_t step) + const u32 *fw, size_t step, bool rom) { size_t i; int err; u8 fw_status; bool data0_or_data1; + u32 status_reg; + + if (rom) + status_reg = RENESAS_ROM_STATUS_MSB; + else + status_reg = RENESAS_FW_STATUS_MSB; /* * The hardware does alternate between two 32-bit pages. @@ -68,8 +88,7 @@ static int renesas_fw_download_image(struct pci_dev *dev, /* step+1. Read "Set DATAX" and confirm it is cleared. */ for (i = 0; i < RENESAS_RETRY; i++) { - err = pci_read_config_byte(dev, RENESAS_FW_STATUS_MSB, - &fw_status); + err = pci_read_config_byte(dev, status_reg, &fw_status); if (err) { dev_err(&dev->dev, "Read Status failed: %d\n", pcibios_err_to_errno(err)); @@ -101,8 +120,7 @@ static int renesas_fw_download_image(struct pci_dev *dev, udelay(100); /* step+3. Set "Set DATAX". */ - err = pci_write_config_byte(dev, RENESAS_FW_STATUS_MSB, - BIT(data0_or_data1)); + err = pci_write_config_byte(dev, status_reg, BIT(data0_or_data1)); if (err) { dev_err(&dev->dev, "Write config for DATAX failed: %d\n", pcibios_err_to_errno(err)); @@ -152,10 +170,84 @@ static int renesas_fw_verify(const void *fw_data, return 0; } -static int renesas_fw_check_running(struct pci_dev *pdev) +static bool renesas_check_rom(struct pci_dev *pdev) +{ + u16 rom_status; + int retval; + + /* Check if external ROM exists */ + retval = pci_read_config_word(pdev, RENESAS_ROM_STATUS, &rom_status); + if (retval) + return false; + + rom_status &= RENESAS_ROM_STATUS_ROM_EXISTS; + if (rom_status) { + dev_dbg(&pdev->dev, "External ROM exists\n"); + return true; /* External ROM exists */ + } + + return false; +} + +static int renesas_check_rom_state(struct pci_dev *pdev) { + u16 rom_state; + u32 version; int err; + + /* check FW version */ + err = pci_read_config_dword(pdev, RENESAS_FW_VERSION, &version); + if (err) + return pcibios_err_to_errno(err); + + version &= RENESAS_FW_VERSION_FIELD; + version = version >> RENESAS_FW_VERSION_OFFSET; + + err = renesas_verify_fw_version(pdev, version); + if (err) + return err; + + /* + * Test if ROM is present and loaded, if so we can skip everything + */ + err = pci_read_config_word(pdev, RENESAS_ROM_STATUS, &rom_state); + if (err) + return pcibios_err_to_errno(err); + + if (rom_state & BIT(15)) { + /* ROM exists */ + dev_dbg(&pdev->dev, "ROM exists\n"); + + /* Check the "Result Code" Bits (6:4) and act accordingly */ + switch (rom_state & RENESAS_ROM_STATUS_RESULT) { + case RENESAS_ROM_STATUS_SUCCESS: + return 0; + + case RENESAS_ROM_STATUS_NO_RESULT: /* No result yet */ + return 0; + + case RENESAS_ROM_STATUS_ERROR: /* Error State */ + default: /* All other states are marked as "Reserved states" */ + dev_err(&pdev->dev, "Invalid ROM.."); + break; + } + } + + return -EIO; +} + +static int renesas_fw_check_running(struct pci_dev *pdev) +{ u8 fw_state; + int err; + + /* Check if device has ROM and loaded, if so skip everything */ + err = renesas_check_rom(pdev); + if (err) { /* we have rom */ + err = renesas_check_rom_state(pdev); + if (!err) + return err; + } /* * Test if the device is actually needing the firmware. As most @@ -243,7 +335,7 @@ static int renesas_fw_download(struct pci_dev *pdev, /* 1 - 10 follow one step after the other. */ for (i = 0; i < fw->size / 4; i++) { - err = renesas_fw_download_image(pdev, fw_data, i); + err = renesas_fw_download_image(pdev, fw_data, i, false); if (err) { dev_err(&pdev->dev, "Firmware Download Step %zd failed at position %zd bytes with (%d).", @@ -311,11 +403,199 @@ static int renesas_fw_download(struct pci_dev *pdev, return 0; } +static void renesas_rom_erase(struct pci_dev *pdev) +{ + int retval, i; + u8 status; + + dev_dbg(&pdev->dev, "Performing ROM Erase...\n"); + retval = pci_write_config_dword(pdev, RENESAS_DATA0, + RENESAS_ROM_ERASE_MAGIC); + if (retval) { + dev_err(&pdev->dev, "ROM erase, magic word write failed: %d\n", + pcibios_err_to_errno(retval)); + return; + } + + retval = pci_read_config_byte(pdev, RENESAS_ROM_STATUS, &status); + if (retval) { + dev_err(&pdev->dev, "ROM status read failed: %d\n", + pcibios_err_to_errno(retval)); + return; + } + status |= RENESAS_ROM_STATUS_ERASE; + retval = pci_write_config_byte(pdev, RENESAS_ROM_STATUS, status); + if (retval) { + dev_err(&pdev->dev, "ROM erase set word write failed\n"); + return; + } + + /* sleep a bit while ROM is erased */ + msleep(20); + + for (i = 0; i < RENESAS_RETRY; i++) { + retval = pci_read_config_byte(pdev, RENESAS_ROM_STATUS, + &status); + status &= RENESAS_ROM_STATUS_ERASE; + if (!status) + break; + + mdelay(RENESAS_DELAY); + } + + if (i == RENESAS_RETRY) + dev_dbg(&pdev->dev, "Chip erase timedout: %x\n", status); + + dev_dbg(&pdev->dev, "ROM Erase... Done success\n"); +} + +static bool renesas_setup_rom(struct pci_dev *pdev, const struct firmware *fw) +{ + const u32 *fw_data = (const u32 *)fw->data; + int err, i; + u8 status; + + /* 2. Write magic word to Data0 */ + err = pci_write_config_dword(pdev, RENESAS_DATA0, + RENESAS_ROM_WRITE_MAGIC); + if (err) + return false; + + /* 3. Set External ROM access */ + err = pci_write_config_byte(pdev, RENESAS_ROM_STATUS, + RENESAS_ROM_STATUS_ACCESS); + if (err) + goto remove_bypass; + + /* 4. Check the result */ + err = pci_read_config_byte(pdev, RENESAS_ROM_STATUS, &status); + if (err) + goto remove_bypass; + status &= GENMASK(6, 4); + if (status) { + dev_err(&pdev->dev, + "setting external rom failed: %x\n", status); + goto remove_bypass; + } + + /* 5 to 16 Write FW to DATA0/1 while checking SetData0/1 */ + for (i = 0; i < fw->size / 4; i++) { + err = renesas_fw_download_image(pdev, fw_data, i, true); + if (err) { + dev_err(&pdev->dev, + "ROM Download Step %d failed at position %d bytes with (%d)\n", + i, i * 4, err); + goto remove_bypass; + } + } + + /* + * wait till DATA0/1 is cleared + */ + for (i = 0; i < RENESAS_RETRY; i++) { + err = pci_read_config_byte(pdev, RENESAS_ROM_STATUS_MSB, + &status); + if (err) + goto remove_bypass; + if (!(status & (BIT(0) | BIT(1)))) + break; + + udelay(RENESAS_DELAY); + } + if (i == RENESAS_RETRY) { + dev_err(&pdev->dev, "Final Firmware ROM Download step timed out\n"); + goto remove_bypass; + } + + /* 17. Remove bypass */ + err = pci_write_config_byte(pdev, RENESAS_ROM_STATUS, 0); + if (err) + return false; + + udelay(10); + + /* 18. check result */ + for (i = 0; i < RENESAS_RETRY; i++) { + err = pci_read_config_byte(pdev, RENESAS_ROM_STATUS, &status); + if (err) { + dev_err(&pdev->dev, "Read ROM status failed:%d\n", + pcibios_err_to_errno(err)); + return false; + } + status &= RENESAS_ROM_STATUS_RESULT; + if (status == RENESAS_ROM_STATUS_SUCCESS) { + dev_dbg(&pdev->dev, "Download ROM success\n"); + break; + } + udelay(RENESAS_DELAY); + } + if (i == RENESAS_RETRY) { /* Timed out */ + dev_err(&pdev->dev, + "Download to external ROM TO: %x\n", status); + return false; + } + + dev_dbg(&pdev->dev, "Download to external ROM succeeded\n"); + + /* Last step set Reload */ + err = pci_write_config_byte(pdev, RENESAS_ROM_STATUS, + RENESAS_ROM_STATUS_RELOAD); + if (err) { + dev_err(&pdev->dev, "Set ROM execute failed: %d\n", + pcibios_err_to_errno(err)); + return false; + } + + /* + * wait till Reload is cleared + */ + for (i = 0; i < RENESAS_RETRY; i++) { + err = pci_read_config_byte(pdev, RENESAS_ROM_STATUS, &status); + if (err) + return false; + if (!(status & RENESAS_ROM_STATUS_RELOAD)) + break; + + udelay(RENESAS_DELAY); + } + if (i == RENESAS_RETRY) { + dev_err(&pdev->dev, "ROM Exec timed out: %x\n", status); + return false; + } + + return true; + +remove_bypass: + pci_write_config_byte(pdev, RENESAS_ROM_STATUS, 0); + return false; +} + static int renesas_load_fw(struct pci_dev *pdev, const struct firmware *fw) { int err = 0; + bool rom; + + /* Check if the device has external ROM */ + rom = renesas_check_rom(pdev); + if (rom) { + /* perform chip erase first */ + renesas_rom_erase(pdev); + + /* lets try loading fw on ROM first */ + rom = renesas_setup_rom(pdev, fw); + if (!rom) { + dev_dbg(&pdev->dev, + "ROM load failed, falling back on FW load\n"); + } else { + dev_dbg(&pdev->dev, + "ROM load success\n"); + goto exit; + } + } err = renesas_fw_download(pdev, fw); + +exit: if (err) dev_err(&pdev->dev, "firmware failed to download (%d).", err); return err; -- cgit v1.2.3-59-g8ed1b From 357abc1d6b832bdb6a7d27ed258f6d2be27d096d Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Sat, 16 May 2020 21:55:16 +0530 Subject: usb: renesas-xhci: include correct header for get_unaligned_le16() get_unaligned_le16() is defined in linux/unaligned/access_ok.h header but it uses symbols which may not be available, leading to build failures on ia64. Using asm/unaligned.h seem to be the right thing and used in other drivers. This fixes below error reported by kbuild test robot In file included from drivers/usb/host/xhci-pci-renesas.c:9: >> include/linux/unaligned/access_ok.h:8:28: error: redefinition of 'get_unaligned_le16' 8 | static __always_inline u16 get_unaligned_le16(const void *p) | ^~~~~~~~~~~~~~~~~~ In file included from arch/ia64/include/asm/unaligned.h:5, from arch/ia64/include/asm/io.h:23, from arch/ia64/include/asm/smp.h:21, from include/linux/smp.h:67, from include/linux/percpu.h:7, from include/linux/arch_topology.h:9, from include/linux/topology.h:30, from include/linux/gfp.h:9, from include/linux/xarray.h:14, from include/linux/radix-tree.h:18, from include/linux/idr.h:15, from include/linux/kernfs.h:13, from include/linux/sysfs.h:16, from include/linux/kobject.h:20, from include/linux/of.h:17, from include/linux/irqdomain.h:35, from include/linux/acpi.h:13, from drivers/usb/host/xhci-pci-renesas.c:4: include/linux/unaligned/le_struct.h:7:19: note: previous definition of 'get_unaligned_le16' was here 7 | static inline u16 get_unaligned_le16(const void *p) | ^~~~~~~~~~~~~~~~~~ In file included from drivers/usb/host/xhci-pci-renesas.c:9: include/linux/unaligned/access_ok.h:13:28: error: redefinition of 'get_unaligned_le32' 13 | static __always_inline u32 get_unaligned_le32(const void *p) | ^~~~~~~~~~~~~~~~~~ In file included from arch/ia64/include/asm/unaligned.h:5, from arch/ia64/include/asm/io.h:23, from arch/ia64/include/asm/smp.h:21, from include/linux/smp.h:67, from include/linux/percpu.h:7, from include/linux/arch_topology.h:9, from include/linux/topology.h:30, from include/linux/gfp.h:9, from include/linux/xarray.h:14, from include/linux/radix-tree.h:18, from include/linux/idr.h:15, from include/linux/kernfs.h:13, from include/linux/sysfs.h:16, from include/linux/kobject.h:20, from include/linux/of.h:17, from include/linux/irqdomain.h:35, from include/linux/acpi.h:13, from drivers/usb/host/xhci-pci-renesas.c:4: include/linux/unaligned/le_struct.h:12:19: note: previous definition of 'get_unaligned_le32' was here Fixes: 8bd5741e3145 ("usb: renesas-xhci: Add the renesas xhci driver") Reported-by: kbuild test robot Signed-off-by: Vinod Koul Link: https://lore.kernel.org/r/20200516162516.385149-1-vkoul@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-pci-renesas.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/usb/host') diff --git a/drivers/usb/host/xhci-pci-renesas.c b/drivers/usb/host/xhci-pci-renesas.c index f7d2445d30ec..59b1965ad0a3 100644 --- a/drivers/usb/host/xhci-pci-renesas.c +++ b/drivers/usb/host/xhci-pci-renesas.c @@ -6,7 +6,7 @@ #include #include #include -#include +#include #include "xhci.h" #include "xhci-trace.h" -- cgit v1.2.3-59-g8ed1b From 1cb3b0095c3d0bb96912bfbbce4fc006d41f367c Mon Sep 17 00:00:00 2001 From: Qais Yousef Date: Mon, 18 May 2020 16:49:29 +0100 Subject: usb/ohci-platform: Fix a warning when hibernating The following warning was observed when attempting to suspend to disk using a USB flash as a swap device. [ 111.779649] ------------[ cut here ]------------ [ 111.788382] URB (____ptrval____) submitted while active [ 111.796646] WARNING: CPU: 3 PID: 365 at drivers/usb/core/urb.c:363 usb_submit_urb+0x3d8/0x590 [ 111.805417] Modules linked in: [ 111.808584] CPU: 3 PID: 365 Comm: kworker/3:2 Not tainted 5.6.0-rc6-00002-gdfd1731f9a3e-dirty #545 [ 111.817796] Hardware name: ARM Juno development board (r2) (DT) [ 111.823896] Workqueue: usb_hub_wq hub_event [ 111.828217] pstate: 60000005 (nZCv daif -PAN -UAO) [ 111.833156] pc : usb_submit_urb+0x3d8/0x590 [ 111.837471] lr : usb_submit_urb+0x3d8/0x590 [ 111.841783] sp : ffff800018de38b0 [ 111.845205] x29: ffff800018de38b0 x28: 0000000000000003 [ 111.850682] x27: ffff000970530b20 x26: ffff8000133fd000 [ 111.856159] x25: ffff8000133fd000 x24: ffff800018de3b38 [ 111.861635] x23: 0000000000000004 x22: 0000000000000c00 [ 111.867112] x21: 0000000000000000 x20: 00000000fffffff0 [ 111.872589] x19: ffff0009704e7a00 x18: ffffffffffffffff [ 111.878065] x17: 00000000a7c8f4bc x16: 000000002af33de8 [ 111.883542] x15: ffff8000133fda88 x14: 0720072007200720 [ 111.889019] x13: 0720072007200720 x12: 0720072007200720 [ 111.894496] x11: 0000000000000000 x10: 00000000a5286134 [ 111.899973] x9 : 0000000000000002 x8 : ffff000970c837a0 [ 111.905449] x7 : 0000000000000000 x6 : ffff800018de3570 [ 111.910926] x5 : 0000000000000001 x4 : 0000000000000003 [ 111.916401] x3 : 0000000000000000 x2 : ffff800013427118 [ 111.921879] x1 : 9d4e965b4b7d7c00 x0 : 0000000000000000 [ 111.927356] Call trace: [ 111.929892] usb_submit_urb+0x3d8/0x590 [ 111.933852] hub_activate+0x108/0x7f0 [ 111.937633] hub_resume+0xac/0x148 [ 111.941149] usb_resume_interface.isra.10+0x60/0x138 [ 111.946265] usb_resume_both+0xe4/0x140 [ 111.950225] usb_runtime_resume+0x24/0x30 [ 111.954365] __rpm_callback+0xdc/0x138 [ 111.958236] rpm_callback+0x34/0x98 [ 111.961841] rpm_resume+0x4a8/0x720 [ 111.965445] rpm_resume+0x50c/0x720 [ 111.969049] __pm_runtime_resume+0x4c/0xb8 [ 111.973276] usb_autopm_get_interface+0x28/0x60 [ 111.977948] hub_event+0x80/0x16d8 [ 111.981466] process_one_work+0x2a4/0x748 [ 111.985604] worker_thread+0x48/0x498 [ 111.989387] kthread+0x13c/0x140 [ 111.992725] ret_from_fork+0x10/0x18 [ 111.996415] irq event stamp: 354 [ 111.999756] hardirqs last enabled at (353): [] console_unlock+0x504/0x5b8 [ 112.008441] hardirqs last disabled at (354): [] do_debug_exception+0x1a8/0x258 [ 112.017479] softirqs last enabled at (350): [] __do_softirq+0x4bc/0x568 [ 112.025984] softirqs last disabled at (343): [] irq_exit+0x144/0x150 [ 112.034129] ---[ end trace dc96030b9cf6c8a3 ]--- The problem was tracked down to a missing call to pm_runtime_set_active() on resume in ohci-platform. Link: https://lore.kernel.org/lkml/20200323143857.db5zphxhq4hz3hmd@e107158-lin.cambridge.arm.com/ Acked-by: Alan Stern Signed-off-by: Qais Yousef CC: Tony Prisk CC: Greg Kroah-Hartman CC: Mathias Nyman CC: Oliver Neukum CC: linux-arm-kernel@lists.infradead.org CC: linux-usb@vger.kernel.org CC: linux-kernel@vger.kernel.org Link: https://lore.kernel.org/r/20200518154931.6144-1-qais.yousef@arm.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ohci-platform.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers/usb/host') diff --git a/drivers/usb/host/ohci-platform.c b/drivers/usb/host/ohci-platform.c index 7addfc2cbadc..4a8456f12a73 100644 --- a/drivers/usb/host/ohci-platform.c +++ b/drivers/usb/host/ohci-platform.c @@ -299,6 +299,11 @@ static int ohci_platform_resume(struct device *dev) } ohci_resume(hcd, false); + + pm_runtime_disable(dev); + pm_runtime_set_active(dev); + pm_runtime_enable(dev); + return 0; } #endif /* CONFIG_PM_SLEEP */ -- cgit v1.2.3-59-g8ed1b From 79112cc3c29f4a8c73a21428fbcbcb0afb005e3e Mon Sep 17 00:00:00 2001 From: Qais Yousef Date: Mon, 18 May 2020 16:49:30 +0100 Subject: usb/xhci-plat: Set PM runtime as active on resume Follow suit of ohci-platform.c and perform pm_runtime_set_active() on resume. ohci-platform.c had a warning reported due to the missing pm_runtime_set_active() [1]. [1] https://lore.kernel.org/lkml/20200323143857.db5zphxhq4hz3hmd@e107158-lin.cambridge.arm.com/ Signed-off-by: Qais Yousef CC: Tony Prisk CC: Greg Kroah-Hartman CC: Mathias Nyman CC: Oliver Neukum CC: linux-arm-kernel@lists.infradead.org CC: linux-usb@vger.kernel.org CC: linux-kernel@vger.kernel.org Link: https://lore.kernel.org/r/20200518154931.6144-2-qais.yousef@arm.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-plat.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'drivers/usb/host') diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c index 38ac6efb2cc2..f6b4089bfc4a 100644 --- a/drivers/usb/host/xhci-plat.c +++ b/drivers/usb/host/xhci-plat.c @@ -419,7 +419,15 @@ static int __maybe_unused xhci_plat_resume(struct device *dev) if (ret) return ret; - return xhci_resume(xhci, 0); + ret = xhci_resume(xhci, 0); + if (ret) + return ret; + + pm_runtime_disable(dev); + pm_runtime_set_active(dev); + pm_runtime_enable(dev); + + return 0; } static int __maybe_unused xhci_plat_runtime_suspend(struct device *dev) -- cgit v1.2.3-59-g8ed1b From 16bdc04cc98ab0c74392ceef2475ecc5e73fcf49 Mon Sep 17 00:00:00 2001 From: Qais Yousef Date: Mon, 18 May 2020 16:49:31 +0100 Subject: usb/ehci-platform: Set PM runtime as active on resume Follow suit of ohci-platform.c and perform pm_runtime_set_active() on resume. ohci-platform.c had a warning reported due to the missing pm_runtime_set_active() [1]. [1] https://lore.kernel.org/lkml/20200323143857.db5zphxhq4hz3hmd@e107158-lin.cambridge.arm.com/ Acked-by: Alan Stern Signed-off-by: Qais Yousef CC: Tony Prisk CC: Greg Kroah-Hartman CC: Mathias Nyman CC: Oliver Neukum CC: linux-arm-kernel@lists.infradead.org CC: linux-usb@vger.kernel.org CC: linux-kernel@vger.kernel.org Link: https://lore.kernel.org/r/20200518154931.6144-3-qais.yousef@arm.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-platform.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/usb/host') diff --git a/drivers/usb/host/ehci-platform.c b/drivers/usb/host/ehci-platform.c index e4fc3f66d43b..e9a49007cce4 100644 --- a/drivers/usb/host/ehci-platform.c +++ b/drivers/usb/host/ehci-platform.c @@ -455,6 +455,10 @@ static int ehci_platform_resume(struct device *dev) ehci_resume(hcd, priv->reset_on_resume); + pm_runtime_disable(dev); + pm_runtime_set_active(dev); + pm_runtime_enable(dev); + if (priv->quirk_poll) quirk_poll_init(priv); -- cgit v1.2.3-59-g8ed1b From df00731cffa0edb454ee0c490696ce0c1745e680 Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Tue, 19 May 2020 10:36:22 +0530 Subject: usb: xhci: fix USB_XHCI_PCI depends The xhci-pci-renesas module exports symbols for xhci-pci to load the RAM/ROM on renesas xhci controllers. We had dependency which works when both the modules are builtin or modules. But if xhci-pci is inbuilt and xhci-pci-renesas in module, we get below linker error: drivers/usb/host/xhci-pci.o: In function `xhci_pci_remove': drivers/usb/host/xhci-pci.c:411: undefined reference to `renesas_xhci_pci_exit' drivers/usb/host/xhci-pci.o: In function `xhci_pci_probe': drivers/usb/host/xhci-pci.c:345: undefined reference to `renesas_xhci_check_request_fw' Fix this by adding USB_XHCI_PCI having depends on USB_XHCI_PCI_RENESAS || !USB_XHCI_PCI_RENESAS so that both can be either inbuilt or modules. Reported-by: Anders Roxell Fixes: a66d21d7dba8 ("usb: xhci: Add support for Renesas controller with memory") Tested-by: Anders Roxell Signed-off-by: Vinod Koul Reviewed-by: Bjorn Andersson Link: https://lore.kernel.org/r/20200519050622.994908-1-vkoul@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/usb/host') diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 20137be083a8..62c348062e48 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -40,11 +40,11 @@ config USB_XHCI_DBGCAP config USB_XHCI_PCI tristate depends on USB_PCI + depends on USB_XHCI_PCI_RENESAS || !USB_XHCI_PCI_RENESAS default y config USB_XHCI_PCI_RENESAS tristate "Support for additional Renesas xHCI controller with firwmare" - depends on USB_XHCI_PCI ---help--- Say 'Y' to enable the support for the Renesas xHCI controller with firwmare. Make sure you have the firwmare for the device and -- cgit v1.2.3-59-g8ed1b From 78ef1b1ea193d1b977864f8c20968fcf4f1dbff4 Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Tue, 19 May 2020 15:00:02 +0530 Subject: usb: xhci: make symbols static MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When renesas module is not built, we get compiler warning on xhci driver with W=1 CC [M] drivers/usb/host/xhci-rcar.o drivers/usb/host/xhci-pci.h:13:5: warning: no previous prototype for ‘renesas_xhci_check_request_fw’ [-Wmissing-prototypes] int renesas_xhci_check_request_fw(struct pci_dev *dev, ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~ drivers/usb/host/xhci-pci.h:19:6: warning: no previous prototype for ‘renesas_xhci_pci_exit’ [-Wmissing-prototypes] void renesas_xhci_pci_exit(struct pci_dev *dev) { }; ^~~~~~~~~~~~~~~~~~~~~ We have defined these symbols when CONFIG_USB_XHCI_PCI_RENESAS is not defined, but missed making then static. Reported-by: kbuild test robot Fixes: 8bd5741e3145 ("usb: renesas-xhci: Add the renesas xhci driver") Signed-off-by: Vinod Koul Link: https://lore.kernel.org/r/20200519093002.1152144-1-vkoul@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-pci.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/usb/host') diff --git a/drivers/usb/host/xhci-pci.h b/drivers/usb/host/xhci-pci.h index 4d749556e350..acd7cf0a1706 100644 --- a/drivers/usb/host/xhci-pci.h +++ b/drivers/usb/host/xhci-pci.h @@ -10,13 +10,13 @@ int renesas_xhci_check_request_fw(struct pci_dev *dev, void renesas_xhci_pci_exit(struct pci_dev *dev); #else -int renesas_xhci_check_request_fw(struct pci_dev *dev, - const struct pci_device_id *id) +static int renesas_xhci_check_request_fw(struct pci_dev *dev, + const struct pci_device_id *id) { return 0; } -void renesas_xhci_pci_exit(struct pci_dev *dev) { }; +static void renesas_xhci_pci_exit(struct pci_dev *dev) { }; #endif -- cgit v1.2.3-59-g8ed1b From a7f40c233a6b0540d28743267560df9cfb571ca9 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Fri, 15 May 2020 17:54:53 +0100 Subject: USB: EHCI: ehci-mv: fix less than zero comparison of an unsigned int The comparison of hcd->irq to less than zero for an error check will never be true because hcd->irq is an unsigned int. Fix this by assigning the int retval to the return of platform_get_irq and checking this for the -ve error condition and assigning hcd->irq to retval. Addresses-Coverity: ("Unsigned compared against 0") Fixes: c856b4b0fdb5 ("USB: EHCI: ehci-mv: fix error handling in mv_ehci_probe()") Signed-off-by: Colin Ian King Link: https://lore.kernel.org/r/20200515165453.104028-1-colin.king@canonical.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-mv.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'drivers/usb/host') diff --git a/drivers/usb/host/ehci-mv.c b/drivers/usb/host/ehci-mv.c index 0d61f43c29dc..cffdc8d01b2a 100644 --- a/drivers/usb/host/ehci-mv.c +++ b/drivers/usb/host/ehci-mv.c @@ -166,11 +166,10 @@ static int mv_ehci_probe(struct platform_device *pdev) hcd->rsrc_len = resource_size(r); hcd->regs = ehci_mv->op_regs; - hcd->irq = platform_get_irq(pdev, 0); - if (hcd->irq < 0) { - retval = hcd->irq; + retval = platform_get_irq(pdev, 0); + if (retval < 0) goto err_disable_clk; - } + hcd->irq = retval; ehci = hcd_to_ehci(hcd); ehci->caps = (struct ehci_caps __iomem *) ehci_mv->cap_regs; -- cgit v1.2.3-59-g8ed1b From d49292025f79693d3348f8e2029a8b4703be0f0a Mon Sep 17 00:00:00 2001 From: Tang Bin Date: Wed, 13 May 2020 21:26:47 +0800 Subject: USB: host: ehci-mxc: Add error handling in ehci_mxc_drv_probe() The function ehci_mxc_drv_probe() does not perform sufficient error checking after executing platform_get_irq(), thus fix it. Fixes: 7e8d5cd93fac ("USB: Add EHCI support for MX27 and MX31 based boards") Signed-off-by: Zhang Shengju Signed-off-by: Tang Bin Reviewed-by: Peter Chen Link: https://lore.kernel.org/r/20200513132647.5456-1-tangbin@cmss.chinamobile.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-mxc.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/usb/host') diff --git a/drivers/usb/host/ehci-mxc.c b/drivers/usb/host/ehci-mxc.c index 09e01397f987..dc2676320527 100644 --- a/drivers/usb/host/ehci-mxc.c +++ b/drivers/usb/host/ehci-mxc.c @@ -50,6 +50,8 @@ static int ehci_mxc_drv_probe(struct platform_device *pdev) } irq = platform_get_irq(pdev, 0); + if (irq < 0) + return irq; hcd = usb_create_hcd(&ehci_mxc_hc_driver, dev, dev_name(dev)); if (!hcd) -- cgit v1.2.3-59-g8ed1b