Commit ec5499d3 authored by Arnd Bergmann's avatar Arnd Bergmann Committed by Greg Kroah-Hartman
Browse files

xhci: split out rcar/rz support from xhci-plat.c



The USB_XHCI_RZV2M and USB_RENESAS_USB3 select other drivers
based on the enabled SoC types, which leads to build failures
when the dependencies are not met:

WARNING: unmet direct dependencies detected for USB_RZV2M_USB3DRD
  Depends on [n]: USB_SUPPORT [=y] && USB_GADGET [=n] && (ARCH_R9A09G011 [=n] || COMPILE_TEST [=y])
  Selected by [m]:
  - USB_XHCI_RZV2M [=m] && USB_SUPPORT [=y] && USB [=y] && USB_XHCI_HCD [=m] && USB_XHCI_PLATFORM [=m] && (ARCH_R9A09G011 [=n] || COMPILE_TEST [=y])
ERROR: modpost: "rzv2m_usb3drd_reset" [drivers/usb/host/xhci-plat-hcd.ko] undefined!

The xhci-rcar driver has a reverse dependency with the xhci core, and it
depends on the UDC driver in turn. To untangle this, make the xhci-rcar.ko
driver a standalone module that just calls into the xhci-plat.ko module
like other drivers do.

This allows handling the dependency on the USB_RZV2M_USB3DRD driver to
only affect the xhci-rcar module and simplify the xhci-plat module.

It also allows leaving out the hacks for broken dma mask and nested
devices from the rcar side and keep that only in the generic xhci driver.

As a future cleanup, the marvell and dwc3 specific bits of xhci-plat.c
could be moved out as well, but that is not required for this bugfix.

Fixes: c52c9acc ("xhci: host: Add Renesas RZ/V2M SoC support")
Signed-off-by: default avatarArnd Bergmann <arnd@arndb.de>
Tested-by: default avatarBiju Das <biju.das.jz@bp.renesas.com>
Link: https://lore.kernel.org/r/20230131150531.12347-1-arnd@kernel.org


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent ba883de9
Loading
Loading
Loading
Loading
+1 −3
Original line number Diff line number Diff line
@@ -183,8 +183,6 @@ config USB_RENESAS_USBHS_UDC
config USB_RZV2M_USB3DRD
	tristate 'Renesas USB3.1 DRD controller'
	depends on ARCH_R9A09G011 || COMPILE_TEST
	default USB_XHCI_RZV2M
	default USB_RENESAS_USB3
	help
	   Renesas USB3.1 DRD controller is a USB DRD controller
	   that supports both host and device switching.
@@ -195,8 +193,8 @@ config USB_RZV2M_USB3DRD
config USB_RENESAS_USB3
	tristate 'Renesas USB3.0 Peripheral controller'
	depends on ARCH_RENESAS || COMPILE_TEST
	depends on USB_RZV2M_USB3DRD || !USB_RZV2M_USB3DRD
	depends on EXTCON
	select USB_RZV2M_USB3DRD if ARCH_R9A09G011
	select USB_ROLE_SWITCH
	help
	   Renesas USB3.0 Peripheral controller is a USB peripheral controller
+4 −5
Original line number Diff line number Diff line
@@ -53,8 +53,6 @@ config USB_XHCI_PCI_RENESAS

config USB_XHCI_PLATFORM
	tristate "Generic xHCI driver for a platform device"
	select USB_XHCI_RCAR if ARCH_RENESAS
	select USB_XHCI_RZV2M if ARCH_R9A09G011
	help
	  Adds an xHCI host driver for a generic platform device, which
	  provides a memory space and an irq.
@@ -92,15 +90,16 @@ config USB_XHCI_RCAR
	tristate "xHCI support for Renesas R-Car SoCs"
	depends on USB_XHCI_PLATFORM
	depends on ARCH_RENESAS || COMPILE_TEST
	default ARCH_RENESAS
	help
	  Say 'Y' to enable the support for the xHCI host controller
	  found in Renesas R-Car ARM SoCs.

config USB_XHCI_RZV2M
	tristate "xHCI support for Renesas RZ/V2M SoC"
	depends on USB_XHCI_PLATFORM
	bool "xHCI support for Renesas RZ/V2M SoC"
	depends on USB_XHCI_RCAR
	depends on ARCH_R9A09G011 || COMPILE_TEST
	select USB_RZV2M_USB3DRD
	depends on USB_RZV2M_USB3DRD=y || (USB_RZV2M_USB3DRD=USB_XHCI_RCAR)
	help
	  Say 'Y' to enable the support for the xHCI host controller
	  found in Renesas RZ/V2M SoC.
+4 −7
Original line number Diff line number Diff line
@@ -25,17 +25,13 @@ xhci-plat-hcd-y := xhci-plat.o
ifneq ($(CONFIG_USB_XHCI_MVEBU), )
	xhci-plat-hcd-y		+= xhci-mvebu.o
endif
ifneq ($(CONFIG_USB_XHCI_RCAR), )
	xhci-plat-hcd-y		+= xhci-rcar.o
endif
ifneq ($(CONFIG_USB_XHCI_RZV2M), )
	xhci-plat-hcd-y		+= xhci-rzv2m.o
endif

ifneq ($(CONFIG_DEBUG_FS),)
	xhci-hcd-y		+= xhci-debugfs.o
endif

xhci-rcar-hcd-y				+= xhci-rcar.o
xhci-rcar-hcd-$(CONFIG_USB_XHCI_RZV2M)	+= xhci-rzv2m.o

obj-$(CONFIG_USB_PCI)	+= pci-quirks.o

obj-$(CONFIG_USB_EHCI_HCD)	+= ehci-hcd.o
@@ -75,6 +71,7 @@ obj-$(CONFIG_USB_XHCI_PCI) += xhci-pci.o
obj-$(CONFIG_USB_XHCI_PCI_RENESAS)	+= xhci-pci-renesas.o
obj-$(CONFIG_USB_XHCI_PLATFORM) += xhci-plat-hcd.o
obj-$(CONFIG_USB_XHCI_HISTB)	+= xhci-histb.o
obj-$(CONFIG_USB_XHCI_RCAR)	+= xhci-rcar-hcd.o
obj-$(CONFIG_USB_XHCI_MTK)	+= xhci-mtk-hcd.o
obj-$(CONFIG_USB_XHCI_TEGRA)	+= xhci-tegra.o
obj-$(CONFIG_USB_SL811_HCD)	+= sl811-hcd.o
+50 −77
Original line number Diff line number Diff line
@@ -24,8 +24,6 @@
#include "xhci.h"
#include "xhci-plat.h"
#include "xhci-mvebu.h"
#include "xhci-rcar.h"
#include "xhci-rzv2m.h"

static struct hc_driver __read_mostly xhci_plat_hc_driver;

@@ -116,21 +114,6 @@ static const struct xhci_plat_priv xhci_plat_marvell_armada3700 = {
	.init_quirk = xhci_mvebu_a3700_init_quirk,
};

static const struct xhci_plat_priv xhci_plat_renesas_rcar_gen2 = {
	SET_XHCI_PLAT_PRIV_FOR_RCAR(XHCI_RCAR_FIRMWARE_NAME_V1)
};

static const struct xhci_plat_priv xhci_plat_renesas_rcar_gen3 = {
	SET_XHCI_PLAT_PRIV_FOR_RCAR(XHCI_RCAR_FIRMWARE_NAME_V3)
};

static const struct xhci_plat_priv xhci_plat_renesas_rzv2m = {
	.quirks = XHCI_NO_64BIT_SUPPORT | XHCI_TRUST_TX_LENGTH |
		  XHCI_SLOW_SUSPEND,
	.init_quirk = xhci_rzv2m_init_quirk,
	.plat_start = xhci_rzv2m_start,
};

static const struct xhci_plat_priv xhci_plat_brcm = {
	.quirks = XHCI_RESET_ON_RESUME | XHCI_SUSPEND_RESUME_CLKS,
};
@@ -149,30 +132,6 @@ static const struct of_device_id usb_xhci_of_match[] = {
	}, {
		.compatible = "marvell,armada3700-xhci",
		.data = &xhci_plat_marvell_armada3700,
	}, {
		.compatible = "renesas,xhci-r8a7790",
		.data = &xhci_plat_renesas_rcar_gen2,
	}, {
		.compatible = "renesas,xhci-r8a7791",
		.data = &xhci_plat_renesas_rcar_gen2,
	}, {
		.compatible = "renesas,xhci-r8a7793",
		.data = &xhci_plat_renesas_rcar_gen2,
	}, {
		.compatible = "renesas,xhci-r8a7795",
		.data = &xhci_plat_renesas_rcar_gen3,
	}, {
		.compatible = "renesas,xhci-r8a7796",
		.data = &xhci_plat_renesas_rcar_gen3,
	}, {
		.compatible = "renesas,rcar-gen2-xhci",
		.data = &xhci_plat_renesas_rcar_gen2,
	}, {
		.compatible = "renesas,rcar-gen3-xhci",
		.data = &xhci_plat_renesas_rcar_gen3,
	}, {
		.compatible = "renesas,rzv2m-xhci",
		.data = &xhci_plat_renesas_rzv2m,
	}, {
		.compatible = "brcm,xhci-brcm-v2",
		.data = &xhci_plat_brcm,
@@ -185,11 +144,10 @@ static const struct of_device_id usb_xhci_of_match[] = {
MODULE_DEVICE_TABLE(of, usb_xhci_of_match);
#endif

static int xhci_plat_probe(struct platform_device *pdev)
int xhci_plat_probe(struct platform_device *pdev, struct device *sysdev, const struct xhci_plat_priv *priv_match)
{
	const struct xhci_plat_priv *priv_match;
	const struct hc_driver	*driver;
	struct device		*sysdev, *tmpdev;
	struct device		*tmpdev;
	struct xhci_hcd		*xhci;
	struct resource         *res;
	struct usb_hcd		*hcd, *usb3_hcd;
@@ -207,30 +165,9 @@ static int xhci_plat_probe(struct platform_device *pdev)
	if (irq < 0)
		return irq;

	/*
	 * sysdev must point to a device that is known to the system firmware
	 * or PCI hardware. We handle these three cases here:
	 * 1. xhci_plat comes from firmware
	 * 2. xhci_plat is child of a device from firmware (dwc3-plat)
	 * 3. xhci_plat is grandchild of a pci device (dwc3-pci)
	 */
	for (sysdev = &pdev->dev; sysdev; sysdev = sysdev->parent) {
		if (is_of_node(sysdev->fwnode) ||
			is_acpi_device_node(sysdev->fwnode))
			break;
#ifdef CONFIG_PCI
		else if (sysdev->bus == &pci_bus_type)
			break;
#endif
	}

	if (!sysdev)
		sysdev = &pdev->dev;

	if (WARN_ON(!sysdev->dma_mask))
		/* Platform did not initialize dma_mask */
		ret = dma_coerce_mask_and_coherent(sysdev, DMA_BIT_MASK(64));
	else
	ret = dma_set_mask_and_coherent(sysdev, DMA_BIT_MASK(64));
	if (ret)
		return ret;
@@ -293,11 +230,6 @@ static int xhci_plat_probe(struct platform_device *pdev)
	if (ret)
		goto disable_reg_clk;

	if (pdev->dev.of_node)
		priv_match = of_device_get_match_data(&pdev->dev);
	else
		priv_match = dev_get_platdata(&pdev->dev);

	if (priv_match) {
		priv = hcd_to_xhci_priv(hcd);
		/* Just copy data for now */
@@ -411,8 +343,47 @@ static int xhci_plat_probe(struct platform_device *pdev)

	return ret;
}
EXPORT_SYMBOL_GPL(xhci_plat_probe);

static int xhci_generic_plat_probe(struct platform_device *pdev)
{
	const struct xhci_plat_priv *priv_match;
	struct device *sysdev;
	int ret;

	/*
	 * sysdev must point to a device that is known to the system firmware
	 * or PCI hardware. We handle these three cases here:
	 * 1. xhci_plat comes from firmware
	 * 2. xhci_plat is child of a device from firmware (dwc3-plat)
	 * 3. xhci_plat is grandchild of a pci device (dwc3-pci)
	 */
	for (sysdev = &pdev->dev; sysdev; sysdev = sysdev->parent) {
		if (is_of_node(sysdev->fwnode) ||
			is_acpi_device_node(sysdev->fwnode))
			break;
#ifdef CONFIG_PCI
		else if (sysdev->bus == &pci_bus_type)
			break;
#endif
	}

	if (WARN_ON(!sysdev->dma_mask)) {
		/* Platform did not initialize dma_mask */
		ret = dma_coerce_mask_and_coherent(sysdev, DMA_BIT_MASK(64));
		if (ret)
			return ret;
	}

	if (pdev->dev.of_node)
		priv_match = of_device_get_match_data(&pdev->dev);
	else
		priv_match = dev_get_platdata(&pdev->dev);

	return xhci_plat_probe(pdev, sysdev, priv_match);
}

static int xhci_plat_remove(struct platform_device *dev)
int xhci_plat_remove(struct platform_device *dev)
{
	struct usb_hcd	*hcd = platform_get_drvdata(dev);
	struct xhci_hcd	*xhci = hcd_to_xhci(hcd);
@@ -446,6 +417,7 @@ static int xhci_plat_remove(struct platform_device *dev)

	return 0;
}
EXPORT_SYMBOL_GPL(xhci_plat_remove);

static int __maybe_unused xhci_plat_suspend(struct device *dev)
{
@@ -522,13 +494,14 @@ static int __maybe_unused xhci_plat_runtime_resume(struct device *dev)
	return xhci_resume(xhci, 0);
}

static const struct dev_pm_ops xhci_plat_pm_ops = {
const struct dev_pm_ops xhci_plat_pm_ops = {
	SET_SYSTEM_SLEEP_PM_OPS(xhci_plat_suspend, xhci_plat_resume)

	SET_RUNTIME_PM_OPS(xhci_plat_runtime_suspend,
			   xhci_plat_runtime_resume,
			   NULL)
};
EXPORT_SYMBOL_GPL(xhci_plat_pm_ops);

#ifdef CONFIG_ACPI
static const struct acpi_device_id usb_xhci_acpi_match[] = {
@@ -539,8 +512,8 @@ static const struct acpi_device_id usb_xhci_acpi_match[] = {
MODULE_DEVICE_TABLE(acpi, usb_xhci_acpi_match);
#endif

static struct platform_driver usb_xhci_driver = {
	.probe	= xhci_plat_probe,
static struct platform_driver usb_generic_xhci_driver = {
	.probe	= xhci_generic_plat_probe,
	.remove	= xhci_plat_remove,
	.shutdown = usb_hcd_platform_shutdown,
	.driver	= {
@@ -555,13 +528,13 @@ MODULE_ALIAS("platform:xhci-hcd");
static int __init xhci_plat_init(void)
{
	xhci_init_driver(&xhci_plat_hc_driver, &xhci_plat_overrides);
	return platform_driver_register(&usb_xhci_driver);
	return platform_driver_register(&usb_generic_xhci_driver);
}
module_init(xhci_plat_init);

static void __exit xhci_plat_exit(void)
{
	platform_driver_unregister(&usb_xhci_driver);
	platform_driver_unregister(&usb_generic_xhci_driver);
}
module_exit(xhci_plat_exit);

+7 −0
Original line number Diff line number Diff line
@@ -21,4 +21,11 @@ struct xhci_plat_priv {

#define hcd_to_xhci_priv(h) ((struct xhci_plat_priv *)hcd_to_xhci(h)->priv)
#define xhci_to_priv(x) ((struct xhci_plat_priv *)(x)->priv)

int xhci_plat_probe(struct platform_device *pdev, struct device *sysdev,
		    const struct xhci_plat_priv *priv_match);

int xhci_plat_remove(struct platform_device *dev);
extern const struct dev_pm_ops xhci_plat_pm_ops;

#endif	/* _XHCI_PLAT_H */
Loading