Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 01cced25 authored by Kumar Gala's avatar Kumar Gala Committed by Greg Kroah-Hartman
Browse files

[PATCH] USB: allow multiple types of EHCI controllers to be built as modules



In some systems we may have both a platform EHCI controller and PCI EHCI
controller.  Previously we couldn't build the EHCI support as a module due
to conflicting module_init() calls in the code.

Signed-off-by: default avatarKumar Gala <galak@kernel.crashing.org>
Signed-off-by: default avatarDavid Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent df47e533
Loading
Loading
Loading
Loading
+26 −40
Original line number Diff line number Diff line
@@ -372,7 +372,7 @@ static int __init fsl_usb_of_init(void)
{
	struct device_node *np;
	unsigned int i;
	struct platform_device *usb_dev;
	struct platform_device *usb_dev_mph = NULL, *usb_dev_dr = NULL;
	int ret;

	for (np = NULL, i = 0;
@@ -393,15 +393,15 @@ static int __init fsl_usb_of_init(void)
		r[1].end = np->intrs[0].line;
		r[1].flags = IORESOURCE_IRQ;

		usb_dev =
		    platform_device_register_simple("fsl-usb2-mph", i, r, 2);
		if (IS_ERR(usb_dev)) {
			ret = PTR_ERR(usb_dev);
		usb_dev_mph =
		    platform_device_register_simple("fsl-ehci", i, r, 2);
		if (IS_ERR(usb_dev_mph)) {
			ret = PTR_ERR(usb_dev_mph);
			goto err;
		}

		usb_dev->dev.coherent_dma_mask = 0xffffffffUL;
		usb_dev->dev.dma_mask = &usb_dev->dev.coherent_dma_mask;
		usb_dev_mph->dev.coherent_dma_mask = 0xffffffffUL;
		usb_dev_mph->dev.dma_mask = &usb_dev_mph->dev.coherent_dma_mask;

		usb_data.operating_mode = FSL_USB2_MPH_HOST;

@@ -417,31 +417,14 @@ static int __init fsl_usb_of_init(void)
		usb_data.phy_mode = determine_usb_phy(prop);

		ret =
		    platform_device_add_data(usb_dev, &usb_data,
		    platform_device_add_data(usb_dev_mph, &usb_data,
					     sizeof(struct
						    fsl_usb2_platform_data));
		if (ret)
			goto unreg;
			goto unreg_mph;
	}

	return 0;

unreg:
	platform_device_unregister(usb_dev);
err:
	return ret;
}

arch_initcall(fsl_usb_of_init);

static int __init fsl_usb_dr_of_init(void)
{
	struct device_node *np;
	unsigned int i;
	struct platform_device *usb_dev;
	int ret;

	for (np = NULL, i = 0;
	for (np = NULL;
	     (np = of_find_compatible_node(np, "usb", "fsl-usb2-dr")) != NULL;
	     i++) {
		struct resource r[2];
@@ -453,21 +436,21 @@ static int __init fsl_usb_dr_of_init(void)

		ret = of_address_to_resource(np, 0, &r[0]);
		if (ret)
			goto err;
			goto unreg_mph;

		r[1].start = np->intrs[0].line;
		r[1].end = np->intrs[0].line;
		r[1].flags = IORESOURCE_IRQ;

		usb_dev =
		    platform_device_register_simple("fsl-usb2-dr", i, r, 2);
		if (IS_ERR(usb_dev)) {
			ret = PTR_ERR(usb_dev);
		usb_dev_dr =
		    platform_device_register_simple("fsl-ehci", i, r, 2);
		if (IS_ERR(usb_dev_dr)) {
			ret = PTR_ERR(usb_dev_dr);
			goto err;
		}

		usb_dev->dev.coherent_dma_mask = 0xffffffffUL;
		usb_dev->dev.dma_mask = &usb_dev->dev.coherent_dma_mask;
		usb_dev_dr->dev.coherent_dma_mask = 0xffffffffUL;
		usb_dev_dr->dev.dma_mask = &usb_dev_dr->dev.coherent_dma_mask;

		usb_data.operating_mode = FSL_USB2_DR_HOST;

@@ -475,19 +458,22 @@ static int __init fsl_usb_dr_of_init(void)
		usb_data.phy_mode = determine_usb_phy(prop);

		ret =
		    platform_device_add_data(usb_dev, &usb_data,
		    platform_device_add_data(usb_dev_dr, &usb_data,
					     sizeof(struct
						    fsl_usb2_platform_data));
		if (ret)
			goto unreg;
			goto unreg_dr;
	}

	return 0;

unreg:
	platform_device_unregister(usb_dev);
unreg_dr:
	if (usb_dev_dr)
		platform_device_unregister(usb_dev_dr);
unreg_mph:
	if (usb_dev_mph)
		platform_device_unregister(usb_dev_mph);
err:
	return ret;
}

arch_initcall(fsl_usb_dr_of_init);
arch_initcall(fsl_usb_of_init);
+3 −3
Original line number Diff line number Diff line
@@ -186,7 +186,7 @@ struct platform_device ppc_sys_platform_devices[] = {
		},
	},
	[MPC83xx_USB2_DR] = {
		.name = "fsl-usb2-dr",
		.name = "fsl-ehci",
		.id	= 1,
		.num_resources	 = 2,
		.resource = (struct resource[]) {
@@ -203,8 +203,8 @@ struct platform_device ppc_sys_platform_devices[] = {
		},
	},
	[MPC83xx_USB2_MPH] = {
		.name = "fsl-usb2-mph",
		.id	= 1,
		.name = "fsl-ehci",
		.id	= 2,
		.num_resources	 = 2,
		.resource = (struct resource[]) {
			{
+2 −15
Original line number Diff line number Diff line
@@ -272,6 +272,8 @@ static int ehci_hcd_au1xxx_drv_resume(struct device *dev)
	return 0;
}
*/
MODULE_ALIAS("au1xxx-ehci");
/* FIXME use "struct platform_driver" */
static struct device_driver ehci_hcd_au1xxx_driver = {
	.name = "au1xxx-ehci",
	.bus = &platform_bus_type,
@@ -280,18 +282,3 @@ static struct device_driver ehci_hcd_au1xxx_driver = {
	/*.suspend      = ehci_hcd_au1xxx_drv_suspend, */
	/*.resume       = ehci_hcd_au1xxx_drv_resume, */
};

static int __init ehci_hcd_au1xxx_init(void)
{
	pr_debug(DRIVER_INFO " (Au1xxx)\n");

	return driver_register(&ehci_hcd_au1xxx_driver);
}

static void __exit ehci_hcd_au1xxx_cleanup(void)
{
	driver_unregister(&ehci_hcd_au1xxx_driver);
}

module_init(ehci_hcd_au1xxx_init);
module_exit(ehci_hcd_au1xxx_cleanup);
+3 −34
Original line number Diff line number Diff line
@@ -324,43 +324,12 @@ static int ehci_fsl_drv_remove(struct platform_device *pdev)
	return 0;
}

static struct platform_driver ehci_fsl_dr_driver = {
	.probe = ehci_fsl_drv_probe,
	.remove = ehci_fsl_drv_remove,
	.driver = {
		   .name = "fsl-usb2-dr",
		   },
};
MODULE_ALIAS("fsl-ehci");

static struct platform_driver ehci_fsl_mph_driver = {
static struct platform_driver ehci_fsl_driver = {
	.probe = ehci_fsl_drv_probe,
	.remove = ehci_fsl_drv_remove,
	.driver = {
		   .name = "fsl-usb2-mph",
		   .name = "fsl-ehci",
		   },
};

static int __init ehci_fsl_init(void)
{
	int retval;

	pr_debug("%s: block sizes: qh %Zd qtd %Zd itd %Zd sitd %Zd\n",
		 hcd_name,
		 sizeof(struct ehci_qh), sizeof(struct ehci_qtd),
		 sizeof(struct ehci_itd), sizeof(struct ehci_sitd));

	retval = platform_driver_register(&ehci_fsl_dr_driver);
	if (retval)
		return retval;

	return platform_driver_register(&ehci_fsl_mph_driver);
}

static void __exit ehci_fsl_cleanup(void)
{
	platform_driver_unregister(&ehci_fsl_mph_driver);
	platform_driver_unregister(&ehci_fsl_dr_driver);
}

module_init(ehci_fsl_init);
module_exit(ehci_fsl_cleanup);
+44 −4
Original line number Diff line number Diff line
@@ -889,19 +889,59 @@ MODULE_LICENSE ("GPL");

#ifdef CONFIG_PCI
#include "ehci-pci.c"
#define	EHCI_BUS_GLUED
#define	PCI_DRIVER		ehci_pci_driver
#endif

#ifdef CONFIG_PPC_83xx
#include "ehci-fsl.c"
#define	EHCI_BUS_GLUED
#define	PLATFORM_DRIVER		ehci_fsl_driver
#endif

#ifdef CONFIG_SOC_AU1X00
#include "ehci-au1xxx.c"
#define	EHCI_BUS_GLUED
#define	PLATFORM_DRIVER		ehci_hcd_au1xxx_driver
#endif

#ifndef	EHCI_BUS_GLUED
#if !defined(PCI_DRIVER) && !defined(PLATFORM_DRIVER)
#error "missing bus glue for ehci-hcd"
#endif

static int __init ehci_hcd_init(void)
{
	int retval = 0;

	pr_debug("%s: block sizes: qh %Zd qtd %Zd itd %Zd sitd %Zd\n",
		 hcd_name,
		 sizeof(struct ehci_qh), sizeof(struct ehci_qtd),
		 sizeof(struct ehci_itd), sizeof(struct ehci_sitd));

#ifdef PLATFORM_DRIVER
	retval = platform_driver_register(&PLATFORM_DRIVER);
	if (retval < 0)
		return retval;
#endif

#ifdef PCI_DRIVER
	retval = pci_register_driver(&PCI_DRIVER);
	if (retval < 0) {
#ifdef PLATFORM_DRIVER
		platform_driver_unregister(&PLATFORM_DRIVER);
#endif
	}
#endif

	return retval;
}
module_init(ehci_hcd_init);

static void __exit ehci_hcd_cleanup(void)
{
#ifdef PLATFORM_DRIVER
	platform_driver_unregister(&PLATFORM_DRIVER);
#endif
#ifdef PCI_DRIVER
	pci_unregister_driver(&PCI_DRIVER);
#endif
}
module_exit(ehci_hcd_cleanup);
Loading