usb: fotg210: Compile into one module

It is since ages perfectly possible to compile both of these
modules into the same kernel, which makes no sense since it
is one piece of hardware.

Compile one module named "fotg210.ko" for both HCD and UDC
drivers by collecting the init calls into a fotg210-core.c
file and start to centralize things handling one and the same
piece of hardware.

Stub out the initcalls if one or the other part of the driver
was not selected.

Tested by compiling one or the other or both of the drivers
into the kernel and as modules.

Cc: Fabian Vogt <fabian@ritter-vogt.de>
Cc: Yuan-Hsin Chen <yhchen@faraday-tech.com>
Cc: Felipe Balbi <balbi@kernel.org>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Link: https://lore.kernel.org/r/20221023144708.3596563-2-linus.walleij@linaro.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Linus Walleij 2022-10-23 16:47:07 +02:00 committed by Greg Kroah-Hartman
parent 1dd33a9f1b
commit aeffd2c3b0
6 changed files with 142 additions and 62 deletions

View file

@ -12,7 +12,7 @@ config USB_FOTG210
if USB_FOTG210
config USB_FOTG210_HCD
tristate "Faraday FOTG210 USB Host Controller support"
bool "Faraday FOTG210 USB Host Controller support"
depends on USB
help
Faraday FOTG210 is an OTG controller which can be configured as
@ -24,7 +24,7 @@ config USB_FOTG210_HCD
config USB_FOTG210_UDC
depends on USB_GADGET
tristate "Faraday FOTG210 USB Peripheral Controller support"
bool "Faraday FOTG210 USB Peripheral Controller support"
help
Faraday USB2.0 OTG controller which can be configured as
high speed or full speed USB device. This driver suppports

View file

@ -1,3 +1,10 @@
# SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_USB_FOTG210_HCD) += fotg210-hcd.o
obj-$(CONFIG_USB_FOTG210_UDC) += fotg210-udc.o
# This setup links the different object files into one single
# module so we don't have to EXPORT() a lot of internal symbols
# or create unnecessary submodules.
fotg210-objs-y += fotg210-core.o
fotg210-objs-$(CONFIG_USB_FOTG210_HCD) += fotg210-hcd.o
fotg210-objs-$(CONFIG_USB_FOTG210_UDC) += fotg210-udc.o
fotg210-objs := $(fotg210-objs-y)
obj-$(CONFIG_USB_FOTG210) += fotg210.o

View file

@ -0,0 +1,79 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Central probing code for the FOTG210 dual role driver
* We register one driver for the hardware and then we decide
* whether to proceed with probing the host or the peripheral
* driver.
*/
#include <linux/device.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/usb.h>
#include "fotg210.h"
static int fotg210_probe(struct platform_device *pdev)
{
int ret;
if (IS_ENABLED(CONFIG_USB_FOTG210_HCD)) {
ret = fotg210_hcd_probe(pdev);
if (ret)
return ret;
}
if (IS_ENABLED(CONFIG_USB_FOTG210_UDC))
ret = fotg210_udc_probe(pdev);
return ret;
}
static int fotg210_remove(struct platform_device *pdev)
{
if (IS_ENABLED(CONFIG_USB_FOTG210_HCD))
fotg210_hcd_remove(pdev);
if (IS_ENABLED(CONFIG_USB_FOTG210_UDC))
fotg210_udc_remove(pdev);
return 0;
}
#ifdef CONFIG_OF
static const struct of_device_id fotg210_of_match[] = {
{ .compatible = "faraday,fotg210" },
{},
};
MODULE_DEVICE_TABLE(of, fotg210_of_match);
#endif
static struct platform_driver fotg210_driver = {
.driver = {
.name = "fotg210",
.of_match_table = of_match_ptr(fotg210_of_match),
},
.probe = fotg210_probe,
.remove = fotg210_remove,
};
static int __init fotg210_init(void)
{
if (usb_disabled())
return -ENODEV;
if (IS_ENABLED(CONFIG_USB_FOTG210_HCD))
fotg210_hcd_init();
return platform_driver_register(&fotg210_driver);
}
module_init(fotg210_init);
static void __exit fotg210_cleanup(void)
{
platform_driver_unregister(&fotg210_driver);
if (IS_ENABLED(CONFIG_USB_FOTG210_HCD))
fotg210_hcd_cleanup();
}
module_exit(fotg210_cleanup);
MODULE_AUTHOR("Yuan-Hsin Chen, Feng-Hsin Chiang");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("FOTG210 Dual Role Controller Driver");

View file

@ -39,8 +39,8 @@
#include <asm/irq.h>
#include <asm/unaligned.h>
#define DRIVER_AUTHOR "Yuan-Hsin Chen"
#define DRIVER_DESC "FOTG210 Host Controller (EHCI) Driver"
#include "fotg210.h"
static const char hcd_name[] = "fotg210_hcd";
#undef FOTG210_URB_TRACE
@ -5490,9 +5490,6 @@ static int fotg210_get_frame(struct usb_hcd *hcd)
* functions and in order to facilitate role switching we cannot
* give the fotg210 driver exclusive access to those.
*/
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_LICENSE("GPL");
static const struct hc_driver fotg210_fotg210_hc_driver = {
.description = hcd_name,
@ -5560,7 +5557,7 @@ static void fotg210_init(struct fotg210_hcd *fotg210)
* then invokes the start() method for the HCD associated with it
* through the hotplug entry's driver_data.
*/
static int fotg210_hcd_probe(struct platform_device *pdev)
int fotg210_hcd_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct usb_hcd *hcd;
@ -5652,7 +5649,7 @@ static int fotg210_hcd_probe(struct platform_device *pdev)
* @dev: USB Host Controller being removed
*
*/
static int fotg210_hcd_remove(struct platform_device *pdev)
int fotg210_hcd_remove(struct platform_device *pdev)
{
struct usb_hcd *hcd = platform_get_drvdata(pdev);
struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
@ -5668,27 +5665,8 @@ static int fotg210_hcd_remove(struct platform_device *pdev)
return 0;
}
#ifdef CONFIG_OF
static const struct of_device_id fotg210_of_match[] = {
{ .compatible = "faraday,fotg210" },
{},
};
MODULE_DEVICE_TABLE(of, fotg210_of_match);
#endif
static struct platform_driver fotg210_hcd_driver = {
.driver = {
.name = "fotg210-hcd",
.of_match_table = of_match_ptr(fotg210_of_match),
},
.probe = fotg210_hcd_probe,
.remove = fotg210_hcd_remove,
};
static int __init fotg210_hcd_init(void)
int __init fotg210_hcd_init(void)
{
int retval = 0;
if (usb_disabled())
return -ENODEV;
@ -5704,24 +5682,11 @@ static int __init fotg210_hcd_init(void)
fotg210_debug_root = debugfs_create_dir("fotg210", usb_debug_root);
retval = platform_driver_register(&fotg210_hcd_driver);
if (retval < 0)
goto clean;
return retval;
clean:
debugfs_remove(fotg210_debug_root);
fotg210_debug_root = NULL;
clear_bit(USB_EHCI_LOADED, &usb_hcds_loaded);
return retval;
return 0;
}
module_init(fotg210_hcd_init);
static void __exit fotg210_hcd_cleanup(void)
void __exit fotg210_hcd_cleanup(void)
{
platform_driver_unregister(&fotg210_hcd_driver);
debugfs_remove(fotg210_debug_root);
clear_bit(USB_EHCI_LOADED, &usb_hcds_loaded);
}
module_exit(fotg210_hcd_cleanup);

View file

@ -16,6 +16,7 @@
#include <linux/usb/ch9.h>
#include <linux/usb/gadget.h>
#include "fotg210.h"
#include "fotg210-udc.h"
#define DRIVER_DESC "FOTG210 USB Device Controller Driver"
@ -1068,7 +1069,7 @@ static const struct usb_gadget_ops fotg210_gadget_ops = {
.udc_stop = fotg210_udc_stop,
};
static int fotg210_udc_remove(struct platform_device *pdev)
int fotg210_udc_remove(struct platform_device *pdev)
{
struct fotg210_udc *fotg210 = platform_get_drvdata(pdev);
int i;
@ -1085,7 +1086,7 @@ static int fotg210_udc_remove(struct platform_device *pdev)
return 0;
}
static int fotg210_udc_probe(struct platform_device *pdev)
int fotg210_udc_probe(struct platform_device *pdev)
{
struct resource *res, *ires;
struct fotg210_udc *fotg210 = NULL;
@ -1208,17 +1209,3 @@ static int fotg210_udc_probe(struct platform_device *pdev)
err:
return ret;
}
static struct platform_driver fotg210_driver = {
.driver = {
.name = udc_name,
},
.probe = fotg210_udc_probe,
.remove = fotg210_udc_remove,
};
module_platform_driver(fotg210_driver);
MODULE_AUTHOR("Yuan-Hsin Chen, Feng-Hsin Chiang <john453@faraday-tech.com>");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION(DRIVER_DESC);

View file

@ -0,0 +1,42 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __FOTG210_H
#define __FOTG210_H
#ifdef CONFIG_USB_FOTG210_HCD
int fotg210_hcd_probe(struct platform_device *pdev);
int fotg210_hcd_remove(struct platform_device *pdev);
int fotg210_hcd_init(void);
void fotg210_hcd_cleanup(void);
#else
static inline int fotg210_hcd_probe(struct platform_device *pdev)
{
return 0;
}
static inline int fotg210_hcd_remove(struct platform_device *pdev)
{
return 0;
}
static inline int fotg210_hcd_init(void)
{
return 0;
}
static inline void fotg210_hcd_cleanup(void)
{
}
#endif
#ifdef CONFIG_USB_FOTG210_UDC
int fotg210_udc_probe(struct platform_device *pdev);
int fotg210_udc_remove(struct platform_device *pdev);
#else
static inline int fotg210_udc_probe(struct platform_device *pdev)
{
return 0;
}
static inline int fotg210_udc_remove(struct platform_device *pdev)
{
return 0;
}
#endif
#endif /* __FOTG210_H */