diff options
Diffstat (limited to 'drivers/usb/host')
129 files changed, 1128 insertions, 1309 deletions
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index fa5692dec832..b80a94e632af 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -45,12 +45,12 @@ config USB_XHCI_PLATFORM If unsure, say N. config USB_XHCI_MTK - tristate "xHCI support for Mediatek MT65xx/MT7621" + tristate "xHCI support for MediaTek SoCs" select MFD_SYSCON depends on (MIPS && SOC_MT7621) || ARCH_MEDIATEK || COMPILE_TEST ---help--- Say 'Y' to enable the support for the xHCI host controller - found in Mediatek MT65xx SoCs. + found in MediaTek SoCs. If unsure, say N. config USB_XHCI_MVEBU @@ -222,18 +222,6 @@ config USB_EHCI_HCD_AT91 Enables support for the on-chip EHCI controller on Atmel chips. -config USB_EHCI_MSM - tristate "Support for Qualcomm QSD/MSM on-chip EHCI USB controller" - depends on ARCH_QCOM - select USB_EHCI_ROOT_HUB_TT - ---help--- - Enables support for the USB Host controller present on the - Qualcomm chipsets. Root Hub has inbuilt TT. - This driver depends on OTG driver for PHY initialization, - clock management, powering up VBUS, and power management. - This driver is not supported on boards like trout which - has an external PHY. - config USB_EHCI_TEGRA tristate "NVIDIA Tegra HCD support" depends on ARCH_TEGRA diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile index cf2691fffcc0..32b036e2ffef 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for USB Host Controller Drivers # @@ -25,6 +26,10 @@ ifneq ($(CONFIG_USB_XHCI_RCAR), ) xhci-plat-hcd-y += xhci-rcar.o endif +ifneq ($(CONFIG_DEBUG_FS),) + xhci-hcd-y += xhci-debugfs.o +endif + obj-$(CONFIG_USB_WHCI_HCD) += whci/ obj-$(CONFIG_USB_PCI) += pci-quirks.o @@ -39,7 +44,6 @@ obj-$(CONFIG_USB_EHCI_HCD_SPEAR) += ehci-spear.o 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_MSM) += ehci-msm.o obj-$(CONFIG_USB_EHCI_TEGRA) += ehci-tegra.o obj-$(CONFIG_USB_W90X900_EHCI) += ehci-w90x900.o diff --git a/drivers/usb/host/bcma-hcd.c b/drivers/usb/host/bcma-hcd.c index 5f425c89faf1..2400a826397a 100644 --- a/drivers/usb/host/bcma-hcd.c +++ b/drivers/usb/host/bcma-hcd.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Broadcom specific Advanced Microcontroller Bus * Broadcom USB-core driver (BCMA bus glue) @@ -16,8 +17,6 @@ * * Derived from the USBcore related parts of Broadcom-SB * Copyright 2005-2011 Broadcom Corporation - * - * Licensed under the GNU/GPL. See COPYING for details. */ #include <linux/bcma/bcma.h> #include <linux/delay.h> diff --git a/drivers/usb/host/ehci-atmel.c b/drivers/usb/host/ehci-atmel.c index 7440722bfbf0..3ba140ceaf52 100644 --- a/drivers/usb/host/ehci-atmel.c +++ b/drivers/usb/host/ehci-atmel.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Driver for EHCI UHP on Atmel chips * @@ -5,10 +6,6 @@ * Nicolas Ferre <nicolas.ferre@atmel.com> * * Based on various ehci-*.c drivers - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file COPYING in the main directory of this archive for - * more details. */ #include <linux/clk.h> @@ -205,7 +202,8 @@ static int __maybe_unused ehci_atmel_drv_resume(struct device *dev) struct atmel_ehci_priv *atmel_ehci = hcd_to_atmel_ehci_priv(hcd); atmel_start_clock(atmel_ehci); - return ehci_resume(hcd, false); + ehci_resume(hcd, false); + return 0; } #ifdef CONFIG_OF diff --git a/drivers/usb/host/ehci-dbg.c b/drivers/usb/host/ehci-dbg.c index cbb9b8e12c3c..19f00424f53e 100644 --- a/drivers/usb/host/ehci-dbg.c +++ b/drivers/usb/host/ehci-dbg.c @@ -1,16 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (c) 2001-2002 by David Brownell - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * */ /* this file is part of ehci-hcd.c */ diff --git a/drivers/usb/host/ehci-exynos.c b/drivers/usb/host/ehci-exynos.c index 26b641100639..d9145a8f35d2 100644 --- a/drivers/usb/host/ehci-exynos.c +++ b/drivers/usb/host/ehci-exynos.c @@ -1,15 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * SAMSUNG EXYNOS USB HOST EHCI Controller * * Copyright (C) 2011 Samsung Electronics Co.Ltd * Author: Jingoo Han <jg1.han@samsung.com> * Author: Joonyoung Shim <jy0922.shim@samsung.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * */ #include <linux/clk.h> diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c index d025cc06dda7..c5094cb88cd5 100644 --- a/drivers/usb/host/ehci-fsl.c +++ b/drivers/usb/host/ehci-fsl.c @@ -1,21 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright 2005-2009 MontaVista Software, Inc. * Copyright 2008,2012,2015 Freescale Semiconductor, Inc. * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * * Ported to 834x by Randy Vinson <rvinson@mvista.com> using code provided * by Hunter Wu. * Power Management support by Dave Liu <daveliu@freescale.com>, diff --git a/drivers/usb/host/ehci-fsl.h b/drivers/usb/host/ehci-fsl.h index 1a8a60a57cf2..cbc422032e50 100644 --- a/drivers/usb/host/ehci-fsl.h +++ b/drivers/usb/host/ehci-fsl.h @@ -1,19 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0+ /* Copyright (C) 2005-2010,2012 Freescale Semiconductor, Inc. * Copyright (c) 2005 MontaVista Software - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef _EHCI_FSL_H #define _EHCI_FSL_H diff --git a/drivers/usb/host/ehci-grlib.c b/drivers/usb/host/ehci-grlib.c index 21650044b09e..656b8c08efc8 100644 --- a/drivers/usb/host/ehci-grlib.c +++ b/drivers/usb/host/ehci-grlib.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Driver for Aeroflex Gaisler GRLIB GRUSBHC EHCI host controller * @@ -9,20 +10,6 @@ * (c) Valentine Barshak <vbarshak@ru.mvista.com> * and in turn based on "ehci-ppc-soc.c" by Stefan Roese <sr@denx.de> * and "ohci-ppc-of.c" by Sylvain Munaut <tnt@246tNt.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include <linux/err.h> diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 6e834b83a104..7f0737449df7 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -1,23 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Enhanced Host Controller Interface (EHCI) driver for USB. * * Maintainer: Alan Stern <stern@rowland.harvard.edu> * * Copyright (c) 2000-2004 by David Brownell - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include <linux/module.h> @@ -1012,7 +999,7 @@ idle_timeout: qh_destroy(ehci, qh); break; } - /* else FALL THROUGH */ + /* fall through */ default: /* caller was supposed to have unlinked any requests; * that's not our job. just leak this memory. diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c index df169c8e7225..facafdf8fb95 100644 --- a/drivers/usb/host/ehci-hub.c +++ b/drivers/usb/host/ehci-hub.c @@ -1,19 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (C) 2001-2004 by David Brownell - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* this file is part of ehci-hcd.c */ diff --git a/drivers/usb/host/ehci-mem.c b/drivers/usb/host/ehci-mem.c index 9b7e63977215..21307d862af6 100644 --- a/drivers/usb/host/ehci-mem.c +++ b/drivers/usb/host/ehci-mem.c @@ -1,19 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (c) 2001 by David Brownell - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* this file is part of ehci-hcd.c */ diff --git a/drivers/usb/host/ehci-msm.c b/drivers/usb/host/ehci-msm.c deleted file mode 100644 index 2f8d3af811ce..000000000000 --- a/drivers/usb/host/ehci-msm.c +++ /dev/null @@ -1,265 +0,0 @@ -/* ehci-msm.c - HSUSB Host Controller Driver Implementation - * - * Copyright (c) 2008-2011, Code Aurora Forum. All rights reserved. - * - * Partly derived from ehci-fsl.c and ehci-hcd.c - * Copyright (c) 2000-2004 by David Brownell - * Copyright (c) 2005 MontaVista Software - * - * All source code in this file is licensed under the following license except - * where indicated. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published - * by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * See the GNU General Public License for more details. - * You should have received a copy of the GNU General Public License - * along with this program; if not, you can find it at http://www.fsf.org - */ - -#include <linux/clk.h> -#include <linux/err.h> -#include <linux/io.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/pm_runtime.h> -#include <linux/usb/otg.h> -#include <linux/usb/msm_hsusb_hw.h> -#include <linux/usb.h> -#include <linux/usb/hcd.h> -#include <linux/acpi.h> - -#include "ehci.h" - -#define MSM_USB_BASE (hcd->regs) - -#define DRIVER_DESC "Qualcomm On-Chip EHCI Host Controller" - -static const char hcd_name[] = "ehci-msm"; -static struct hc_driver __read_mostly msm_hc_driver; - -static int ehci_msm_reset(struct usb_hcd *hcd) -{ - struct ehci_hcd *ehci = hcd_to_ehci(hcd); - int retval; - - ehci->caps = USB_CAPLENGTH; - hcd->has_tt = 1; - - retval = ehci_setup(hcd); - if (retval) - return retval; - - /* select ULPI phy and clear other status/control bits in PORTSC */ - writel(PORTSC_PTS_ULPI, USB_PORTSC); - /* bursts of unspecified length. */ - writel(0, USB_AHBBURST); - /* Use the AHB transactor, allow posted data writes */ - writel(0x8, USB_AHBMODE); - /* Disable streaming mode and select host mode */ - writel(0x13, USB_USBMODE); - /* Disable ULPI_TX_PKT_EN_CLR_FIX which is valid only for HSIC */ - writel(readl(USB_GENCONFIG_2) & ~ULPI_TX_PKT_EN_CLR_FIX, USB_GENCONFIG_2); - - return 0; -} - -static int ehci_msm_probe(struct platform_device *pdev) -{ - struct usb_hcd *hcd; - struct resource *res; - struct usb_phy *phy; - int ret; - - dev_dbg(&pdev->dev, "ehci_msm proble\n"); - - hcd = usb_create_hcd(&msm_hc_driver, &pdev->dev, dev_name(&pdev->dev)); - if (!hcd) { - dev_err(&pdev->dev, "Unable to create HCD\n"); - return -ENOMEM; - } - - ret = platform_get_irq(pdev, 0); - if (ret < 0) { - dev_err(&pdev->dev, "Unable to get IRQ resource\n"); - goto put_hcd; - } - hcd->irq = ret; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(&pdev->dev, "Unable to get memory resource\n"); - ret = -ENODEV; - goto put_hcd; - } - - hcd->rsrc_start = res->start; - hcd->rsrc_len = resource_size(res); - hcd->regs = devm_ioremap(&pdev->dev, hcd->rsrc_start, hcd->rsrc_len); - if (!hcd->regs) { - dev_err(&pdev->dev, "ioremap failed\n"); - ret = -ENOMEM; - goto put_hcd; - } - - /* - * If there is an OTG driver, let it take care of PHY initialization, - * clock management, powering up VBUS, mapping of registers address - * space and power management. - */ - if (pdev->dev.of_node) - phy = devm_usb_get_phy_by_phandle(&pdev->dev, "usb-phy", 0); - else - phy = devm_usb_get_phy(&pdev->dev, USB_PHY_TYPE_USB2); - - if (IS_ERR(phy)) { - if (PTR_ERR(phy) == -EPROBE_DEFER) { - dev_err(&pdev->dev, "unable to find transceiver\n"); - ret = -EPROBE_DEFER; - goto put_hcd; - } - phy = NULL; - } - - hcd->usb_phy = phy; - device_init_wakeup(&pdev->dev, 1); - - if (phy && phy->otg) { - /* - * MSM OTG driver takes care of adding the HCD and - * placing hardware into low power mode via runtime PM. - */ - ret = otg_set_host(phy->otg, &hcd->self); - if (ret < 0) { - dev_err(&pdev->dev, "unable to register with transceiver\n"); - goto put_hcd; - } - - pm_runtime_no_callbacks(&pdev->dev); - pm_runtime_enable(&pdev->dev); - } else { - ret = usb_add_hcd(hcd, hcd->irq, IRQF_SHARED); - if (ret) - goto put_hcd; - } - - return 0; - -put_hcd: - usb_put_hcd(hcd); - - return ret; -} - -static int ehci_msm_remove(struct platform_device *pdev) -{ - struct usb_hcd *hcd = platform_get_drvdata(pdev); - - device_init_wakeup(&pdev->dev, 0); - pm_runtime_disable(&pdev->dev); - pm_runtime_set_suspended(&pdev->dev); - - if (hcd->usb_phy && hcd->usb_phy->otg) - otg_set_host(hcd->usb_phy->otg, NULL); - else - usb_remove_hcd(hcd); - - usb_put_hcd(hcd); - - return 0; -} - -#ifdef CONFIG_PM -static int ehci_msm_pm_suspend(struct device *dev) -{ - struct usb_hcd *hcd = dev_get_drvdata(dev); - struct ehci_hcd *ehci = hcd_to_ehci(hcd); - bool do_wakeup = device_may_wakeup(dev); - - dev_dbg(dev, "ehci-msm PM suspend\n"); - - /* Only call ehci_suspend if ehci_setup has been done */ - if (ehci->sbrn) - return ehci_suspend(hcd, do_wakeup); - - return 0; -} - -static int ehci_msm_pm_resume(struct device *dev) -{ - struct usb_hcd *hcd = dev_get_drvdata(dev); - struct ehci_hcd *ehci = hcd_to_ehci(hcd); - - dev_dbg(dev, "ehci-msm PM resume\n"); - - /* Only call ehci_resume if ehci_setup has been done */ - if (ehci->sbrn) - ehci_resume(hcd, false); - - return 0; -} - -#else -#define ehci_msm_pm_suspend NULL -#define ehci_msm_pm_resume NULL -#endif - -static const struct dev_pm_ops ehci_msm_dev_pm_ops = { - .suspend = ehci_msm_pm_suspend, - .resume = ehci_msm_pm_resume, -}; - -static const struct acpi_device_id msm_ehci_acpi_ids[] = { - { "QCOM8040", 0 }, - { } -}; -MODULE_DEVICE_TABLE(acpi, msm_ehci_acpi_ids); - -static const struct of_device_id msm_ehci_dt_match[] = { - { .compatible = "qcom,ehci-host", }, - {} -}; -MODULE_DEVICE_TABLE(of, msm_ehci_dt_match); - -static struct platform_driver ehci_msm_driver = { - .probe = ehci_msm_probe, - .remove = ehci_msm_remove, - .shutdown = usb_hcd_platform_shutdown, - .driver = { - .name = "msm_hsusb_host", - .pm = &ehci_msm_dev_pm_ops, - .of_match_table = msm_ehci_dt_match, - .acpi_match_table = ACPI_PTR(msm_ehci_acpi_ids), - }, -}; - -static const struct ehci_driver_overrides msm_overrides __initconst = { - .reset = ehci_msm_reset, -}; - -static int __init ehci_msm_init(void) -{ - if (usb_disabled()) - return -ENODEV; - - pr_info("%s: " DRIVER_DESC "\n", hcd_name); - ehci_init_driver(&msm_hc_driver, &msm_overrides); - return platform_driver_register(&ehci_msm_driver); -} -module_init(ehci_msm_init); - -static void __exit ehci_msm_cleanup(void) -{ - platform_driver_unregister(&ehci_msm_driver); -} -module_exit(ehci_msm_cleanup); - -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_ALIAS("platform:msm-ehci"); -MODULE_LICENSE("GPL"); diff --git a/drivers/usb/host/ehci-mv.c b/drivers/usb/host/ehci-mv.c index 849806a75f1c..de764459e05a 100644 --- a/drivers/usb/host/ehci-mv.c +++ b/drivers/usb/host/ehci-mv.c @@ -1,12 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (C) 2011 Marvell International Ltd. All rights reserved. * Author: Chao Xie <chao.xie@marvell.com> * Neil Zhang <zhangwm@marvell.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. */ #include <linux/kernel.h> diff --git a/drivers/usb/host/ehci-mxc.c b/drivers/usb/host/ehci-mxc.c index c7a9b31eeaef..c9f91e6c72b6 100644 --- a/drivers/usb/host/ehci-mxc.c +++ b/drivers/usb/host/ehci-mxc.c @@ -1,20 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (c) 2008 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix * Copyright (c) 2009 Daniel Mack <daniel@caiaq.de> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include <linux/kernel.h> diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c index 4d308533bc83..854b146a457d 100644 --- a/drivers/usb/host/ehci-omap.c +++ b/drivers/usb/host/ehci-omap.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * ehci-omap.c - driver for USBHOST on OMAP3/4 processors * @@ -14,21 +15,6 @@ * Contact: Felipe Balbi <felipe.balbi@nokia.com> * * Based on "ehci-fsl.c" and "ehci-au1xxx.c" ehci glue layers - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * */ #include <linux/kernel.h> diff --git a/drivers/usb/host/ehci-orion.c b/drivers/usb/host/ehci-orion.c index 1aec87ec68df..1ad72647a069 100644 --- a/drivers/usb/host/ehci-orion.c +++ b/drivers/usb/host/ehci-orion.c @@ -1,11 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0 /* * drivers/usb/host/ehci-orion.c * * Tzachi Perelstein <tzachi@marvell.com> - * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. */ #include <linux/kernel.h> diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c index 93326974ff4b..fe9422d3bcdc 100644 --- a/drivers/usb/host/ehci-pci.c +++ b/drivers/usb/host/ehci-pci.c @@ -1,21 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * EHCI HCD (Host Controller Driver) PCI Bus Glue. * * Copyright (c) 2000-2004 by David Brownell - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include <linux/kernel.h> diff --git a/drivers/usb/host/ehci-platform.c b/drivers/usb/host/ehci-platform.c index f1908ea9fbd8..b065a960adc2 100644 --- a/drivers/usb/host/ehci-platform.c +++ b/drivers/usb/host/ehci-platform.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Generic platform ehci driver * @@ -16,8 +17,6 @@ * Copyright 2000-2002 David Brownell * Copyright 1999 Linus Torvalds * Copyright 1999 Gregory P. Smith - * - * Licensed under the GNU/GPL. See COPYING for details. */ #include <linux/acpi.h> #include <linux/clk.h> @@ -40,12 +39,11 @@ #define DRIVER_DESC "EHCI generic platform driver" #define EHCI_MAX_CLKS 4 -#define EHCI_MAX_RSTS 4 #define hcd_to_ehci_priv(h) ((struct ehci_platform_priv *)hcd_to_ehci(h)->priv) struct ehci_platform_priv { struct clk *clks[EHCI_MAX_CLKS]; - struct reset_control *rsts[EHCI_MAX_RSTS]; + struct reset_control *rsts; struct phy **phys; int num_phys; bool reset_on_resume; @@ -151,7 +149,7 @@ static int ehci_platform_probe(struct platform_device *dev) struct usb_ehci_pdata *pdata = dev_get_platdata(&dev->dev); struct ehci_platform_priv *priv; struct ehci_hcd *ehci; - int err, irq, phy_num, clk = 0, rst; + int err, irq, phy_num, clk = 0; if (usb_disabled()) return -ENODEV; @@ -239,22 +237,16 @@ static int ehci_platform_probe(struct platform_device *dev) } } - for (rst = 0; rst < EHCI_MAX_RSTS; rst++) { - priv->rsts[rst] = devm_reset_control_get_shared_by_index( - &dev->dev, rst); - if (IS_ERR(priv->rsts[rst])) { - err = PTR_ERR(priv->rsts[rst]); - if (err == -EPROBE_DEFER) - goto err_reset; - priv->rsts[rst] = NULL; - break; - } - - err = reset_control_deassert(priv->rsts[rst]); - if (err) - goto err_reset; + priv->rsts = devm_reset_control_array_get_optional_shared(&dev->dev); + if (IS_ERR(priv->rsts)) { + err = PTR_ERR(priv->rsts); + goto err_put_clks; } + err = reset_control_deassert(priv->rsts); + if (err) + goto err_put_clks; + if (pdata->big_endian_desc) ehci->big_endian_desc = 1; if (pdata->big_endian_mmio) @@ -310,8 +302,7 @@ err_power: if (pdata->power_off) pdata->power_off(dev); err_reset: - while (--rst >= 0) - reset_control_assert(priv->rsts[rst]); + reset_control_assert(priv->rsts); err_put_clks: while (--clk >= 0) clk_put(priv->clks[clk]); @@ -329,15 +320,14 @@ static int ehci_platform_remove(struct platform_device *dev) struct usb_hcd *hcd = platform_get_drvdata(dev); struct usb_ehci_pdata *pdata = dev_get_platdata(&dev->dev); struct ehci_platform_priv *priv = hcd_to_ehci_priv(hcd); - int clk, rst; + int clk; usb_remove_hcd(hcd); if (pdata->power_off) pdata->power_off(dev); - for (rst = 0; rst < EHCI_MAX_RSTS && priv->rsts[rst]; rst++) - reset_control_assert(priv->rsts[rst]); + reset_control_assert(priv->rsts); for (clk = 0; clk < EHCI_MAX_CLKS && priv->clks[clk]; clk++) clk_put(priv->clks[clk]); diff --git a/drivers/usb/host/ehci-pmcmsp.c b/drivers/usb/host/ehci-pmcmsp.c index 342816a7f8b1..46e160370d6e 100644 --- a/drivers/usb/host/ehci-pmcmsp.c +++ b/drivers/usb/host/ehci-pmcmsp.c @@ -1,12 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0 /* * PMC MSP EHCI (Host Controller Driver) for USB. * * (C) Copyright 2006-2010 PMC-Sierra Inc - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * */ /* includes */ diff --git a/drivers/usb/host/ehci-ppc-of.c b/drivers/usb/host/ehci-ppc-of.c index 1a10c8d542ca..576f7d79ad4e 100644 --- a/drivers/usb/host/ehci-ppc-of.c +++ b/drivers/usb/host/ehci-ppc-of.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-1.0+ /* * EHCI HCD (Host Controller Driver) for USB. * diff --git a/drivers/usb/host/ehci-ps3.c b/drivers/usb/host/ehci-ps3.c index 7934ff9b35e1..8c733492d8fe 100644 --- a/drivers/usb/host/ehci-ps3.c +++ b/drivers/usb/host/ehci-ps3.c @@ -1,21 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0 /* * PS3 EHCI Host Controller driver * * Copyright (C) 2006 Sony Computer Entertainment Inc. * Copyright 2006 Sony Corp. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include <asm/firmware.h> diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c index 8f3f055c05fa..88158324dcae 100644 --- a/drivers/usb/host/ehci-q.c +++ b/drivers/usb/host/ehci-q.c @@ -1,19 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (C) 2001-2004 by David Brownell - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* this file is part of ehci-hcd.c */ diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index 6bc6304672bc..e56db44708bc 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c @@ -1,20 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (c) 2001-2004 by David Brownell * Copyright (c) 2003 Michal Sojka, for high-speed iso transfers - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* this file is part of ehci-hcd.c */ diff --git a/drivers/usb/host/ehci-sh.c b/drivers/usb/host/ehci-sh.c index 5caf88d679e4..a9ee767952c1 100644 --- a/drivers/usb/host/ehci-sh.c +++ b/drivers/usb/host/ehci-sh.c @@ -1,13 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0 /* * SuperH EHCI host controller driver * * Copyright (C) 2010 Paul Mundt * * Based on ohci-sh.c and ehci-atmel.c. - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. */ #include <linux/platform_device.h> #include <linux/clk.h> diff --git a/drivers/usb/host/ehci-spear.c b/drivers/usb/host/ehci-spear.c index 1f25c7985f5b..add796c78561 100644 --- a/drivers/usb/host/ehci-spear.c +++ b/drivers/usb/host/ehci-spear.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Driver for EHCI HCD on SPEAr SOC * @@ -5,10 +6,6 @@ * Deepak Sikri <deepak.sikri@st.com> * * Based on various ehci-*.c drivers -* -* This file is subject to the terms and conditions of the GNU General Public -* License. See the file COPYING in the main directory of this archive for -* more details. */ #include <linux/clk.h> diff --git a/drivers/usb/host/ehci-st.c b/drivers/usb/host/ehci-st.c index be4a2788fc58..3c1362ab70be 100644 --- a/drivers/usb/host/ehci-st.c +++ b/drivers/usb/host/ehci-st.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * ST EHCI driver * @@ -6,10 +7,6 @@ * Author: Peter Griffin <peter.griffin@linaro.org> * * Derived from ehci-platform.c - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. */ #include <linux/clk.h> diff --git a/drivers/usb/host/ehci-sysfs.c b/drivers/usb/host/ehci-sysfs.c index 5216f2b09d63..71fb61dd4a87 100644 --- a/drivers/usb/host/ehci-sysfs.c +++ b/drivers/usb/host/ehci-sysfs.c @@ -1,19 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (C) 2007 by Alan Stern - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* this file is part of ehci-hcd.c */ diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c index 9a3d7db5be57..c809f7d2f08f 100644 --- a/drivers/usb/host/ehci-tegra.c +++ b/drivers/usb/host/ehci-tegra.c @@ -1,19 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * EHCI-compliant USB host controller driver for NVIDIA Tegra SoCs * * Copyright (C) 2010 Google, Inc. * Copyright (C) 2009 - 2013 NVIDIA Corporation - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * */ #include <linux/clk.h> diff --git a/drivers/usb/host/ehci-tilegx.c b/drivers/usb/host/ehci-tilegx.c index bdb93b6a356f..610ed437ed2c 100644 --- a/drivers/usb/host/ehci-tilegx.c +++ b/drivers/usb/host/ehci-tilegx.c @@ -1,15 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright 2012 Tilera Corporation. All Rights Reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation, version 2. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or - * NON INFRINGEMENT. See the GNU General Public License for - * more details. */ /* diff --git a/drivers/usb/host/ehci-timer.c b/drivers/usb/host/ehci-timer.c index 0b6cdb723192..4fcebda4b79d 100644 --- a/drivers/usb/host/ehci-timer.c +++ b/drivers/usb/host/ehci-timer.c @@ -1,15 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (C) 2012 by Alan Stern - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. */ /* This file is part of ehci-hcd.c */ diff --git a/drivers/usb/host/ehci-w90x900.c b/drivers/usb/host/ehci-w90x900.c index 63b9d0c67963..6d77ace1697b 100644 --- a/drivers/usb/host/ehci-w90x900.c +++ b/drivers/usb/host/ehci-w90x900.c @@ -1,14 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/driver/usb/host/ehci-w90x900.c * * Copyright (c) 2008 Nuvoton technology corporation. * * Wan ZongShun <mcuos.com@gmail.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation;version 2 of the License. - * */ #include <linux/dma-mapping.h> diff --git a/drivers/usb/host/ehci-xilinx-of.c b/drivers/usb/host/ehci-xilinx-of.c index f54480850bb8..d2a27578e440 100644 --- a/drivers/usb/host/ehci-xilinx-of.c +++ b/drivers/usb/host/ehci-xilinx-of.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * EHCI HCD (Host Controller Driver) for USB. * @@ -8,21 +9,6 @@ * Based on "ehci-ppc-of.c" by Valentine Barshak <vbarshak@ru.mvista.com> * and "ehci-ppc-soc.c" by Stefan Roese <sr@denx.de> * and "ohci-ppc-of.c" by Sylvain Munaut <tnt@246tNt.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * */ #include <linux/err.h> diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index a8e36170d8b8..c8e9a48e1d51 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h @@ -1,19 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (c) 2001-2002 by David Brownell - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __LINUX_EHCI_HCD_H diff --git a/drivers/usb/host/fhci-dbg.c b/drivers/usb/host/fhci-dbg.c index b58e7a60913a..fafa91189e45 100644 --- a/drivers/usb/host/fhci-dbg.c +++ b/drivers/usb/host/fhci-dbg.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Freescale QUICC Engine USB Host Controller Driver * @@ -8,11 +9,6 @@ * Peter Barada <peterb@logicpd.com> * Copyright (c) MontaVista Software, Inc. 2008. * Anton Vorontsov <avorontsov@ru.mvista.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. */ #include <linux/kernel.h> diff --git a/drivers/usb/host/fhci-hcd.c b/drivers/usb/host/fhci-hcd.c index 55a0ae6f2d74..48fe9e6c2465 100644 --- a/drivers/usb/host/fhci-hcd.c +++ b/drivers/usb/host/fhci-hcd.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Freescale QUICC Engine USB Host Controller Driver * @@ -8,11 +9,6 @@ * Peter Barada <peterb@logicpd.com> * Copyright (c) MontaVista Software, Inc. 2008. * Anton Vorontsov <avorontsov@ru.mvista.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. */ #include <linux/module.h> diff --git a/drivers/usb/host/fhci-hub.c b/drivers/usb/host/fhci-hub.c index 60d55eb3de0d..c359dcdb9b13 100644 --- a/drivers/usb/host/fhci-hub.c +++ b/drivers/usb/host/fhci-hub.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Freescale QUICC Engine USB Host Controller Driver * @@ -8,11 +9,6 @@ * Peter Barada <peterb@logicpd.com> * Copyright (c) MontaVista Software, Inc. 2008. * Anton Vorontsov <avorontsov@ru.mvista.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. */ #include <linux/kernel.h> diff --git a/drivers/usb/host/fhci-mem.c b/drivers/usb/host/fhci-mem.c index b0b88f57a5ac..658aedc6adc1 100644 --- a/drivers/usb/host/fhci-mem.c +++ b/drivers/usb/host/fhci-mem.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Freescale QUICC Engine USB Host Controller Driver * @@ -8,11 +9,6 @@ * Peter Barada <peterb@logicpd.com> * Copyright (c) MontaVista Software, Inc. 2008. * Anton Vorontsov <avorontsov@ru.mvista.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. */ #include <linux/kernel.h> diff --git a/drivers/usb/host/fhci-q.c b/drivers/usb/host/fhci-q.c index 03be7494a476..669c240523fe 100644 --- a/drivers/usb/host/fhci-q.c +++ b/drivers/usb/host/fhci-q.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Freescale QUICC Engine USB Host Controller Driver * @@ -8,11 +9,6 @@ * Peter Barada <peterb@logicpd.com> * Copyright (c) MontaVista Software, Inc. 2008. * Anton Vorontsov <avorontsov@ru.mvista.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. */ #include <linux/kernel.h> diff --git a/drivers/usb/host/fhci-sched.c b/drivers/usb/host/fhci-sched.c index 2f162faabbca..3d12cdd5f999 100644 --- a/drivers/usb/host/fhci-sched.c +++ b/drivers/usb/host/fhci-sched.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Freescale QUICC Engine USB Host Controller Driver * @@ -8,11 +9,6 @@ * Peter Barada <peterb@logicpd.com> * Copyright (c) MontaVista Software, Inc. 2008. * Anton Vorontsov <avorontsov@ru.mvista.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. */ #include <linux/kernel.h> diff --git a/drivers/usb/host/fhci-tds.c b/drivers/usb/host/fhci-tds.c index f82ad5df1b0d..3a4e8f616751 100644 --- a/drivers/usb/host/fhci-tds.c +++ b/drivers/usb/host/fhci-tds.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Freescale QUICC Engine USB Host Controller Driver * @@ -8,11 +9,6 @@ * Peter Barada <peterb@logicpd.com> * Copyright (c) MontaVista Software, Inc. 2008. * Anton Vorontsov <avorontsov@ru.mvista.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. */ #include <linux/kernel.h> diff --git a/drivers/usb/host/fhci.h b/drivers/usb/host/fhci.h index 3fc82c1c3c73..e7ec41d62410 100644 --- a/drivers/usb/host/fhci.h +++ b/drivers/usb/host/fhci.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Freescale QUICC Engine USB Host Controller Driver * @@ -8,11 +9,6 @@ * Peter Barada <peterb@logicpd.com> * Copyright (c) MontaVista Software, Inc. 2008. * Anton Vorontsov <avorontsov@ru.mvista.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. */ #ifndef __FHCI_H diff --git a/drivers/usb/host/fotg210-hcd.c b/drivers/usb/host/fotg210-hcd.c index 457cc6525abd..62fc955085a1 100644 --- a/drivers/usb/host/fotg210-hcd.c +++ b/drivers/usb/host/fotg210-hcd.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* Faraday FOTG210 EHCI-like driver * * Copyright (c) 2013 Faraday Technology Corporation @@ -7,20 +8,6 @@ * Po-Yu Chuang <ratbert.chuang@gmail.com> * * Most of code borrowed from the Linux-3.7 EHCI driver - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include <linux/module.h> #include <linux/device.h> @@ -5449,7 +5436,7 @@ idle_timeout: qh_destroy(fotg210, qh); break; } - /* else FALL THROUGH */ + /* fall through */ default: /* caller was supposed to have unlinked any requests; * that's not our job. just leak this memory. diff --git a/drivers/usb/host/fotg210.h b/drivers/usb/host/fotg210.h index b5cfa7aeb277..7fcd785c7bc8 100644 --- a/drivers/usb/host/fotg210.h +++ b/drivers/usb/host/fotg210.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __LINUX_FOTG210_H #define __LINUX_FOTG210_H diff --git a/drivers/usb/host/fsl-mph-dr-of.c b/drivers/usb/host/fsl-mph-dr-of.c index ba557cdba8ef..677f9d592109 100644 --- a/drivers/usb/host/fsl-mph-dr-of.c +++ b/drivers/usb/host/fsl-mph-dr-of.c @@ -1,12 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Setup platform devices needed by the Freescale multi-port host * and/or dual-role USB controller modules based on the description * in flat device tree. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. */ #include <linux/kernel.h> diff --git a/drivers/usb/host/hwa-hc.c b/drivers/usb/host/hwa-hc.c index da3b18038d23..684d6f074c3a 100644 --- a/drivers/usb/host/hwa-hc.c +++ b/drivers/usb/host/hwa-hc.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Host Wire Adapter: * Driver glue, HWA-specific functions, bridges to WAHC and WUSBHC @@ -5,21 +6,6 @@ * Copyright (C) 2005-2006 Intel Corporation * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com> * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version - * 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - * * The HWA driver is a simple layer that forwards requests to the WAHC * (Wire Adater Host Controller) or WUSBHC (Wireless USB Host * Controller) layers. diff --git a/drivers/usb/host/imx21-dbg.c b/drivers/usb/host/imx21-dbg.c index 4f320d050da7..b964f9a51d87 100644 --- a/drivers/usb/host/imx21-dbg.c +++ b/drivers/usb/host/imx21-dbg.c @@ -1,19 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (c) 2009 by Martin Fuzzey - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* this file is part of imx21-hcd.c */ diff --git a/drivers/usb/host/imx21-hcd.c b/drivers/usb/host/imx21-hcd.c index 39ae7fb64b6f..3a8bbfe43a8e 100644 --- a/drivers/usb/host/imx21-hcd.c +++ b/drivers/usb/host/imx21-hcd.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * USB Host Controller Driver for IMX21 * @@ -5,20 +6,6 @@ * Copyright (C) 2009 Martin Fuzzey * Originally written by Jay Monkman <jtm@lopingdog.com> * Ported to 2.6.30, debugged and enhanced by Martin Fuzzey - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ diff --git a/drivers/usb/host/imx21-hcd.h b/drivers/usb/host/imx21-hcd.h index 05122f8a6983..7b9cf0a38d6e 100644 --- a/drivers/usb/host/imx21-hcd.h +++ b/drivers/usb/host/imx21-hcd.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Macros and prototypes for i.MX21 * @@ -5,20 +6,6 @@ * Copyright (C) 2009 Martin Fuzzey * Originally written by Jay Monkman <jtm@lopingdog.com> * Ported to 2.6.30, debugged and enhanced by Martin Fuzzey - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __LINUX_IMX21_HCD_H__ diff --git a/drivers/usb/host/isp116x-hcd.c b/drivers/usb/host/isp116x-hcd.c index 73fec38754f9..5f9234b9cf7b 100644 --- a/drivers/usb/host/isp116x-hcd.c +++ b/drivers/usb/host/isp116x-hcd.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * ISP116x HCD (Host Controller Driver) for USB. * @@ -1018,6 +1019,7 @@ static int isp116x_hub_control(struct usb_hcd *hcd, spin_lock_irqsave(&isp116x->lock, flags); isp116x_write_reg32(isp116x, HCRHSTATUS, RH_HS_OCIC); spin_unlock_irqrestore(&isp116x->lock, flags); + /* fall through */ case C_HUB_LOCAL_POWER: DBG("C_HUB_LOCAL_POWER\n"); break; @@ -1433,8 +1435,10 @@ static int isp116x_bus_suspend(struct usb_hcd *hcd) isp116x_write_reg32(isp116x, HCCONTROL, (val & ~HCCONTROL_HCFS) | HCCONTROL_USB_RESET); + /* fall through */ case HCCONTROL_USB_RESET: ret = -EBUSY; + /* fall through */ default: /* HCCONTROL_USB_SUSPEND */ spin_unlock_irqrestore(&isp116x->lock, flags); break; diff --git a/drivers/usb/host/isp116x.h b/drivers/usb/host/isp116x.h index dd34b7a33965..a5e929c10d53 100644 --- a/drivers/usb/host/isp116x.h +++ b/drivers/usb/host/isp116x.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * ISP116x register declarations and HCD data structures * diff --git a/drivers/usb/host/isp1362-hcd.c b/drivers/usb/host/isp1362-hcd.c index 9b7e307e2d54..b21c386e6a46 100644 --- a/drivers/usb/host/isp1362-hcd.c +++ b/drivers/usb/host/isp1362-hcd.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * ISP1362 HCD (Host Controller Driver) for USB. * @@ -712,7 +713,7 @@ static inline void enable_istl_transfers(struct isp1362_hcd *isp1362_hcd, int fl static int submit_req(struct isp1362_hcd *isp1362_hcd, struct urb *urb, struct isp1362_ep *ep, struct isp1362_ep_queue *epq) { - int index = epq->free_ptd; + int index; prepare_ptd(isp1362_hcd, urb, ep, epq, 0); index = claim_ptd_buffers(epq, ep, ep->length); @@ -1578,6 +1579,7 @@ static int isp1362_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, spin_lock_irqsave(&isp1362_hcd->lock, flags); isp1362_write_reg32(isp1362_hcd, HCRHSTATUS, RH_HS_OCIC); spin_unlock_irqrestore(&isp1362_hcd->lock, flags); + break; case C_HUB_LOCAL_POWER: DBG(0, "C_HUB_LOCAL_POWER\n"); break; @@ -2251,7 +2253,6 @@ static int isp1362_mem_config(struct usb_hcd *hcd) return -ENOMEM; } - total = istl_size + intl_size + atl_size; spin_lock_irqsave(&isp1362_hcd->lock, flags); for (i = 0; i < 2; i++) { diff --git a/drivers/usb/host/isp1362.h b/drivers/usb/host/isp1362.h index 3b0b4847c3a9..da79e36ced89 100644 --- a/drivers/usb/host/isp1362.h +++ b/drivers/usb/host/isp1362.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * ISP1362 HCD (Host Controller Driver) for USB. * diff --git a/drivers/usb/host/max3421-hcd.c b/drivers/usb/host/max3421-hcd.c index 0ece9a9341e5..afa321ab55fc 100644 --- a/drivers/usb/host/max3421-hcd.c +++ b/drivers/usb/host/max3421-hcd.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * MAX3421 Host Controller driver for USB. * @@ -60,6 +61,7 @@ #include <linux/spi/spi.h> #include <linux/usb.h> #include <linux/usb/hcd.h> +#include <linux/of.h> #include <linux/platform_data/max3421-hcd.h> @@ -85,6 +87,8 @@ USB_PORT_STAT_C_OVERCURRENT | \ USB_PORT_STAT_C_RESET) << 16) +#define MAX3421_GPOUT_COUNT 8 + enum max3421_rh_state { MAX3421_RH_RESET, MAX3421_RH_SUSPENDED, @@ -1672,7 +1676,7 @@ max3421_gpout_set_value(struct usb_hcd *hcd, u8 pin_number, u8 value) u8 mask, idx; --pin_number; - if (pin_number > 7) + if (pin_number >= MAX3421_GPOUT_COUNT) return; mask = 1u << (pin_number % 4); @@ -1696,10 +1700,10 @@ max3421_hub_control(struct usb_hcd *hcd, u16 type_req, u16 value, u16 index, unsigned long flags; int retval = 0; - spin_lock_irqsave(&max3421_hcd->lock, flags); - pdata = spi->dev.platform_data; + spin_lock_irqsave(&max3421_hcd->lock, flags); + switch (type_req) { case ClearHubFeature: break; @@ -1832,10 +1836,34 @@ static const struct hc_driver max3421_hcd_desc = { }; static int +max3421_of_vbus_en_pin(struct device *dev, struct max3421_hcd_platform_data *pdata) +{ + int retval; + uint32_t value[2]; + + if (!pdata) + return -EINVAL; + + retval = of_property_read_u32_array(dev->of_node, "maxim,vbus-en-pin", value, 2); + if (retval) { + dev_err(dev, "device tree node property 'maxim,vbus-en-pin' is missing\n"); + return retval; + } + dev_info(dev, "property 'maxim,vbus-en-pin' value is <%d %d>\n", value[0], value[1]); + + pdata->vbus_gpout = value[0]; + pdata->vbus_active_level = value[1]; + + return 0; +} + +static int max3421_probe(struct spi_device *spi) { + struct device *dev = &spi->dev; struct max3421_hcd *max3421_hcd; struct usb_hcd *hcd = NULL; + struct max3421_hcd_platform_data *pdata = NULL; int retval = -ENOMEM; if (spi_setup(spi) < 0) { @@ -1843,6 +1871,41 @@ max3421_probe(struct spi_device *spi) return -EFAULT; } + if (!spi->irq) { + dev_err(dev, "Failed to get SPI IRQ"); + return -EFAULT; + } + + if (IS_ENABLED(CONFIG_OF) && dev->of_node) { + pdata = devm_kzalloc(&spi->dev, sizeof(*pdata), GFP_KERNEL); + if (!pdata) { + retval = -ENOMEM; + goto error; + } + retval = max3421_of_vbus_en_pin(dev, pdata); + if (retval) + goto error; + + spi->dev.platform_data = pdata; + } + + pdata = spi->dev.platform_data; + if (!pdata) { + dev_err(&spi->dev, "driver configuration data is not provided\n"); + retval = -EFAULT; + goto error; + } + if (pdata->vbus_active_level > 1) { + dev_err(&spi->dev, "vbus active level value %d is out of range (0/1)\n", pdata->vbus_active_level); + retval = -EINVAL; + goto error; + } + if (pdata->vbus_gpout < 1 || pdata->vbus_gpout > MAX3421_GPOUT_COUNT) { + dev_err(&spi->dev, "vbus gpout value %d is out of range (1..8)\n", pdata->vbus_gpout); + retval = -EINVAL; + goto error; + } + hcd = usb_create_hcd(&max3421_hcd_desc, &spi->dev, dev_name(&spi->dev)); if (!hcd) { @@ -1885,6 +1948,11 @@ max3421_probe(struct spi_device *spi) return 0; error: + if (IS_ENABLED(CONFIG_OF) && dev->of_node && pdata) { + devm_kfree(&spi->dev, pdata); + spi->dev.platform_data = NULL; + } + if (hcd) { kfree(max3421_hcd->tx); kfree(max3421_hcd->rx); @@ -1929,11 +1997,18 @@ max3421_remove(struct spi_device *spi) return 0; } +static const struct of_device_id max3421_of_match_table[] = { + { .compatible = "maxim,max3421", }, + {}, +}; +MODULE_DEVICE_TABLE(of, max3421_of_match_table); + static struct spi_driver max3421_driver = { .probe = max3421_probe, .remove = max3421_remove, .driver = { .name = "max3421-hcd", + .of_match_table = of_match_ptr(max3421_of_match_table), }, }; diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c index 5302f988e7e6..5ad9e9bdc8ee 100644 --- a/drivers/usb/host/ohci-at91.c +++ b/drivers/usb/host/ohci-at91.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-1.0+ /* * OHCI HCD (Host Controller Driver) for USB. * diff --git a/drivers/usb/host/ohci-da8xx.c b/drivers/usb/host/ohci-da8xx.c index 05da2cb59612..0c507a0cfe1f 100644 --- a/drivers/usb/host/ohci-da8xx.c +++ b/drivers/usb/host/ohci-da8xx.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * OHCI HCD (Host Controller Driver) for USB. * @@ -5,10 +6,6 @@ * * Derived from: ohci-omap.c and ohci-s3c2410.c * Copyright (C) 2008-2009 MontaVista Software, Inc. <source@mvista.com> - * - * This file is licensed under the terms of the GNU General Public License - * version 2. This program is licensed "as is" without any warranty of any - * kind, whether express or implied. */ #include <linux/clk.h> diff --git a/drivers/usb/host/ohci-dbg.c b/drivers/usb/host/ohci-dbg.c index c3eded317495..ac7d4ac34b02 100644 --- a/drivers/usb/host/ohci-dbg.c +++ b/drivers/usb/host/ohci-dbg.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-1.0+ /* * OHCI HCD (Host Controller Driver) for USB. * diff --git a/drivers/usb/host/ohci-exynos.c b/drivers/usb/host/ohci-exynos.c index 6865b919403f..a39fae41bc70 100644 --- a/drivers/usb/host/ohci-exynos.c +++ b/drivers/usb/host/ohci-exynos.c @@ -1,14 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * SAMSUNG EXYNOS USB HOST OHCI Controller * * Copyright (C) 2011 Samsung Electronics Co.Ltd * Author: Jingoo Han <jg1.han@samsung.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * */ #include <linux/clk.h> diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index 44924824fa41..10887e09e9bc 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-1.0+ /* * Open Host Controller Interface (OHCI) driver for USB. * @@ -382,7 +383,7 @@ sanitize: ed_free (ohci, ed); break; } - /* else FALL THROUGH */ + /* fall through */ default: /* caller was supposed to have unlinked any requests; * that's not our job. can't recover; must leak ed. @@ -785,7 +786,7 @@ static void io_watchdog_func(unsigned long _ohci) } /* find the last TD processed by the controller. */ - head = hc32_to_cpu(ohci, ACCESS_ONCE(ed->hwHeadP)) & TD_MASK; + head = hc32_to_cpu(ohci, READ_ONCE(ed->hwHeadP)) & TD_MASK; td_start = td; td_next = list_prepare_entry(td, &ed->td_list, td_list); list_for_each_entry_continue(td_next, &ed->td_list, td_list) { diff --git a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c index 248eb7702463..fb7aaa3b9d06 100644 --- a/drivers/usb/host/ohci-hub.c +++ b/drivers/usb/host/ohci-hub.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-1.0+ /* * OHCI HCD (Host Controller Driver) for USB. * diff --git a/drivers/usb/host/ohci-mem.c b/drivers/usb/host/ohci-mem.c index ed8a762b8670..b3da3f12e5b1 100644 --- a/drivers/usb/host/ohci-mem.c +++ b/drivers/usb/host/ohci-mem.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-1.0+ /* * OHCI HCD (Host Controller Driver) for USB. * diff --git a/drivers/usb/host/ohci-nxp.c b/drivers/usb/host/ohci-nxp.c index 6df8e2ed40fd..f5f532601092 100644 --- a/drivers/usb/host/ohci-nxp.c +++ b/drivers/usb/host/ohci-nxp.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * driver for NXP USB Host devices * @@ -13,10 +14,7 @@ * NOTE: This driver does not have suspend/resume functionality * This driver is intended for engineering development purposes only * - * 2005-2006 (c) MontaVista Software, Inc. This file is licensed under - * the terms of the GNU General Public License version 2. This program - * is licensed "as is" without any warranty of any kind, whether express - * or implied. + * 2005-2006 (c) MontaVista Software, Inc. */ #include <linux/clk.h> #include <linux/dma-mapping.h> diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c index 91393ec7d850..0201c49bc4fc 100644 --- a/drivers/usb/host/ohci-omap.c +++ b/drivers/usb/host/ohci-omap.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-1.0+ /* * OHCI HCD (Host Controller Driver) for USB. * diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c index a84aebe9b0a9..fbcd34911025 100644 --- a/drivers/usb/host/ohci-pci.c +++ b/drivers/usb/host/ohci-pci.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-1.0+ /* * OHCI HCD (Host Controller Driver) for USB. * diff --git a/drivers/usb/host/ohci-platform.c b/drivers/usb/host/ohci-platform.c index 61fe2b985070..1e6c954f4b3f 100644 --- a/drivers/usb/host/ohci-platform.c +++ b/drivers/usb/host/ohci-platform.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Generic platform ohci driver * @@ -11,8 +12,6 @@ * Copyright 2000-2002 David Brownell * Copyright 1999 Linus Torvalds * Copyright 1999 Gregory P. Smith - * - * Licensed under the GNU/GPL. See COPYING for details. */ #include <linux/clk.h> @@ -34,12 +33,11 @@ #define DRIVER_DESC "OHCI generic platform driver" #define OHCI_MAX_CLKS 3 -#define OHCI_MAX_RESETS 2 #define hcd_to_ohci_priv(h) ((struct ohci_platform_priv *)hcd_to_ohci(h)->priv) struct ohci_platform_priv { struct clk *clks[OHCI_MAX_CLKS]; - struct reset_control *resets[OHCI_MAX_RESETS]; + struct reset_control *resets; struct phy **phys; int num_phys; }; @@ -119,7 +117,7 @@ static int ohci_platform_probe(struct platform_device *dev) struct usb_ohci_pdata *pdata = dev_get_platdata(&dev->dev); struct ohci_platform_priv *priv; struct ohci_hcd *ohci; - int err, irq, phy_num, clk = 0, rst = 0; + int err, irq, phy_num, clk = 0; if (usb_disabled()) return -ENODEV; @@ -204,21 +202,17 @@ static int ohci_platform_probe(struct platform_device *dev) break; } } - for (rst = 0; rst < OHCI_MAX_RESETS; rst++) { - priv->resets[rst] = - devm_reset_control_get_shared_by_index( - &dev->dev, rst); - if (IS_ERR(priv->resets[rst])) { - err = PTR_ERR(priv->resets[rst]); - if (err == -EPROBE_DEFER) - goto err_reset; - priv->resets[rst] = NULL; - break; - } - err = reset_control_deassert(priv->resets[rst]); - if (err) - goto err_reset; + + priv->resets = devm_reset_control_array_get_optional_shared( + &dev->dev); + if (IS_ERR(priv->resets)) { + err = PTR_ERR(priv->resets); + goto err_put_clks; } + + err = reset_control_deassert(priv->resets); + if (err) + goto err_put_clks; } if (pdata->big_endian_desc) @@ -279,8 +273,7 @@ err_power: pdata->power_off(dev); err_reset: pm_runtime_disable(&dev->dev); - while (--rst >= 0) - reset_control_assert(priv->resets[rst]); + reset_control_assert(priv->resets); err_put_clks: while (--clk >= 0) clk_put(priv->clks[clk]); @@ -298,7 +291,7 @@ static int ohci_platform_remove(struct platform_device *dev) struct usb_hcd *hcd = platform_get_drvdata(dev); struct usb_ohci_pdata *pdata = dev_get_platdata(&dev->dev); struct ohci_platform_priv *priv = hcd_to_ohci_priv(hcd); - int clk, rst; + int clk; pm_runtime_get_sync(&dev->dev); usb_remove_hcd(hcd); @@ -306,8 +299,7 @@ static int ohci_platform_remove(struct platform_device *dev) if (pdata->power_off) pdata->power_off(dev); - for (rst = 0; rst < OHCI_MAX_RESETS && priv->resets[rst]; rst++) - reset_control_assert(priv->resets[rst]); + reset_control_assert(priv->resets); for (clk = 0; clk < OHCI_MAX_CLKS && priv->clks[clk]; clk++) clk_put(priv->clks[clk]); diff --git a/drivers/usb/host/ohci-ppc-of.c b/drivers/usb/host/ohci-ppc-of.c index 4f87a5c61b08..76a9b40b08f1 100644 --- a/drivers/usb/host/ohci-ppc-of.c +++ b/drivers/usb/host/ohci-ppc-of.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-1.0+ /* * OHCI HCD (Host Controller Driver) for USB. * diff --git a/drivers/usb/host/ohci-ps3.c b/drivers/usb/host/ohci-ps3.c index 71d8bc4c27f6..20a23d795adf 100644 --- a/drivers/usb/host/ohci-ps3.c +++ b/drivers/usb/host/ohci-ps3.c @@ -1,21 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0 /* * PS3 OHCI Host Controller driver * * Copyright (C) 2006 Sony Computer Entertainment Inc. * Copyright 2006 Sony Corp. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include <asm/firmware.h> diff --git a/drivers/usb/host/ohci-pxa27x.c b/drivers/usb/host/ohci-pxa27x.c index 21c010ffb03c..3e2474959735 100644 --- a/drivers/usb/host/ohci-pxa27x.c +++ b/drivers/usb/host/ohci-pxa27x.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-1.0+ /* * OHCI HCD (Host Controller Driver) for USB. * diff --git a/drivers/usb/host/ohci-q.c b/drivers/usb/host/ohci-q.c index 641fed609911..b2ec8c399363 100644 --- a/drivers/usb/host/ohci-q.c +++ b/drivers/usb/host/ohci-q.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-1.0+ /* * OHCI HCD (Host Controller Driver) for USB. * diff --git a/drivers/usb/host/ohci-s3c2410.c b/drivers/usb/host/ohci-s3c2410.c index b006b93126f7..4511e27e9da8 100644 --- a/drivers/usb/host/ohci-s3c2410.c +++ b/drivers/usb/host/ohci-s3c2410.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-1.0+ /* * OHCI HCD (Host Controller Driver) for USB. * diff --git a/drivers/usb/host/ohci-sa1111.c b/drivers/usb/host/ohci-sa1111.c index 3a9ea32508df..ebec9a7699e3 100644 --- a/drivers/usb/host/ohci-sa1111.c +++ b/drivers/usb/host/ohci-sa1111.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-1.0+ /* * OHCI HCD (Host Controller Driver) for USB. * @@ -42,7 +43,7 @@ #if 0 static void dump_hci_status(struct usb_hcd *hcd, const char *label) { - unsigned long status = sa1111_readl(hcd->regs + USB_STATUS); + unsigned long status = readl_relaxed(hcd->regs + USB_STATUS); printk(KERN_DEBUG "%s USB_STATUS = { %s%s%s%s%s}\n", label, ((status & USB_STATUS_IRQHCIRMTWKUP) ? "IRQHCIRMTWKUP " : ""), @@ -134,7 +135,7 @@ static int sa1111_start_hc(struct sa1111_dev *dev) * Configure the power sense and control lines. Place the USB * host controller in reset. */ - sa1111_writel(usb_rst | USB_RESET_FORCEIFRESET | USB_RESET_FORCEHCRESET, + writel_relaxed(usb_rst | USB_RESET_FORCEIFRESET | USB_RESET_FORCEHCRESET, dev->mapbase + USB_RESET); /* @@ -144,7 +145,7 @@ static int sa1111_start_hc(struct sa1111_dev *dev) ret = sa1111_enable_device(dev); if (ret == 0) { udelay(11); - sa1111_writel(usb_rst, dev->mapbase + USB_RESET); + writel_relaxed(usb_rst, dev->mapbase + USB_RESET); } return ret; @@ -159,8 +160,8 @@ static void sa1111_stop_hc(struct sa1111_dev *dev) /* * Put the USB host controller into reset. */ - usb_rst = sa1111_readl(dev->mapbase + USB_RESET); - sa1111_writel(usb_rst | USB_RESET_FORCEIFRESET | USB_RESET_FORCEHCRESET, + usb_rst = readl_relaxed(dev->mapbase + USB_RESET); + writel_relaxed(usb_rst | USB_RESET_FORCEIFRESET | USB_RESET_FORCEHCRESET, dev->mapbase + USB_RESET); /* @@ -178,7 +179,7 @@ static void sa1111_stop_hc(struct sa1111_dev *dev) static int ohci_hcd_sa1111_probe(struct sa1111_dev *dev) { struct usb_hcd *hcd; - int ret; + int ret, irq; if (usb_disabled()) return -ENODEV; @@ -196,6 +197,12 @@ static int ohci_hcd_sa1111_probe(struct sa1111_dev *dev) hcd->rsrc_start = dev->res.start; hcd->rsrc_len = resource_size(&dev->res); + irq = sa1111_get_irq(dev, 1); + if (irq <= 0) { + ret = irq ? : -ENXIO; + goto err1; + } + if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { dev_dbg(&dev->dev, "request_mem_region failed\n"); ret = -EBUSY; @@ -208,7 +215,7 @@ static int ohci_hcd_sa1111_probe(struct sa1111_dev *dev) if (ret) goto err2; - ret = usb_add_hcd(hcd, dev->irq[1], 0); + ret = usb_add_hcd(hcd, irq, 0); if (ret == 0) { device_wakeup_enable(hcd->self.controller); return ret; @@ -241,8 +248,9 @@ static int ohci_hcd_sa1111_remove(struct sa1111_dev *dev) return 0; } -static void ohci_hcd_sa1111_shutdown(struct sa1111_dev *dev) +static void ohci_hcd_sa1111_shutdown(struct device *_dev) { + struct sa1111_dev *dev = to_sa1111_device(_dev); struct usb_hcd *hcd = sa1111_get_drvdata(dev); if (test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) { @@ -255,9 +263,9 @@ static struct sa1111_driver ohci_hcd_sa1111_driver = { .drv = { .name = "sa1111-ohci", .owner = THIS_MODULE, + .shutdown = ohci_hcd_sa1111_shutdown, }, .devid = SA1111_DEVID_USB, .probe = ohci_hcd_sa1111_probe, .remove = ohci_hcd_sa1111_remove, - .shutdown = ohci_hcd_sa1111_shutdown, }; diff --git a/drivers/usb/host/ohci-sm501.c b/drivers/usb/host/ohci-sm501.c index d4e0f7cd96fa..c9233cddf9a2 100644 --- a/drivers/usb/host/ohci-sm501.c +++ b/drivers/usb/host/ohci-sm501.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-1.0+ /* * OHCI HCD (Host Controller Driver) for USB. * diff --git a/drivers/usb/host/ohci-spear.c b/drivers/usb/host/ohci-spear.c index 56478ed2f932..69fa04697793 100644 --- a/drivers/usb/host/ohci-spear.c +++ b/drivers/usb/host/ohci-spear.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * OHCI HCD (Host Controller Driver) for USB. * @@ -5,10 +6,6 @@ * Deepak Sikri<deepak.sikri@st.com> * * Based on various ohci-*.c drivers -* -* This file is licensed under the terms of the GNU General Public -* License version 2. This program is licensed "as is" without any -* warranty of any kind, whether express or implied. */ #include <linux/clk.h> diff --git a/drivers/usb/host/ohci-st.c b/drivers/usb/host/ohci-st.c index 02816a1515a1..992807c9850a 100644 --- a/drivers/usb/host/ohci-st.c +++ b/drivers/usb/host/ohci-st.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * ST OHCI driver * @@ -6,10 +7,6 @@ * Author: Peter Griffin <peter.griffin@linaro.org> * * Derived from ohci-platform.c - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. */ #include <linux/clk.h> diff --git a/drivers/usb/host/ohci-tilegx.c b/drivers/usb/host/ohci-tilegx.c index e1b208da460a..d21ca3ce9a30 100644 --- a/drivers/usb/host/ohci-tilegx.c +++ b/drivers/usb/host/ohci-tilegx.c @@ -1,15 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright 2012 Tilera Corporation. All Rights Reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation, version 2. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or - * NON INFRINGEMENT. See the GNU General Public License for - * more details. */ /* diff --git a/drivers/usb/host/ohci-tmio.c b/drivers/usb/host/ohci-tmio.c index 16d081a093bb..a631dbb369d7 100644 --- a/drivers/usb/host/ohci-tmio.c +++ b/drivers/usb/host/ohci-tmio.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * OHCI HCD(Host Controller Driver) for USB. * @@ -18,10 +19,6 @@ * Written from sparse documentation from Toshiba and Sharp's driver * for the 2.4 kernel, * usb-ohci-tc6393.c(C) Copyright 2004 Lineo Solutions, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. */ /*#include <linux/fs.h> diff --git a/drivers/usb/host/ohci.h b/drivers/usb/host/ohci.h index 12742d002d2d..508a803139dd 100644 --- a/drivers/usb/host/ohci.h +++ b/drivers/usb/host/ohci.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-1.0+ /* * OHCI HCD (Host Controller Driver) for USB. * diff --git a/drivers/usb/host/oxu210hp-hcd.c b/drivers/usb/host/oxu210hp-hcd.c index ed20fb34c897..0bf7759aae78 100644 --- a/drivers/usb/host/oxu210hp-hcd.c +++ b/drivers/usb/host/oxu210hp-hcd.c @@ -1,23 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (c) 2008 Rodolfo Giometti <giometti@linux.it> * Copyright (c) 2008 Eurotech S.p.A. <info@eurtech.it> * * This code is *strongly* based on EHCI-HCD code by David Brownell since * the chip is a quasi-EHCI compatible. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include <linux/module.h> @@ -3040,7 +3027,7 @@ idle_timeout: qh_put(qh); break; } - /* else FALL THROUGH */ + /* fall through */ default: nogood: /* caller was supposed to have unlinked any requests; diff --git a/drivers/usb/host/oxu210hp.h b/drivers/usb/host/oxu210hp.h index 1c216ad9aad2..437044147862 100644 --- a/drivers/usb/host/oxu210hp.h +++ b/drivers/usb/host/oxu210hp.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Host interface registers */ diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c index 6dda3623a276..161536717025 100644 --- a/drivers/usb/host/pci-quirks.c +++ b/drivers/usb/host/pci-quirks.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * This file contains code to reset and initialize USB host controllers. * Some of it includes work-arounds for PCI hardware and BIOS quirks. @@ -841,7 +842,7 @@ static void quirk_usb_disable_ehci(struct pci_dev *pdev) ehci_bios_handoff(pdev, op_reg_base, cap, offset); break; case 0: /* Illegal reserved cap, set cap=0 so we exit */ - cap = 0; /* then fallthrough... */ + cap = 0; /* fall through */ default: dev_warn(&pdev->dev, "EHCI: unrecognized capability %02x\n", diff --git a/drivers/usb/host/pci-quirks.h b/drivers/usb/host/pci-quirks.h index 5582cbafecd4..b68dcb5dd0fd 100644 --- a/drivers/usb/host/pci-quirks.h +++ b/drivers/usb/host/pci-quirks.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __LINUX_USB_PCI_QUIRKS_H #define __LINUX_USB_PCI_QUIRKS_H diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c index 5e5fc9d7d533..f3d9ba420a97 100644 --- a/drivers/usb/host/r8a66597-hcd.c +++ b/drivers/usb/host/r8a66597-hcd.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * R8A66597 HCD (Host Controller Driver) * @@ -7,20 +8,6 @@ * Portions Copyright (C) 1999 Roman Weissgaerber * * Author : Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * */ #include <linux/module.h> @@ -1273,7 +1260,7 @@ static void set_td_timer(struct r8a66597 *r8a66597, struct r8a66597_td *td) break; } - mod_timer(&r8a66597->td_timer[td->pipenum], + mod_timer(&r8a66597->timers[td->pipenum].td, jiffies + msecs_to_jiffies(time)); } } @@ -1733,9 +1720,10 @@ static void r8a66597_root_hub_control(struct r8a66597 *r8a66597, int port) } } -static void r8a66597_interval_timer(unsigned long _r8a66597) +static void r8a66597_interval_timer(struct timer_list *t) { - struct r8a66597 *r8a66597 = (struct r8a66597 *)_r8a66597; + struct r8a66597_timers *timers = from_timer(timers, t, interval); + struct r8a66597 *r8a66597 = timers->r8a66597; unsigned long flags; u16 pipenum; struct r8a66597_td *td; @@ -1745,7 +1733,7 @@ static void r8a66597_interval_timer(unsigned long _r8a66597) for (pipenum = 0; pipenum < R8A66597_MAX_NUM_PIPE; pipenum++) { if (!(r8a66597->interval_map & (1 << pipenum))) continue; - if (timer_pending(&r8a66597->interval_timer[pipenum])) + if (timer_pending(&r8a66597->timers[pipenum].interval)) continue; td = r8a66597_get_td(r8a66597, pipenum); @@ -1756,9 +1744,10 @@ static void r8a66597_interval_timer(unsigned long _r8a66597) spin_unlock_irqrestore(&r8a66597->lock, flags); } -static void r8a66597_td_timer(unsigned long _r8a66597) +static void r8a66597_td_timer(struct timer_list *t) { - struct r8a66597 *r8a66597 = (struct r8a66597 *)_r8a66597; + struct r8a66597_timers *timers = from_timer(timers, t, td); + struct r8a66597 *r8a66597 = timers->r8a66597; unsigned long flags; u16 pipenum; struct r8a66597_td *td, *new_td = NULL; @@ -1768,7 +1757,7 @@ static void r8a66597_td_timer(unsigned long _r8a66597) for (pipenum = 0; pipenum < R8A66597_MAX_NUM_PIPE; pipenum++) { if (!(r8a66597->timeout_map & (1 << pipenum))) continue; - if (timer_pending(&r8a66597->td_timer[pipenum])) + if (timer_pending(&r8a66597->timers[pipenum].td)) continue; td = r8a66597_get_td(r8a66597, pipenum); @@ -1942,7 +1931,7 @@ static int r8a66597_urb_enqueue(struct usb_hcd *hcd, if (request) { if (td->pipe->info.timer_interval) { r8a66597->interval_map |= 1 << td->pipenum; - mod_timer(&r8a66597->interval_timer[td->pipenum], + mod_timer(&r8a66597->timers[td->pipenum].interval, jiffies + msecs_to_jiffies( td->pipe->info.timer_interval)); } else { @@ -2495,11 +2484,10 @@ static int r8a66597_probe(struct platform_device *pdev) for (i = 0; i < R8A66597_MAX_NUM_PIPE; i++) { INIT_LIST_HEAD(&r8a66597->pipe_queue[i]); - setup_timer(&r8a66597->td_timer[i], r8a66597_td_timer, - (unsigned long)r8a66597); - setup_timer(&r8a66597->interval_timer[i], - r8a66597_interval_timer, - (unsigned long)r8a66597); + r8a66597->timers[i].r8a66597 = r8a66597; + timer_setup(&r8a66597->timers[i].td, r8a66597_td_timer, 0); + timer_setup(&r8a66597->timers[i].interval, + r8a66597_interval_timer, 0); } INIT_LIST_HEAD(&r8a66597->child_device); diff --git a/drivers/usb/host/r8a66597.h b/drivers/usb/host/r8a66597.h index 672cea307abb..51973a923526 100644 --- a/drivers/usb/host/r8a66597.h +++ b/drivers/usb/host/r8a66597.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * R8A66597 HCD (Host Controller Driver) * @@ -7,20 +8,6 @@ * Portions Copyright (C) 1999 Roman Weissgaerber * * Author : Yoshihiro Shimoda <shimoda.yoshihiro@renesas.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * */ #ifndef __R8A66597_H__ @@ -107,6 +94,14 @@ struct r8a66597_root_hub { struct r8a66597_device *dev; }; +struct r8a66597; + +struct r8a66597_timers { + struct timer_list td; + struct timer_list interval; + struct r8a66597 *r8a66597; +}; + struct r8a66597 { spinlock_t lock; void __iomem *reg; @@ -117,8 +112,7 @@ struct r8a66597 { struct list_head pipe_queue[R8A66597_MAX_NUM_PIPE]; struct timer_list rh_timer; - struct timer_list td_timer[R8A66597_MAX_NUM_PIPE]; - struct timer_list interval_timer[R8A66597_MAX_NUM_PIPE]; + struct r8a66597_timers timers[R8A66597_MAX_NUM_PIPE]; unsigned short address_map; unsigned short timeout_map; diff --git a/drivers/usb/host/sl811-hcd.c b/drivers/usb/host/sl811-hcd.c index 24ad1d6cec25..601fb00603cc 100644 --- a/drivers/usb/host/sl811-hcd.c +++ b/drivers/usb/host/sl811-hcd.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * SL811HS HCD (Host Controller Driver) for USB. * diff --git a/drivers/usb/host/sl811.h b/drivers/usb/host/sl811.h index 1e23ef49bec1..2abe51a5db44 100644 --- a/drivers/usb/host/sl811.h +++ b/drivers/usb/host/sl811.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * SL811HS register declarations and HCD data structures * diff --git a/drivers/usb/host/sl811_cs.c b/drivers/usb/host/sl811_cs.c index 88a9bffe93df..72136373ffab 100644 --- a/drivers/usb/host/sl811_cs.c +++ b/drivers/usb/host/sl811_cs.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * PCMCIA driver for SL811HS (as found in REX-CFU1U) * Filename: sl811_cs.c diff --git a/drivers/usb/host/ssb-hcd.c b/drivers/usb/host/ssb-hcd.c index 62b6b7804c66..016987764afb 100644 --- a/drivers/usb/host/ssb-hcd.c +++ b/drivers/usb/host/ssb-hcd.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Sonics Silicon Backplane * Broadcom USB-core driver (SSB bus glue) @@ -15,8 +16,6 @@ * * Derived from the USBcore related parts of Broadcom-SB * Copyright 2005-2011 Broadcom Corporation - * - * Licensed under the GNU/GPL. See COPYING for details. */ #include <linux/ssb/ssb.h> #include <linux/delay.h> diff --git a/drivers/usb/host/u132-hcd.c b/drivers/usb/host/u132-hcd.c index c38855aed62c..032b8652910a 100644 --- a/drivers/usb/host/u132-hcd.c +++ b/drivers/usb/host/u132-hcd.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Host Controller Driver for the Elan Digital Systems U132 adapter * @@ -7,11 +8,6 @@ * Author and Maintainer - Tony Olech - Elan Digital Systems * tony.olech@elandigitalsystems.com * -* This program is free software;you can redistribute it and/or -* modify it under the terms of the GNU General Public License as -* published by the Free Software Foundation, version 2. -* -* * This driver was written by Tony Olech(tony.olech@elandigitalsystems.com) * based on various USB host drivers in the 2.6.15 linux kernel * with constant reference to the 3rd Edition of Linux Device Drivers diff --git a/drivers/usb/host/uhci-debug.c b/drivers/usb/host/uhci-debug.c index 9c6635d43db0..c4e67c4b51f6 100644 --- a/drivers/usb/host/uhci-debug.c +++ b/drivers/usb/host/uhci-debug.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * UHCI-specific debugging code. Invaluable when something * goes wrong, but don't get in my face. diff --git a/drivers/usb/host/uhci-grlib.c b/drivers/usb/host/uhci-grlib.c index 0342991c9507..2103b1ed0f8f 100644 --- a/drivers/usb/host/uhci-grlib.c +++ b/drivers/usb/host/uhci-grlib.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * UHCI HCD (Host Controller Driver) for GRLIB GRUSBHC * diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c index c3267a78c94e..babeefd84ffd 100644 --- a/drivers/usb/host/uhci-hcd.c +++ b/drivers/usb/host/uhci-hcd.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Universal Host Controller Interface driver for USB. * diff --git a/drivers/usb/host/uhci-hcd.h b/drivers/usb/host/uhci-hcd.h index 91b22b2ea3aa..f1cc47292a59 100644 --- a/drivers/usb/host/uhci-hcd.h +++ b/drivers/usb/host/uhci-hcd.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __LINUX_UHCI_HCD_H #define __LINUX_UHCI_HCD_H @@ -186,7 +187,7 @@ struct uhci_qh { * We need a special accessor for the element pointer because it is * subject to asynchronous updates by the controller. */ -#define qh_element(qh) ACCESS_ONCE((qh)->element) +#define qh_element(qh) READ_ONCE((qh)->element) #define LINK_TO_QH(uhci, qh) (UHCI_PTR_QH((uhci)) | \ cpu_to_hc32((uhci), (qh)->dma_handle)) @@ -274,7 +275,7 @@ struct uhci_td { * subject to asynchronous updates by the controller. */ #define td_status(uhci, td) hc32_to_cpu((uhci), \ - ACCESS_ONCE((td)->status)) + READ_ONCE((td)->status)) #define LINK_TO_TD(uhci, td) (cpu_to_hc32((uhci), (td)->dma_handle)) diff --git a/drivers/usb/host/uhci-hub.c b/drivers/usb/host/uhci-hub.c index ece9e37e89fe..47106dd8ca7c 100644 --- a/drivers/usb/host/uhci-hub.c +++ b/drivers/usb/host/uhci-hub.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Universal Host Controller Interface driver for USB. * diff --git a/drivers/usb/host/uhci-pci.c b/drivers/usb/host/uhci-pci.c index 49effdc0d857..0dd944277c99 100644 --- a/drivers/usb/host/uhci-pci.c +++ b/drivers/usb/host/uhci-pci.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * UHCI HCD (Host Controller Driver) PCI Bus Glue. * diff --git a/drivers/usb/host/uhci-platform.c b/drivers/usb/host/uhci-platform.c index 1b4e086c33a0..6cb16d4b2257 100644 --- a/drivers/usb/host/uhci-platform.c +++ b/drivers/usb/host/uhci-platform.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Generic UHCI HCD (Host Controller Driver) for Platform Devices * diff --git a/drivers/usb/host/uhci-q.c b/drivers/usb/host/uhci-q.c index c17ea1589b83..49d4edc03cc2 100644 --- a/drivers/usb/host/uhci-q.c +++ b/drivers/usb/host/uhci-q.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Universal Host Controller Interface driver for USB. * diff --git a/drivers/usb/host/whci/asl.c b/drivers/usb/host/whci/asl.c index 773249306031..c5ac9efb076a 100644 --- a/drivers/usb/host/whci/asl.c +++ b/drivers/usb/host/whci/asl.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Wireless Host Controller (WHC) asynchronous schedule management. * * Copyright (C) 2007 Cambridge Silicon Radio Ltd. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version - * 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include <linux/kernel.h> #include <linux/gfp.h> diff --git a/drivers/usb/host/whci/debug.c b/drivers/usb/host/whci/debug.c index 774b89d28fae..f154e5791bfd 100644 --- a/drivers/usb/host/whci/debug.c +++ b/drivers/usb/host/whci/debug.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Wireless Host Controller (WHC) debug. * * Copyright (C) 2008 Cambridge Silicon Radio Ltd. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version - * 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include <linux/slab.h> #include <linux/kernel.h> diff --git a/drivers/usb/host/whci/hcd.c b/drivers/usb/host/whci/hcd.c index cf84269c3e6d..8af9dcfea127 100644 --- a/drivers/usb/host/whci/hcd.c +++ b/drivers/usb/host/whci/hcd.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Wireless Host Controller (WHC) driver. * * Copyright (C) 2007 Cambridge Silicon Radio Ltd. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version - * 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include <linux/kernel.h> #include <linux/init.h> diff --git a/drivers/usb/host/whci/hw.c b/drivers/usb/host/whci/hw.c index 6afa2e379160..22b3b7f7419d 100644 --- a/drivers/usb/host/whci/hw.c +++ b/drivers/usb/host/whci/hw.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Wireless Host Controller (WHC) hardware access helpers. * * Copyright (C) 2007 Cambridge Silicon Radio Ltd. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version - * 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include <linux/kernel.h> #include <linux/dma-mapping.h> diff --git a/drivers/usb/host/whci/init.c b/drivers/usb/host/whci/init.c index ad8eb575c30a..82416973f773 100644 --- a/drivers/usb/host/whci/init.c +++ b/drivers/usb/host/whci/init.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Wireless Host Controller (WHC) initialization. * * Copyright (C) 2007 Cambridge Silicon Radio Ltd. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version - * 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include <linux/kernel.h> #include <linux/gfp.h> diff --git a/drivers/usb/host/whci/int.c b/drivers/usb/host/whci/int.c index 0c086b2790d1..7e4ad1b8f3e3 100644 --- a/drivers/usb/host/whci/int.c +++ b/drivers/usb/host/whci/int.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Wireless Host Controller (WHC) interrupt handling. * * Copyright (C) 2007 Cambridge Silicon Radio Ltd. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version - * 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include <linux/kernel.h> #include <linux/uwb/umc.h> diff --git a/drivers/usb/host/whci/pzl.c b/drivers/usb/host/whci/pzl.c index 33c5580b4d25..bb84366f7bd3 100644 --- a/drivers/usb/host/whci/pzl.c +++ b/drivers/usb/host/whci/pzl.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Wireless Host Controller (WHC) periodic schedule management. * * Copyright (C) 2007 Cambridge Silicon Radio Ltd. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version - * 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include <linux/kernel.h> #include <linux/gfp.h> diff --git a/drivers/usb/host/whci/qset.c b/drivers/usb/host/whci/qset.c index c0e6812426b3..925166a207aa 100644 --- a/drivers/usb/host/whci/qset.c +++ b/drivers/usb/host/whci/qset.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Wireless Host Controller (WHC) qset management. * * Copyright (C) 2007 Cambridge Silicon Radio Ltd. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version - * 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include <linux/kernel.h> #include <linux/dma-mapping.h> diff --git a/drivers/usb/host/whci/whcd.h b/drivers/usb/host/whci/whcd.h index c80c7d93bc4a..139476997e7c 100644 --- a/drivers/usb/host/whci/whcd.h +++ b/drivers/usb/host/whci/whcd.h @@ -1,21 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Wireless Host Controller (WHC) private header. * * Copyright (C) 2007 Cambridge Silicon Radio Ltd. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version - * 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. */ #ifndef __WHCD_H #define __WHCD_H diff --git a/drivers/usb/host/whci/whci-hc.h b/drivers/usb/host/whci/whci-hc.h index 4d4cbc0730bf..5a86a57a80cc 100644 --- a/drivers/usb/host/whci/whci-hc.h +++ b/drivers/usb/host/whci/whci-hc.h @@ -1,21 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Wireless Host Controller (WHC) data structures. * * Copyright (C) 2007 Cambridge Silicon Radio Ltd. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version - * 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. */ #ifndef _WHCI_WHCI_HC_H #define _WHCI_WHCI_HC_H diff --git a/drivers/usb/host/whci/wusb.c b/drivers/usb/host/whci/wusb.c index 8d2762682869..8a4d805ff63a 100644 --- a/drivers/usb/host/whci/wusb.c +++ b/drivers/usb/host/whci/wusb.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Wireless Host Controller (WHC) WUSB operations. * * Copyright (C) 2007 Cambridge Silicon Radio Ltd. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version - * 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include <linux/kernel.h> #include <linux/uwb/umc.h> diff --git a/drivers/usb/host/xhci-dbg.c b/drivers/usb/host/xhci-dbg.c index 2c83b37ae8f2..584d7b9a3683 100644 --- a/drivers/usb/host/xhci-dbg.c +++ b/drivers/usb/host/xhci-dbg.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * xHCI host controller driver * @@ -5,19 +6,6 @@ * * Author: Sarah Sharp * Some code borrowed from the Linux EHCI driver. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "xhci.h" diff --git a/drivers/usb/host/xhci-debugfs.c b/drivers/usb/host/xhci-debugfs.c new file mode 100644 index 000000000000..4f7895dbcf88 --- /dev/null +++ b/drivers/usb/host/xhci-debugfs.c @@ -0,0 +1,523 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * xhci-debugfs.c - xHCI debugfs interface + * + * Copyright (C) 2017 Intel Corporation + * + * Author: Lu Baolu <baolu.lu@linux.intel.com> + */ + +#include <linux/slab.h> + +#include "xhci.h" +#include "xhci-debugfs.h" + +static const struct debugfs_reg32 xhci_cap_regs[] = { + dump_register(CAPLENGTH), + dump_register(HCSPARAMS1), + dump_register(HCSPARAMS2), + dump_register(HCSPARAMS3), + dump_register(HCCPARAMS1), + dump_register(DOORBELLOFF), + dump_register(RUNTIMEOFF), + dump_register(HCCPARAMS2), +}; + +static const struct debugfs_reg32 xhci_op_regs[] = { + dump_register(USBCMD), + dump_register(USBSTS), + dump_register(PAGESIZE), + dump_register(DNCTRL), + dump_register(CRCR), + dump_register(DCBAAP_LOW), + dump_register(DCBAAP_HIGH), + dump_register(CONFIG), +}; + +static const struct debugfs_reg32 xhci_runtime_regs[] = { + dump_register(MFINDEX), + dump_register(IR0_IMAN), + dump_register(IR0_IMOD), + dump_register(IR0_ERSTSZ), + dump_register(IR0_ERSTBA_LOW), + dump_register(IR0_ERSTBA_HIGH), + dump_register(IR0_ERDP_LOW), + dump_register(IR0_ERDP_HIGH), +}; + +static const struct debugfs_reg32 xhci_extcap_legsup[] = { + dump_register(EXTCAP_USBLEGSUP), + dump_register(EXTCAP_USBLEGCTLSTS), +}; + +static const struct debugfs_reg32 xhci_extcap_protocol[] = { + dump_register(EXTCAP_REVISION), + dump_register(EXTCAP_NAME), + dump_register(EXTCAP_PORTINFO), + dump_register(EXTCAP_PORTTYPE), + dump_register(EXTCAP_MANTISSA1), + dump_register(EXTCAP_MANTISSA2), + dump_register(EXTCAP_MANTISSA3), + dump_register(EXTCAP_MANTISSA4), + dump_register(EXTCAP_MANTISSA5), + dump_register(EXTCAP_MANTISSA6), +}; + +static const struct debugfs_reg32 xhci_extcap_dbc[] = { + dump_register(EXTCAP_DBC_CAPABILITY), + dump_register(EXTCAP_DBC_DOORBELL), + dump_register(EXTCAP_DBC_ERSTSIZE), + dump_register(EXTCAP_DBC_ERST_LOW), + dump_register(EXTCAP_DBC_ERST_HIGH), + dump_register(EXTCAP_DBC_ERDP_LOW), + dump_register(EXTCAP_DBC_ERDP_HIGH), + dump_register(EXTCAP_DBC_CONTROL), + dump_register(EXTCAP_DBC_STATUS), + dump_register(EXTCAP_DBC_PORTSC), + dump_register(EXTCAP_DBC_CONT_LOW), + dump_register(EXTCAP_DBC_CONT_HIGH), + dump_register(EXTCAP_DBC_DEVINFO1), + dump_register(EXTCAP_DBC_DEVINFO2), +}; + +static struct dentry *xhci_debugfs_root; + +static struct xhci_regset *xhci_debugfs_alloc_regset(struct xhci_hcd *xhci) +{ + struct xhci_regset *regset; + + regset = kzalloc(sizeof(*regset), GFP_KERNEL); + if (!regset) + return NULL; + + /* + * The allocation and free of regset are executed in order. + * We needn't a lock here. + */ + INIT_LIST_HEAD(®set->list); + list_add_tail(®set->list, &xhci->regset_list); + + return regset; +} + +static void xhci_debugfs_free_regset(struct xhci_regset *regset) +{ + if (!regset) + return; + + list_del(®set->list); + kfree(regset); +} + +static void xhci_debugfs_regset(struct xhci_hcd *xhci, u32 base, + const struct debugfs_reg32 *regs, + size_t nregs, struct dentry *parent, + const char *fmt, ...) +{ + struct xhci_regset *rgs; + va_list args; + struct debugfs_regset32 *regset; + struct usb_hcd *hcd = xhci_to_hcd(xhci); + + rgs = xhci_debugfs_alloc_regset(xhci); + if (!rgs) + return; + + va_start(args, fmt); + vsnprintf(rgs->name, sizeof(rgs->name), fmt, args); + va_end(args); + + regset = &rgs->regset; + regset->regs = regs; + regset->nregs = nregs; + regset->base = hcd->regs + base; + + debugfs_create_regset32((const char *)rgs->name, 0444, parent, regset); +} + +static void xhci_debugfs_extcap_regset(struct xhci_hcd *xhci, int cap_id, + const struct debugfs_reg32 *regs, + size_t n, const char *cap_name) +{ + u32 offset; + int index = 0; + size_t psic, nregs = n; + void __iomem *base = &xhci->cap_regs->hc_capbase; + + offset = xhci_find_next_ext_cap(base, 0, cap_id); + while (offset) { + if (cap_id == XHCI_EXT_CAPS_PROTOCOL) { + psic = XHCI_EXT_PORT_PSIC(readl(base + offset + 8)); + nregs = min(4 + psic, n); + } + + xhci_debugfs_regset(xhci, offset, regs, nregs, + xhci->debugfs_root, "%s:%02d", + cap_name, index); + offset = xhci_find_next_ext_cap(base, offset, cap_id); + index++; + } +} + +static int xhci_ring_enqueue_show(struct seq_file *s, void *unused) +{ + dma_addr_t dma; + struct xhci_ring *ring = s->private; + + dma = xhci_trb_virt_to_dma(ring->enq_seg, ring->enqueue); + seq_printf(s, "%pad\n", &dma); + + return 0; +} + +static int xhci_ring_dequeue_show(struct seq_file *s, void *unused) +{ + dma_addr_t dma; + struct xhci_ring *ring = s->private; + + dma = xhci_trb_virt_to_dma(ring->deq_seg, ring->dequeue); + seq_printf(s, "%pad\n", &dma); + + return 0; +} + +static int xhci_ring_cycle_show(struct seq_file *s, void *unused) +{ + struct xhci_ring *ring = s->private; + + seq_printf(s, "%d\n", ring->cycle_state); + + return 0; +} + +static void xhci_ring_dump_segment(struct seq_file *s, + struct xhci_segment *seg) +{ + int i; + dma_addr_t dma; + union xhci_trb *trb; + + for (i = 0; i < TRBS_PER_SEGMENT; i++) { + trb = &seg->trbs[i]; + dma = seg->dma + i * sizeof(*trb); + seq_printf(s, "%pad: %s\n", &dma, + xhci_decode_trb(trb->generic.field[0], + trb->generic.field[1], + trb->generic.field[2], + trb->generic.field[3])); + } +} + +static int xhci_ring_trb_show(struct seq_file *s, void *unused) +{ + int i; + struct xhci_ring *ring = s->private; + struct xhci_segment *seg = ring->first_seg; + + for (i = 0; i < ring->num_segs; i++) { + xhci_ring_dump_segment(s, seg); + seg = seg->next; + } + + return 0; +} + +static struct xhci_file_map ring_files[] = { + {"enqueue", xhci_ring_enqueue_show, }, + {"dequeue", xhci_ring_dequeue_show, }, + {"cycle", xhci_ring_cycle_show, }, + {"trbs", xhci_ring_trb_show, }, +}; + +static int xhci_ring_open(struct inode *inode, struct file *file) +{ + int i; + struct xhci_file_map *f_map; + const char *file_name = file_dentry(file)->d_iname; + + for (i = 0; i < ARRAY_SIZE(ring_files); i++) { + f_map = &ring_files[i]; + + if (strcmp(f_map->name, file_name) == 0) + break; + } + + return single_open(file, f_map->show, inode->i_private); +} + +static const struct file_operations xhci_ring_fops = { + .open = xhci_ring_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static int xhci_slot_context_show(struct seq_file *s, void *unused) +{ + struct xhci_hcd *xhci; + struct xhci_slot_ctx *slot_ctx; + struct xhci_slot_priv *priv = s->private; + struct xhci_virt_device *dev = priv->dev; + + xhci = hcd_to_xhci(bus_to_hcd(dev->udev->bus)); + slot_ctx = xhci_get_slot_ctx(xhci, dev->out_ctx); + seq_printf(s, "%pad: %s\n", &dev->out_ctx->dma, + xhci_decode_slot_context(slot_ctx->dev_info, + slot_ctx->dev_info2, + slot_ctx->tt_info, + slot_ctx->dev_state)); + + return 0; +} + +static int xhci_endpoint_context_show(struct seq_file *s, void *unused) +{ + int dci; + dma_addr_t dma; + struct xhci_hcd *xhci; + struct xhci_ep_ctx *ep_ctx; + struct xhci_slot_priv *priv = s->private; + struct xhci_virt_device *dev = priv->dev; + + xhci = hcd_to_xhci(bus_to_hcd(dev->udev->bus)); + + for (dci = 1; dci < 32; dci++) { + ep_ctx = xhci_get_ep_ctx(xhci, dev->out_ctx, dci); + dma = dev->out_ctx->dma + dci * CTX_SIZE(xhci->hcc_params); + seq_printf(s, "%pad: %s\n", &dma, + xhci_decode_ep_context(ep_ctx->ep_info, + ep_ctx->ep_info2, + ep_ctx->deq, + ep_ctx->tx_info)); + } + + return 0; +} + +static int xhci_device_name_show(struct seq_file *s, void *unused) +{ + struct xhci_slot_priv *priv = s->private; + struct xhci_virt_device *dev = priv->dev; + + seq_printf(s, "%s\n", dev_name(&dev->udev->dev)); + + return 0; +} + +static struct xhci_file_map context_files[] = { + {"name", xhci_device_name_show, }, + {"slot-context", xhci_slot_context_show, }, + {"ep-context", xhci_endpoint_context_show, }, +}; + +static int xhci_context_open(struct inode *inode, struct file *file) +{ + int i; + struct xhci_file_map *f_map; + const char *file_name = file_dentry(file)->d_iname; + + for (i = 0; i < ARRAY_SIZE(context_files); i++) { + f_map = &context_files[i]; + + if (strcmp(f_map->name, file_name) == 0) + break; + } + + return single_open(file, f_map->show, inode->i_private); +} + +static const struct file_operations xhci_context_fops = { + .open = xhci_context_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static void xhci_debugfs_create_files(struct xhci_hcd *xhci, + struct xhci_file_map *files, + size_t nentries, void *data, + struct dentry *parent, + const struct file_operations *fops) +{ + int i; + + for (i = 0; i < nentries; i++) + debugfs_create_file(files[i].name, 0444, parent, data, fops); +} + +static struct dentry *xhci_debugfs_create_ring_dir(struct xhci_hcd *xhci, + struct xhci_ring *ring, + const char *name, + struct dentry *parent) +{ + struct dentry *dir; + + dir = debugfs_create_dir(name, parent); + xhci_debugfs_create_files(xhci, ring_files, ARRAY_SIZE(ring_files), + ring, dir, &xhci_ring_fops); + + return dir; +} + +static void xhci_debugfs_create_context_files(struct xhci_hcd *xhci, + struct dentry *parent, + int slot_id) +{ + struct xhci_virt_device *dev = xhci->devs[slot_id]; + + xhci_debugfs_create_files(xhci, context_files, + ARRAY_SIZE(context_files), + dev->debugfs_private, + parent, &xhci_context_fops); +} + +void xhci_debugfs_create_endpoint(struct xhci_hcd *xhci, + struct xhci_virt_device *dev, + int ep_index) +{ + struct xhci_ep_priv *epriv; + struct xhci_slot_priv *spriv = dev->debugfs_private; + + if (spriv->eps[ep_index]) + return; + + epriv = kzalloc(sizeof(*epriv), GFP_KERNEL); + if (!epriv) + return; + + snprintf(epriv->name, sizeof(epriv->name), "ep%02d", ep_index); + epriv->root = xhci_debugfs_create_ring_dir(xhci, + dev->eps[ep_index].new_ring, + epriv->name, + spriv->root); + spriv->eps[ep_index] = epriv; +} + +void xhci_debugfs_remove_endpoint(struct xhci_hcd *xhci, + struct xhci_virt_device *dev, + int ep_index) +{ + struct xhci_ep_priv *epriv; + struct xhci_slot_priv *spriv = dev->debugfs_private; + + if (!spriv || !spriv->eps[ep_index]) + return; + + epriv = spriv->eps[ep_index]; + debugfs_remove_recursive(epriv->root); + spriv->eps[ep_index] = NULL; + kfree(epriv); +} + +void xhci_debugfs_create_slot(struct xhci_hcd *xhci, int slot_id) +{ + struct xhci_slot_priv *priv; + struct xhci_virt_device *dev = xhci->devs[slot_id]; + + priv = kzalloc(sizeof(*priv), GFP_KERNEL); + if (!priv) + return; + + snprintf(priv->name, sizeof(priv->name), "%02d", slot_id); + priv->root = debugfs_create_dir(priv->name, xhci->debugfs_slots); + priv->dev = dev; + dev->debugfs_private = priv; + + xhci_debugfs_create_ring_dir(xhci, dev->eps[0].ring, + "ep00", priv->root); + + xhci_debugfs_create_context_files(xhci, priv->root, slot_id); +} + +void xhci_debugfs_remove_slot(struct xhci_hcd *xhci, int slot_id) +{ + int i; + struct xhci_slot_priv *priv; + struct xhci_virt_device *dev = xhci->devs[slot_id]; + + if (!dev || !dev->debugfs_private) + return; + + priv = dev->debugfs_private; + + debugfs_remove_recursive(priv->root); + + for (i = 0; i < 31; i++) + kfree(priv->eps[i]); + + kfree(priv); + dev->debugfs_private = NULL; +} + +void xhci_debugfs_init(struct xhci_hcd *xhci) +{ + struct device *dev = xhci_to_hcd(xhci)->self.controller; + + xhci->debugfs_root = debugfs_create_dir(dev_name(dev), + xhci_debugfs_root); + + INIT_LIST_HEAD(&xhci->regset_list); + + xhci_debugfs_regset(xhci, + 0, + xhci_cap_regs, ARRAY_SIZE(xhci_cap_regs), + xhci->debugfs_root, "reg-cap"); + + xhci_debugfs_regset(xhci, + HC_LENGTH(readl(&xhci->cap_regs->hc_capbase)), + xhci_op_regs, ARRAY_SIZE(xhci_op_regs), + xhci->debugfs_root, "reg-op"); + + xhci_debugfs_regset(xhci, + readl(&xhci->cap_regs->run_regs_off) & RTSOFF_MASK, + xhci_runtime_regs, ARRAY_SIZE(xhci_runtime_regs), + xhci->debugfs_root, "reg-runtime"); + + xhci_debugfs_extcap_regset(xhci, XHCI_EXT_CAPS_LEGACY, + xhci_extcap_legsup, + ARRAY_SIZE(xhci_extcap_legsup), + "reg-ext-legsup"); + + xhci_debugfs_extcap_regset(xhci, XHCI_EXT_CAPS_PROTOCOL, + xhci_extcap_protocol, + ARRAY_SIZE(xhci_extcap_protocol), + "reg-ext-protocol"); + + xhci_debugfs_extcap_regset(xhci, XHCI_EXT_CAPS_DEBUG, + xhci_extcap_dbc, + ARRAY_SIZE(xhci_extcap_dbc), + "reg-ext-dbc"); + + xhci_debugfs_create_ring_dir(xhci, xhci->cmd_ring, + "command-ring", + xhci->debugfs_root); + + xhci_debugfs_create_ring_dir(xhci, xhci->event_ring, + "event-ring", + xhci->debugfs_root); + + xhci->debugfs_slots = debugfs_create_dir("devices", xhci->debugfs_root); +} + +void xhci_debugfs_exit(struct xhci_hcd *xhci) +{ + struct xhci_regset *rgs, *tmp; + + debugfs_remove_recursive(xhci->debugfs_root); + xhci->debugfs_root = NULL; + xhci->debugfs_slots = NULL; + + list_for_each_entry_safe(rgs, tmp, &xhci->regset_list, list) + xhci_debugfs_free_regset(rgs); +} + +void __init xhci_debugfs_create_root(void) +{ + xhci_debugfs_root = debugfs_create_dir("xhci", usb_debug_root); +} + +void __exit xhci_debugfs_remove_root(void) +{ + debugfs_remove_recursive(xhci_debugfs_root); + xhci_debugfs_root = NULL; +} diff --git a/drivers/usb/host/xhci-debugfs.h b/drivers/usb/host/xhci-debugfs.h new file mode 100644 index 000000000000..ac5bc40f5c3a --- /dev/null +++ b/drivers/usb/host/xhci-debugfs.h @@ -0,0 +1,134 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * xhci-debugfs.h - xHCI debugfs interface + * + * Copyright (C) 2017 Intel Corporation + * + * Author: Lu Baolu <baolu.lu@linux.intel.com> + */ + +#ifndef __LINUX_XHCI_DEBUGFS_H +#define __LINUX_XHCI_DEBUGFS_H + +#include <linux/debugfs.h> + +#define DEBUGFS_NAMELEN 32 + +#define REG_CAPLENGTH 0x00 +#define REG_HCSPARAMS1 0x04 +#define REG_HCSPARAMS2 0x08 +#define REG_HCSPARAMS3 0x0c +#define REG_HCCPARAMS1 0x10 +#define REG_DOORBELLOFF 0x14 +#define REG_RUNTIMEOFF 0x18 +#define REG_HCCPARAMS2 0x1c + +#define REG_USBCMD 0x00 +#define REG_USBSTS 0x04 +#define REG_PAGESIZE 0x08 +#define REG_DNCTRL 0x14 +#define REG_CRCR 0x18 +#define REG_DCBAAP_LOW 0x30 +#define REG_DCBAAP_HIGH 0x34 +#define REG_CONFIG 0x38 + +#define REG_MFINDEX 0x00 +#define REG_IR0_IMAN 0x20 +#define REG_IR0_IMOD 0x24 +#define REG_IR0_ERSTSZ 0x28 +#define REG_IR0_ERSTBA_LOW 0x30 +#define REG_IR0_ERSTBA_HIGH 0x34 +#define REG_IR0_ERDP_LOW 0x38 +#define REG_IR0_ERDP_HIGH 0x3c + +#define REG_EXTCAP_USBLEGSUP 0x00 +#define REG_EXTCAP_USBLEGCTLSTS 0x04 + +#define REG_EXTCAP_REVISION 0x00 +#define REG_EXTCAP_NAME 0x04 +#define REG_EXTCAP_PORTINFO 0x08 +#define REG_EXTCAP_PORTTYPE 0x0c +#define REG_EXTCAP_MANTISSA1 0x10 +#define REG_EXTCAP_MANTISSA2 0x14 +#define REG_EXTCAP_MANTISSA3 0x18 +#define REG_EXTCAP_MANTISSA4 0x1c +#define REG_EXTCAP_MANTISSA5 0x20 +#define REG_EXTCAP_MANTISSA6 0x24 + +#define REG_EXTCAP_DBC_CAPABILITY 0x00 +#define REG_EXTCAP_DBC_DOORBELL 0x04 +#define REG_EXTCAP_DBC_ERSTSIZE 0x08 +#define REG_EXTCAP_DBC_ERST_LOW 0x10 +#define REG_EXTCAP_DBC_ERST_HIGH 0x14 +#define REG_EXTCAP_DBC_ERDP_LOW 0x18 +#define REG_EXTCAP_DBC_ERDP_HIGH 0x1c +#define REG_EXTCAP_DBC_CONTROL 0x20 +#define REG_EXTCAP_DBC_STATUS 0x24 +#define REG_EXTCAP_DBC_PORTSC 0x28 +#define REG_EXTCAP_DBC_CONT_LOW 0x30 +#define REG_EXTCAP_DBC_CONT_HIGH 0x34 +#define REG_EXTCAP_DBC_DEVINFO1 0x38 +#define REG_EXTCAP_DBC_DEVINFO2 0x3c + +#define dump_register(nm) \ +{ \ + .name = __stringify(nm), \ + .offset = REG_ ##nm, \ +} + +struct xhci_regset { + char name[DEBUGFS_NAMELEN]; + struct debugfs_regset32 regset; + size_t nregs; + struct dentry *parent; + struct list_head list; +}; + +struct xhci_file_map { + const char *name; + int (*show)(struct seq_file *s, void *unused); +}; + +struct xhci_ep_priv { + char name[DEBUGFS_NAMELEN]; + struct dentry *root; +}; + +struct xhci_slot_priv { + char name[DEBUGFS_NAMELEN]; + struct dentry *root; + struct xhci_ep_priv *eps[31]; + struct xhci_virt_device *dev; +}; + +#ifdef CONFIG_DEBUG_FS +void xhci_debugfs_init(struct xhci_hcd *xhci); +void xhci_debugfs_exit(struct xhci_hcd *xhci); +void __init xhci_debugfs_create_root(void); +void __exit xhci_debugfs_remove_root(void); +void xhci_debugfs_create_slot(struct xhci_hcd *xhci, int slot_id); +void xhci_debugfs_remove_slot(struct xhci_hcd *xhci, int slot_id); +void xhci_debugfs_create_endpoint(struct xhci_hcd *xhci, + struct xhci_virt_device *virt_dev, + int ep_index); +void xhci_debugfs_remove_endpoint(struct xhci_hcd *xhci, + struct xhci_virt_device *virt_dev, + int ep_index); +#else +static inline void xhci_debugfs_init(struct xhci_hcd *xhci) { } +static inline void xhci_debugfs_exit(struct xhci_hcd *xhci) { } +static inline void __init xhci_debugfs_create_root(void) { } +static inline void __exit xhci_debugfs_remove_root(void) { } +static inline void xhci_debugfs_create_slot(struct xhci_hcd *x, int s) { } +static inline void xhci_debugfs_remove_slot(struct xhci_hcd *x, int s) { } +static inline void +xhci_debugfs_create_endpoint(struct xhci_hcd *xhci, + struct xhci_virt_device *virt_dev, + int ep_index) { } +static inline void +xhci_debugfs_remove_endpoint(struct xhci_hcd *xhci, + struct xhci_virt_device *virt_dev, + int ep_index) { } +#endif /* CONFIG_DEBUG_FS */ + +#endif /* __LINUX_XHCI_DEBUGFS_H */ diff --git a/drivers/usb/host/xhci-ext-caps.h b/drivers/usb/host/xhci-ext-caps.h index 28deea584884..bf7316e130d3 100644 --- a/drivers/usb/host/xhci-ext-caps.h +++ b/drivers/usb/host/xhci-ext-caps.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * xHCI host controller driver * @@ -5,19 +6,6 @@ * * Author: Sarah Sharp * Some code borrowed from the Linux EHCI driver. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* Up to 16 ms to halt an HC */ #define XHCI_MAX_HALT_USEC (16*1000) diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c index a2336deb5e36..2a90229be7a6 100644 --- a/drivers/usb/host/xhci-hub.c +++ b/drivers/usb/host/xhci-hub.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * xHCI host controller driver * @@ -5,19 +6,6 @@ * * Author: Sarah Sharp * Some code borrowed from the Linux EHCI driver. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ @@ -634,7 +622,10 @@ static int xhci_enter_test_mode(struct xhci_hcd *xhci, xhci_dbg(xhci, "Disable all slots\n"); spin_unlock_irqrestore(&xhci->lock, *flags); for (i = 1; i <= HCS_MAX_SLOTS(xhci->hcs_params1); i++) { - retval = xhci_disable_slot(xhci, NULL, i); + if (!xhci->devs[i]) + continue; + + retval = xhci_disable_slot(xhci, i); if (retval) xhci_err(xhci, "Failed to disable slot %d, %d. Enter test mode anyway\n", i, retval); @@ -1374,6 +1365,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, break; case USB_PORT_FEAT_C_SUSPEND: bus_state->port_c_suspend &= ~(1 << wIndex); + /* fall through */ case USB_PORT_FEAT_C_RESET: case USB_PORT_FEAT_C_BH_PORT_RESET: case USB_PORT_FEAT_C_CONNECTION: diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index 2a82c927ded2..e1fba4688509 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * xHCI host controller driver * @@ -5,19 +6,6 @@ * * Author: Sarah Sharp * Some code borrowed from the Linux EHCI driver. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include <linux/usb.h> @@ -28,6 +16,7 @@ #include "xhci.h" #include "xhci-trace.h" +#include "xhci-debugfs.h" /* * Allocates a generic ring segment from the ring pool, sets the dma address, @@ -465,8 +454,6 @@ int xhci_ring_expansion(struct xhci_hcd *xhci, struct xhci_ring *ring, return 0; } -#define CTX_SIZE(_hcc) (HCC_64BYTE_CONTEXT(_hcc) ? 64 : 32) - static struct xhci_container_ctx *xhci_alloc_container_ctx(struct xhci_hcd *xhci, int type, gfp_t flags) { @@ -801,8 +788,8 @@ void xhci_free_stream_info(struct xhci_hcd *xhci, static void xhci_init_endpoint_timer(struct xhci_hcd *xhci, struct xhci_virt_ep *ep) { - setup_timer(&ep->stop_cmd_timer, xhci_stop_endpoint_command_watchdog, - (unsigned long)ep); + timer_setup(&ep->stop_cmd_timer, xhci_stop_endpoint_command_watchdog, + 0); ep->xhci = xhci; } @@ -961,6 +948,7 @@ void xhci_free_virt_devices_depth_first(struct xhci_hcd *xhci, int slot_id) } } /* we are now at a leaf device */ + xhci_debugfs_remove_slot(xhci, slot_id); xhci_free_virt_device(xhci, slot_id); } @@ -1311,6 +1299,7 @@ static unsigned int xhci_get_endpoint_interval(struct usb_device *udev, * since it uses the same rules as low speed interrupt * endpoints. */ + /* fall through */ case USB_SPEED_LOW: if (usb_endpoint_xfer_int(&ep->desc) || @@ -1496,7 +1485,6 @@ int xhci_endpoint_init(struct xhci_hcd *xhci, ep_ctx->tx_info = cpu_to_le32(EP_MAX_ESIT_PAYLOAD_LO(max_esit_payload) | EP_AVG_TRB_LENGTH(avg_trb_len)); - /* FIXME Debug endpoint context */ return 0; } diff --git a/drivers/usb/host/xhci-mtk-sch.c b/drivers/usb/host/xhci-mtk-sch.c index 6e7ddf6cafae..eea7360a18fc 100644 --- a/drivers/usb/host/xhci-mtk-sch.c +++ b/drivers/usb/host/xhci-mtk-sch.c @@ -1,18 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2015 MediaTek Inc. * Author: * Zhigang.Wei <zhigang.wei@mediatek.com> * Chunfeng.Yun <chunfeng.yun@mediatek.com> - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * */ #include <linux/kernel.h> @@ -287,12 +278,13 @@ static bool need_bw_sch(struct usb_host_endpoint *ep, int xhci_mtk_sch_init(struct xhci_hcd_mtk *mtk) { + struct xhci_hcd *xhci = hcd_to_xhci(mtk->hcd); struct mu3h_sch_bw_info *sch_array; int num_usb_bus; int i; /* ss IN and OUT are separated */ - num_usb_bus = mtk->num_u3_ports * 2 + mtk->num_u2_ports; + num_usb_bus = xhci->num_usb3_ports * 2 + xhci->num_usb2_ports; sch_array = kcalloc(num_usb_bus, sizeof(*sch_array), GFP_KERNEL); if (sch_array == NULL) diff --git a/drivers/usb/host/xhci-mtk.c b/drivers/usb/host/xhci-mtk.c index 8fb60657ed4f..b62a1d23244b 100644 --- a/drivers/usb/host/xhci-mtk.c +++ b/drivers/usb/host/xhci-mtk.c @@ -1,19 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0 /* * MediaTek xHCI Host Controller Driver * * Copyright (c) 2015 MediaTek Inc. * Author: * Chunfeng Yun <chunfeng.yun@mediatek.com> - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * */ #include <linux/clk.h> @@ -43,6 +34,7 @@ /* ip_pw_sts1 register */ #define STS1_IP_SLEEP_STS BIT(30) +#define STS1_U3_MAC_RST BIT(16) #define STS1_XHCI_RST BIT(11) #define STS1_SYS125_RST BIT(10) #define STS1_REF_RST BIT(8) @@ -91,6 +83,7 @@ static int xhci_mtk_host_enable(struct xhci_hcd_mtk *mtk) { struct mu3c_ippc_regs __iomem *ippc = mtk->ippc_regs; u32 value, check_val; + int u3_ports_disabed = 0; int ret; int i; @@ -102,8 +95,13 @@ static int xhci_mtk_host_enable(struct xhci_hcd_mtk *mtk) value &= ~CTRL1_IP_HOST_PDN; writel(value, &ippc->ip_pw_ctr1); - /* power on and enable all u3 ports */ + /* power on and enable u3 ports except skipped ones */ for (i = 0; i < mtk->num_u3_ports; i++) { + if ((0x1 << i) & mtk->u3p_dis_msk) { + u3_ports_disabed++; + continue; + } + value = readl(&ippc->u3_ctrl_p[i]); value &= ~(CTRL_U3_PORT_PDN | CTRL_U3_PORT_DIS); value |= CTRL_U3_PORT_HOST_SEL; @@ -125,6 +123,9 @@ static int xhci_mtk_host_enable(struct xhci_hcd_mtk *mtk) check_val = STS1_SYSPLL_STABLE | STS1_REF_RST | STS1_SYS125_RST | STS1_XHCI_RST; + if (mtk->num_u3_ports > u3_ports_disabed) + check_val |= STS1_U3_MAC_RST; + ret = readl_poll_timeout(&ippc->ip_pw_sts1, value, (check_val == (value & check_val)), 100, 20000); if (ret) { @@ -145,8 +146,11 @@ static int xhci_mtk_host_disable(struct xhci_hcd_mtk *mtk) if (!mtk->has_ippc) return 0; - /* power down all u3 ports */ + /* power down u3 ports except skipped ones */ for (i = 0; i < mtk->num_u3_ports; i++) { + if ((0x1 << i) & mtk->u3p_dis_msk) + continue; + value = readl(&ippc->u3_ctrl_p[i]); value |= CTRL_U3_PORT_PDN; writel(value, &ippc->u3_ctrl_p[i]); @@ -208,6 +212,41 @@ static int xhci_mtk_ssusb_config(struct xhci_hcd_mtk *mtk) return xhci_mtk_host_enable(mtk); } +/* ignore the error if the clock does not exist */ +static struct clk *optional_clk_get(struct device *dev, const char *id) +{ + struct clk *opt_clk; + + opt_clk = devm_clk_get(dev, id); + /* ignore error number except EPROBE_DEFER */ + if (IS_ERR(opt_clk) && (PTR_ERR(opt_clk) != -EPROBE_DEFER)) + opt_clk = NULL; + + return opt_clk; +} + +static int xhci_mtk_clks_get(struct xhci_hcd_mtk *mtk) +{ + struct device *dev = mtk->dev; + + mtk->sys_clk = devm_clk_get(dev, "sys_ck"); + if (IS_ERR(mtk->sys_clk)) { + dev_err(dev, "fail to get sys_ck\n"); + return PTR_ERR(mtk->sys_clk); + } + + mtk->ref_clk = optional_clk_get(dev, "ref_ck"); + if (IS_ERR(mtk->ref_clk)) + return PTR_ERR(mtk->ref_clk); + + mtk->mcu_clk = optional_clk_get(dev, "mcu_ck"); + if (IS_ERR(mtk->mcu_clk)) + return PTR_ERR(mtk->mcu_clk); + + mtk->dma_clk = optional_clk_get(dev, "dma_ck"); + return PTR_ERR_OR_ZERO(mtk->dma_clk); +} + static int xhci_mtk_clks_enable(struct xhci_hcd_mtk *mtk) { int ret; @@ -224,37 +263,34 @@ static int xhci_mtk_clks_enable(struct xhci_hcd_mtk *mtk) goto sys_clk_err; } - if (mtk->wakeup_src) { - ret = clk_prepare_enable(mtk->wk_deb_p0); - if (ret) { - dev_err(mtk->dev, "failed to enable wk_deb_p0\n"); - goto usb_p0_err; - } + ret = clk_prepare_enable(mtk->mcu_clk); + if (ret) { + dev_err(mtk->dev, "failed to enable mcu_clk\n"); + goto mcu_clk_err; + } - ret = clk_prepare_enable(mtk->wk_deb_p1); - if (ret) { - dev_err(mtk->dev, "failed to enable wk_deb_p1\n"); - goto usb_p1_err; - } + ret = clk_prepare_enable(mtk->dma_clk); + if (ret) { + dev_err(mtk->dev, "failed to enable dma_clk\n"); + goto dma_clk_err; } + return 0; -usb_p1_err: - clk_disable_unprepare(mtk->wk_deb_p0); -usb_p0_err: +dma_clk_err: + clk_disable_unprepare(mtk->mcu_clk); +mcu_clk_err: clk_disable_unprepare(mtk->sys_clk); sys_clk_err: clk_disable_unprepare(mtk->ref_clk); ref_clk_err: - return -EINVAL; + return ret; } static void xhci_mtk_clks_disable(struct xhci_hcd_mtk *mtk) { - if (mtk->wakeup_src) { - clk_disable_unprepare(mtk->wk_deb_p1); - clk_disable_unprepare(mtk->wk_deb_p0); - } + clk_disable_unprepare(mtk->dma_clk); + clk_disable_unprepare(mtk->mcu_clk); clk_disable_unprepare(mtk->sys_clk); clk_disable_unprepare(mtk->ref_clk); } @@ -358,18 +394,6 @@ static int usb_wakeup_of_property_parse(struct xhci_hcd_mtk *mtk, if (!mtk->wakeup_src) return 0; - mtk->wk_deb_p0 = devm_clk_get(dev, "wakeup_deb_p0"); - if (IS_ERR(mtk->wk_deb_p0)) { - dev_err(dev, "fail to get wakeup_deb_p0\n"); - return PTR_ERR(mtk->wk_deb_p0); - } - - mtk->wk_deb_p1 = devm_clk_get(dev, "wakeup_deb_p1"); - if (IS_ERR(mtk->wk_deb_p1)) { - dev_err(dev, "fail to get wakeup_deb_p1\n"); - return PTR_ERR(mtk->wk_deb_p1); - } - mtk->pericfg = syscon_regmap_lookup_by_phandle(dn, "mediatek,syscon-wakeup"); if (IS_ERR(mtk->pericfg)) { @@ -492,7 +516,6 @@ static void xhci_mtk_quirks(struct device *dev, struct xhci_hcd *xhci) /* called during probe() after chip reset completes */ static int xhci_mtk_setup(struct usb_hcd *hcd) { - struct xhci_hcd *xhci = hcd_to_xhci(hcd); struct xhci_hcd_mtk *mtk = hcd_to_mtk(hcd); int ret; @@ -507,8 +530,6 @@ static int xhci_mtk_setup(struct usb_hcd *hcd) return ret; if (usb_hcd_is_primary_hcd(hcd)) { - mtk->num_u3_ports = xhci->num_usb3_ports; - mtk->num_u2_ports = xhci->num_usb2_ports; ret = xhci_mtk_sch_init(mtk); if (ret) return ret; @@ -552,26 +573,14 @@ static int xhci_mtk_probe(struct platform_device *pdev) return PTR_ERR(mtk->vusb33); } - mtk->sys_clk = devm_clk_get(dev, "sys_ck"); - if (IS_ERR(mtk->sys_clk)) { - dev_err(dev, "fail to get sys_ck\n"); - return PTR_ERR(mtk->sys_clk); - } - - /* - * reference clock is usually a "fixed-clock", make it optional - * for backward compatibility and ignore the error if it does - * not exist. - */ - mtk->ref_clk = devm_clk_get(dev, "ref_ck"); - if (IS_ERR(mtk->ref_clk)) { - if (PTR_ERR(mtk->ref_clk) == -EPROBE_DEFER) - return -EPROBE_DEFER; - - mtk->ref_clk = NULL; - } + ret = xhci_mtk_clks_get(mtk); + if (ret) + return ret; mtk->lpm_support = of_property_read_bool(node, "usb3-lpm-capable"); + /* optional property, ignore the error if it does not exist */ + of_property_read_u32(node, "mediatek,u3p-dis-msk", + &mtk->u3p_dis_msk); ret = usb_wakeup_of_property_parse(mtk, node); if (ret) @@ -606,15 +615,10 @@ static int xhci_mtk_probe(struct platform_device *pdev) } /* Initialize dma_mask and coherent_dma_mask to 32-bits */ - ret = dma_set_coherent_mask(dev, DMA_BIT_MASK(32)); + ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32)); if (ret) goto disable_clk; - if (!dev->dma_mask) - dev->dma_mask = &dev->coherent_dma_mask; - else - dma_set_mask(dev, DMA_BIT_MASK(32)); - hcd = usb_create_hcd(driver, dev, dev_name(dev)); if (!hcd) { ret = -ENOMEM; diff --git a/drivers/usb/host/xhci-mtk.h b/drivers/usb/host/xhci-mtk.h index 3aa5e1d25064..6b74ce5b7564 100644 --- a/drivers/usb/host/xhci-mtk.h +++ b/drivers/usb/host/xhci-mtk.h @@ -1,18 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2015 MediaTek Inc. * Author: * Zhigang.Wei <zhigang.wei@mediatek.com> * Chunfeng.Yun <chunfeng.yun@mediatek.com> - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * */ #ifndef _XHCI_MTK_H_ @@ -121,12 +112,13 @@ struct xhci_hcd_mtk { bool has_ippc; int num_u2_ports; int num_u3_ports; + int u3p_dis_msk; struct regulator *vusb33; struct regulator *vbus; struct clk *sys_clk; /* sys and mac clock */ struct clk *ref_clk; - struct clk *wk_deb_p0; /* port0's wakeup debounce clock */ - struct clk *wk_deb_p1; + struct clk *mcu_clk; + struct clk *dma_clk; struct regmap *pericfg; struct phy **phys; int num_phys; diff --git a/drivers/usb/host/xhci-mvebu.c b/drivers/usb/host/xhci-mvebu.c index 85908a3ecb8f..32e158568788 100644 --- a/drivers/usb/host/xhci-mvebu.c +++ b/drivers/usb/host/xhci-mvebu.c @@ -1,10 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 2014 Marvell * Author: Gregory CLEMENT <gregory.clement@free-electrons.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. */ #include <linux/io.h> diff --git a/drivers/usb/host/xhci-mvebu.h b/drivers/usb/host/xhci-mvebu.h index 301fc984cae6..09791df2cec0 100644 --- a/drivers/usb/host/xhci-mvebu.h +++ b/drivers/usb/host/xhci-mvebu.h @@ -1,11 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 2014 Marvell * * Gregory Clement <gregory.clement@free-electrons.com> - * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. */ #ifndef __LINUX_XHCI_MVEBU_H diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index 76f392954733..7ef1274ef7f7 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * xHCI host controller driver PCI Bus Glue. * @@ -5,19 +6,6 @@ * * Author: Sarah Sharp * Some code borrowed from the Linux EHCI driver. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include <linux/pci.h> diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c index 1cb6eaef4ae1..09f164f8cf8c 100644 --- a/drivers/usb/host/xhci-plat.c +++ b/drivers/usb/host/xhci-plat.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * xhci-plat.c - xHCI host controller driver platform Bus Glue. * @@ -5,10 +6,6 @@ * Author: Sebastian Andrzej Siewior <bigeasy@linutronix.de> * * A lot of code borrowed from the Linux xHCI driver. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. */ #include <linux/clk.h> @@ -16,6 +13,7 @@ #include <linux/module.h> #include <linux/pci.h> #include <linux/of.h> +#include <linux/of_device.h> #include <linux/platform_device.h> #include <linux/usb/phy.h> #include <linux/slab.h> @@ -152,7 +150,7 @@ MODULE_DEVICE_TABLE(of, usb_xhci_of_match); static int xhci_plat_probe(struct platform_device *pdev) { - const struct of_device_id *match; + const struct xhci_plat_priv *priv_match; const struct hc_driver *driver; struct device *sysdev; struct xhci_hcd *xhci; @@ -242,9 +240,8 @@ static int xhci_plat_probe(struct platform_device *pdev) } xhci = hcd_to_xhci(hcd); - match = of_match_node(usb_xhci_of_match, pdev->dev.of_node); - if (match) { - const struct xhci_plat_priv *priv_match = match->data; + priv_match = of_device_get_match_data(&pdev->dev); + if (priv_match) { struct xhci_plat_priv *priv = hcd_to_xhci_priv(hcd); /* Just copy data for now */ @@ -263,6 +260,9 @@ static int xhci_plat_probe(struct platform_device *pdev) goto disable_clk; } + if (device_property_read_bool(sysdev, "usb2-lpm-disable")) + xhci->quirks |= XHCI_HW_LPM_DISABLE; + if (device_property_read_bool(sysdev, "usb3-lpm-capable")) xhci->quirks |= XHCI_LPM_SUPPORT; diff --git a/drivers/usb/host/xhci-plat.h b/drivers/usb/host/xhci-plat.h index 29b227895b07..ae29f22ff5bd 100644 --- a/drivers/usb/host/xhci-plat.h +++ b/drivers/usb/host/xhci-plat.h @@ -1,11 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0 /* * xhci-plat.h - xHCI host controller driver platform Bus Glue. * * Copyright (C) 2015 Renesas Electronics Corporation - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. */ #ifndef _XHCI_PLAT_H diff --git a/drivers/usb/host/xhci-rcar.c b/drivers/usb/host/xhci-rcar.c index 198bc188ab25..f0b559660007 100644 --- a/drivers/usb/host/xhci-rcar.c +++ b/drivers/usb/host/xhci-rcar.c @@ -1,11 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0 /* * xHCI host controller driver for R-Car SoCs * * Copyright (C) 2014 Renesas Electronics Corporation - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. */ #include <linux/firmware.h> diff --git a/drivers/usb/host/xhci-rcar.h b/drivers/usb/host/xhci-rcar.h index d247951147a1..804b6ab4246f 100644 --- a/drivers/usb/host/xhci-rcar.h +++ b/drivers/usb/host/xhci-rcar.h @@ -1,11 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0 /* * drivers/usb/host/xhci-rcar.h * * Copyright (C) 2014 Renesas Electronics Corporation - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. */ #ifndef _XHCI_RCAR_H diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 82c746e2d85c..c239c688076c 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * xHCI host controller driver * @@ -5,19 +6,6 @@ * * Author: Sarah Sharp * Some code borrowed from the Linux EHCI driver. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* @@ -171,13 +159,13 @@ static void inc_deq(struct xhci_hcd *xhci, struct xhci_ring *ring) if (ring->type == TYPE_EVENT) { if (!last_trb_on_seg(ring->deq_seg, ring->dequeue)) { ring->dequeue++; - return; + goto out; } if (last_trb_on_ring(ring, ring->deq_seg, ring->dequeue)) ring->cycle_state ^= 1; ring->deq_seg = ring->deq_seg->next; ring->dequeue = ring->deq_seg->trbs; - return; + goto out; } /* All other rings have link trbs */ @@ -190,6 +178,7 @@ static void inc_deq(struct xhci_hcd *xhci, struct xhci_ring *ring) ring->dequeue = ring->deq_seg->trbs; } +out: trace_xhci_inc_deq(ring); return; @@ -946,15 +935,12 @@ void xhci_hc_died(struct xhci_hcd *xhci) * Instead we use a combination of that flag and checking if a new timer is * pending. */ -void xhci_stop_endpoint_command_watchdog(unsigned long arg) +void xhci_stop_endpoint_command_watchdog(struct timer_list *t) { - struct xhci_hcd *xhci; - struct xhci_virt_ep *ep; + struct xhci_virt_ep *ep = from_timer(ep, t, stop_cmd_timer); + struct xhci_hcd *xhci = ep->xhci; unsigned long flags; - ep = (struct xhci_virt_ep *) arg; - xhci = ep->xhci; - spin_lock_irqsave(&xhci->lock, flags); /* bail out if cmd completed but raced with stop ep watchdog timer.*/ @@ -1680,9 +1666,14 @@ static void handle_port_status(struct xhci_hcd *xhci, bus_state->resume_done[faked_port_index] = jiffies + msecs_to_jiffies(USB_RESUME_TIMEOUT); set_bit(faked_port_index, &bus_state->resuming_ports); + /* Do the rest in GetPortStatus after resume time delay. + * Avoid polling roothub status before that so that a + * usb device auto-resume latency around ~40ms. + */ + set_bit(HCD_FLAG_POLL_RH, &hcd->flags); mod_timer(&hcd->rh_timer, bus_state->resume_done[faked_port_index]); - /* Do the rest in GetPortStatus */ + bogus_port_status = true; } } diff --git a/drivers/usb/host/xhci-tegra.c b/drivers/usb/host/xhci-tegra.c index 74436f8ca538..2c076ea80522 100644 --- a/drivers/usb/host/xhci-tegra.c +++ b/drivers/usb/host/xhci-tegra.c @@ -1,12 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0 /* * NVIDIA Tegra xHCI host controller driver * * Copyright (C) 2014 NVIDIA Corporation * Copyright (C) 2014 Google, Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. */ #include <linux/clk.h> @@ -771,7 +768,7 @@ static int tegra_xusb_load_firmware(struct tegra_xusb *tegra) struct device *dev = tegra->dev; const struct firmware *fw; unsigned long timeout; - time_t timestamp; + time64_t timestamp; struct tm time; u64 address; u32 value; @@ -877,7 +874,7 @@ static int tegra_xusb_load_firmware(struct tegra_xusb *tegra) } timestamp = le32_to_cpu(header->fwimg_created_time); - time_to_tm(timestamp, 0, &time); + time64_to_tm(timestamp, 0, &time); dev_info(dev, "Firmware timestamp: %ld-%02d-%02d %02d:%02d:%02d UTC\n", time.tm_year + 1900, time.tm_mon + 1, time.tm_mday, diff --git a/drivers/usb/host/xhci-trace.c b/drivers/usb/host/xhci-trace.c index 367b630bdb3c..d0070814d1ea 100644 --- a/drivers/usb/host/xhci-trace.c +++ b/drivers/usb/host/xhci-trace.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * xHCI host controller driver * @@ -5,10 +6,6 @@ * * Author: Xenia Ragiadakou * Email : burzalodowa@gmail.com - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. */ #define CREATE_TRACE_POINTS diff --git a/drivers/usb/host/xhci-trace.h b/drivers/usb/host/xhci-trace.h index f20753b99624..a3b57c781db1 100644 --- a/drivers/usb/host/xhci-trace.h +++ b/drivers/usb/host/xhci-trace.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * xHCI host controller driver * @@ -5,10 +6,6 @@ * * Author: Xenia Ragiadakou * Email : burzalodowa@gmail.com - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. */ #undef TRACE_SYSTEM @@ -388,6 +385,11 @@ DEFINE_EVENT(xhci_log_slot_ctx, xhci_handle_cmd_set_deq, TP_ARGS(ctx) ); +DEFINE_EVENT(xhci_log_slot_ctx, xhci_configure_endpoint, + TP_PROTO(struct xhci_slot_ctx *ctx), + TP_ARGS(ctx) +); + DECLARE_EVENT_CLASS(xhci_log_ring, TP_PROTO(struct xhci_ring *ring), TP_ARGS(ring), diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 51535ba2bcd4..327ba8b8a98b 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * xHCI host controller driver * @@ -5,19 +6,6 @@ * * Author: Sarah Sharp * Some code borrowed from the Linux EHCI driver. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include <linux/pci.h> @@ -32,6 +20,7 @@ #include "xhci.h" #include "xhci-trace.h" #include "xhci-mtk.h" +#include "xhci-debugfs.h" #define DRIVER_AUTHOR "Sarah Sharp" #define DRIVER_DESC "'eXtensible' Host Controller (xHC) Driver" @@ -632,6 +621,9 @@ int xhci_run(struct usb_hcd *hcd) } xhci_dbg_trace(xhci, trace_xhci_dbg_init, "Finished xhci_run for USB2 roothub"); + + xhci_debugfs_init(xhci); + return 0; } EXPORT_SYMBOL_GPL(xhci_run); @@ -660,6 +652,8 @@ static void xhci_stop(struct usb_hcd *hcd) return; } + xhci_debugfs_exit(xhci); + spin_lock_irq(&xhci->lock); xhci->xhc_state |= XHCI_STATE_HALTED; xhci->cmd_ring_state = CMD_RING_STATE_STOPPED; @@ -1600,6 +1594,8 @@ static int xhci_drop_endpoint(struct usb_hcd *hcd, struct usb_device *udev, ctrl_ctx->add_flags &= cpu_to_le32(~drop_flag); new_add_flags = le32_to_cpu(ctrl_ctx->add_flags); + xhci_debugfs_remove_endpoint(xhci, xhci->devs[udev->slot_id], ep_index); + xhci_endpoint_zero(xhci, xhci->devs[udev->slot_id], ep); if (xhci->quirks & XHCI_MTK_HOST) @@ -1723,6 +1719,8 @@ static int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev, /* Store the usb_device pointer for later use */ ep->hcpriv = udev; + xhci_debugfs_create_endpoint(xhci, virt_dev, ep_index); + xhci_dbg(xhci, "add ep 0x%x, slot id %d, new drop flags = %#x, new add flags = %#x\n", (unsigned int) ep->desc.bEndpointAddress, udev->slot_id, @@ -2555,6 +2553,7 @@ static int xhci_configure_endpoint(struct xhci_hcd *xhci, unsigned long flags; struct xhci_input_control_ctx *ctrl_ctx; struct xhci_virt_device *virt_dev; + struct xhci_slot_ctx *slot_ctx; if (!command) return -EINVAL; @@ -2593,6 +2592,9 @@ static int xhci_configure_endpoint(struct xhci_hcd *xhci, return -ENOMEM; } + slot_ctx = xhci_get_slot_ctx(xhci, command->in_ctx); + trace_xhci_configure_endpoint(slot_ctx); + if (!ctx_change) ret = xhci_queue_configure_endpoint(xhci, command, command->in_ctx->dma, @@ -2773,6 +2775,7 @@ static void xhci_reset_bandwidth(struct usb_hcd *hcd, struct usb_device *udev) /* Free any rings allocated for added endpoints */ for (i = 0; i < 31; i++) { if (virt_dev->eps[i].new_ring) { + xhci_debugfs_remove_endpoint(xhci, virt_dev, i); xhci_ring_free(xhci, virt_dev->eps[i].new_ring); virt_dev->eps[i].new_ring = NULL; } @@ -3488,6 +3491,7 @@ static int xhci_discover_or_reset_device(struct usb_hcd *hcd, } if (ep->ring) { + xhci_debugfs_remove_endpoint(xhci, virt_dev, i); xhci_free_endpoint_ring(xhci, virt_dev, i); last_freed_endpoint = i; } @@ -3520,11 +3524,8 @@ static void xhci_free_dev(struct usb_hcd *hcd, struct usb_device *udev) struct xhci_virt_device *virt_dev; struct xhci_slot_ctx *slot_ctx; int i, ret; - struct xhci_command *command; - command = xhci_alloc_command(xhci, false, false, GFP_KERNEL); - if (!command) - return; + xhci_debugfs_remove_slot(xhci, udev->slot_id); #ifndef CONFIG_USB_DEFAULT_PERSIST /* @@ -3540,10 +3541,8 @@ static void xhci_free_dev(struct usb_hcd *hcd, struct usb_device *udev) /* If the host is halted due to driver unload, we still need to free the * device. */ - if (ret <= 0 && ret != -ENODEV) { - kfree(command); + if (ret <= 0 && ret != -ENODEV) return; - } virt_dev = xhci->devs[udev->slot_id]; slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->out_ctx); @@ -3555,26 +3554,19 @@ static void xhci_free_dev(struct usb_hcd *hcd, struct usb_device *udev) del_timer_sync(&virt_dev->eps[i].stop_cmd_timer); } - xhci_disable_slot(xhci, command, udev->slot_id); - /* - * Event command completion handler will free any data structures - * associated with the slot. XXX Can free sleep? - */ + ret = xhci_disable_slot(xhci, udev->slot_id); + if (ret) + xhci_free_virt_device(xhci, udev->slot_id); } -int xhci_disable_slot(struct xhci_hcd *xhci, struct xhci_command *command, - u32 slot_id) +int xhci_disable_slot(struct xhci_hcd *xhci, u32 slot_id) { + struct xhci_command *command; unsigned long flags; u32 state; int ret = 0; - struct xhci_virt_device *virt_dev; - virt_dev = xhci->devs[slot_id]; - if (!virt_dev) - return -EINVAL; - if (!command) - command = xhci_alloc_command(xhci, false, false, GFP_KERNEL); + command = xhci_alloc_command(xhci, false, false, GFP_KERNEL); if (!command) return -ENOMEM; @@ -3583,17 +3575,16 @@ int xhci_disable_slot(struct xhci_hcd *xhci, struct xhci_command *command, state = readl(&xhci->op_regs->status); if (state == 0xffffffff || (xhci->xhc_state & XHCI_STATE_DYING) || (xhci->xhc_state & XHCI_STATE_HALTED)) { - xhci_free_virt_device(xhci, slot_id); spin_unlock_irqrestore(&xhci->lock, flags); kfree(command); - return ret; + return -ENODEV; } ret = xhci_queue_slot_control(xhci, command, TRB_DISABLE_SLOT, slot_id); if (ret) { spin_unlock_irqrestore(&xhci->lock, flags); - xhci_dbg(xhci, "FIXME: allocate a command ring segment\n"); + kfree(command); return ret; } xhci_ring_cmd_db(xhci); @@ -3641,13 +3632,10 @@ int xhci_alloc_dev(struct usb_hcd *hcd, struct usb_device *udev) if (!command) return 0; - /* xhci->slot_id and xhci->addr_dev are not thread-safe */ - mutex_lock(&xhci->mutex); spin_lock_irqsave(&xhci->lock, flags); ret = xhci_queue_slot_control(xhci, command, TRB_ENABLE_SLOT, 0); if (ret) { spin_unlock_irqrestore(&xhci->lock, flags); - mutex_unlock(&xhci->mutex); xhci_dbg(xhci, "FIXME: allocate a command ring segment\n"); xhci_free_command(xhci, command); return 0; @@ -3657,7 +3645,6 @@ int xhci_alloc_dev(struct usb_hcd *hcd, struct usb_device *udev) wait_for_completion(command->completion); slot_id = command->slot_id; - mutex_unlock(&xhci->mutex); if (!slot_id || command->status != COMP_SUCCESS) { xhci_err(xhci, "Error while assigning device slot ID\n"); @@ -3668,6 +3655,8 @@ int xhci_alloc_dev(struct usb_hcd *hcd, struct usb_device *udev) return 0; } + xhci_free_command(xhci, command); + if ((xhci->quirks & XHCI_EP_LIMIT_QUIRK)) { spin_lock_irqsave(&xhci->lock, flags); ret = xhci_reserve_host_control_ep_resources(xhci); @@ -3694,6 +3683,8 @@ int xhci_alloc_dev(struct usb_hcd *hcd, struct usb_device *udev) udev->slot_id = slot_id; + xhci_debugfs_create_slot(xhci, slot_id); + #ifndef CONFIG_USB_DEFAULT_PERSIST /* * If resetting upon resume, we can't put the controller into runtime @@ -3703,18 +3694,16 @@ int xhci_alloc_dev(struct usb_hcd *hcd, struct usb_device *udev) pm_runtime_get_noresume(hcd->self.controller); #endif - - xhci_free_command(xhci, command); /* Is this a LS or FS device under a HS hub? */ /* Hub or peripherial? */ return 1; disable_slot: - /* Disable slot, if we can do it without mem alloc */ - kfree(command->completion); - command->completion = NULL; - command->status = 0; - return xhci_disable_slot(xhci, command, udev->slot_id); + ret = xhci_disable_slot(xhci, udev->slot_id); + if (ret) + xhci_free_virt_device(xhci, udev->slot_id); + + return 0; } /* @@ -3838,8 +3827,14 @@ static int xhci_setup_device(struct usb_hcd *hcd, struct usb_device *udev, break; case COMP_USB_TRANSACTION_ERROR: dev_warn(&udev->dev, "Device not responding to setup %s.\n", act); - ret = -EPROTO; - break; + + mutex_unlock(&xhci->mutex); + ret = xhci_disable_slot(xhci, udev->slot_id); + if (!ret) + xhci_alloc_dev(hcd, udev); + kfree(command->completion); + kfree(command); + return -EPROTO; case COMP_INCOMPATIBLE_DEVICE_ERROR: dev_warn(&udev->dev, "ERROR: Incompatible device for setup %s command\n", act); @@ -4088,7 +4083,7 @@ static int xhci_set_usb2_hardware_lpm(struct usb_hcd *hcd, xhci_dbg(xhci, "%s port %d USB2 hardware LPM\n", enable ? "enable" : "disable", port_num + 1); - if (enable) { + if (enable && !(xhci->quirks & XHCI_HW_LPM_DISABLE)) { /* Host supports BESL timeout instead of HIRD */ if (udev->usb2_hw_lpm_besl_capable) { /* if device doesn't have a preferred BESL value use a @@ -4287,6 +4282,7 @@ static unsigned long long xhci_calculate_intel_u1_timeout( break; } /* Otherwise the calculation is the same as isoc eps */ + /* fall through */ case USB_ENDPOINT_XFER_ISOC: timeout_ns = xhci_service_interval_to_ns(desc); timeout_ns = DIV_ROUND_UP_ULL(timeout_ns * 105, 100); @@ -5005,6 +5001,8 @@ static int __init xhci_hcd_init(void) if (usb_disabled()) return -ENODEV; + xhci_debugfs_create_root(); + return 0; } @@ -5012,7 +5010,10 @@ static int __init xhci_hcd_init(void) * If an init function is provided, an exit function must also be provided * to allow module unload. */ -static void __exit xhci_hcd_fini(void) { } +static void __exit xhci_hcd_fini(void) +{ + xhci_debugfs_remove_root(); +} module_init(xhci_hcd_init); module_exit(xhci_hcd_fini); diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 2b48aa4f6b76..99a014a920d3 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * xHCI host controller driver @@ -6,19 +7,6 @@ * * Author: Sarah Sharp * Some code borrowed from the Linux EHCI driver. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __LINUX_XHCI_HCD_H @@ -131,6 +119,8 @@ struct xhci_cap_regs { /* Extended Capabilities pointer from PCI base - section 5.3.6 */ #define HCC_EXT_CAPS(p) XHCI_HCC_EXT_CAPS(p) +#define CTX_SIZE(_hcc) (HCC_64BYTE_CONTEXT(_hcc) ? 64 : 32) + /* db_off bitmask - bits 0:1 reserved */ #define DBOFF_MASK (~0x3) @@ -1007,6 +997,8 @@ struct xhci_virt_device { struct xhci_tt_bw_info *tt_info; /* The current max exit latency for the enabled USB3 link states. */ u16 current_mel; + /* Used for the debugfs interfaces. */ + void *debugfs_private; }; /* @@ -1830,6 +1822,7 @@ struct xhci_hcd { #define XHCI_LIMIT_ENDPOINT_INTERVAL_7 (1 << 26) /* Reserved. It was XHCI_U2_DISABLE_WAKE */ #define XHCI_ASMEDIA_MODIFY_FLOWCONTROL (1 << 28) +#define XHCI_HW_LPM_DISABLE (1 << 29) unsigned int num_active_eps; unsigned int limit_active_eps; @@ -1859,6 +1852,10 @@ struct xhci_hcd { /* Compliance Mode Timer Triggered every 2 seconds */ #define COMP_MODE_RCVRY_MSECS 2000 + struct dentry *debugfs_root; + struct dentry *debugfs_slots; + struct list_head regset_list; + /* platform-specific data -- must come last */ unsigned long priv[0] __aligned(sizeof(s64)); }; @@ -2012,8 +2009,7 @@ int xhci_run(struct usb_hcd *hcd); int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks); void xhci_init_driver(struct hc_driver *drv, const struct xhci_driver_overrides *over); -int xhci_disable_slot(struct xhci_hcd *xhci, - struct xhci_command *command, u32 slot_id); +int xhci_disable_slot(struct xhci_hcd *xhci, u32 slot_id); int xhci_suspend(struct xhci_hcd *xhci, bool do_wakeup); int xhci_resume(struct xhci_hcd *xhci, bool hibernated); @@ -2068,7 +2064,7 @@ void xhci_queue_new_dequeue_state(struct xhci_hcd *xhci, struct xhci_dequeue_state *deq_state); void xhci_cleanup_stalled_ring(struct xhci_hcd *xhci, unsigned int ep_index, unsigned int stream_id, struct xhci_td *td); -void xhci_stop_endpoint_command_watchdog(unsigned long arg); +void xhci_stop_endpoint_command_watchdog(struct timer_list *t); void xhci_handle_command_timeout(struct work_struct *work); void xhci_ring_ep_doorbell(struct xhci_hcd *xhci, unsigned int slot_id, @@ -2107,6 +2103,7 @@ struct xhci_ep_ctx *xhci_get_ep_ctx(struct xhci_hcd *xhci, struct xhci_container struct xhci_ring *xhci_triad_to_transfer_ring(struct xhci_hcd *xhci, unsigned int slot_id, unsigned int ep_index, unsigned int stream_id); + static inline struct xhci_ring *xhci_urb_to_transfer_ring(struct xhci_hcd *xhci, struct urb *urb) { @@ -2442,11 +2439,12 @@ static inline const char *xhci_decode_portsc(u32 portsc) static char str[256]; int ret; - ret = sprintf(str, "%s %s %s Link:%s ", + ret = sprintf(str, "%s %s %s Link:%s PortSpeed:%d ", portsc & PORT_POWER ? "Powered" : "Powered-off", portsc & PORT_CONNECT ? "Connected" : "Not-connected", portsc & PORT_PE ? "Enabled" : "Disabled", - xhci_portsc_link_state_string(portsc)); + xhci_portsc_link_state_string(portsc), + DEV_PORT_SPEED(portsc)); if (portsc & PORT_OC) ret += sprintf(str + ret, "OverCurrent "); |