aboutsummaryrefslogtreecommitdiff
path: root/drivers/usb/gadget/dummy_hcd.c
diff options
context:
space:
mode:
authorSebastian Andrzej Siewior <bigeasy@linutronix.de>2012-10-29 18:09:55 +0100
committerFelipe Balbi <balbi@ti.com>2012-10-31 15:17:07 +0200
commitc7a1db457bfca045a0960f4eaaffd6539afbf8d7 (patch)
treeb2d00356f82a46724428b4d1527272249bfd6778 /drivers/usb/gadget/dummy_hcd.c
parentb2113136a5701a7aaffee96c0423e7a620124328 (diff)
usb: gadget: dummy_hcd: add setup / cleanup of multiple HW intances
This patch creates & adds multiple instances of the HCD and UDC. We have a new module option "num" which says how many emulated UDCs + HCDs we want. The default value is one and currently the maximum is one as well. This will change soon. Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Signed-off-by: Felipe Balbi <balbi@ti.com>
Diffstat (limited to 'drivers/usb/gadget/dummy_hcd.c')
-rw-r--r--drivers/usb/gadget/dummy_hcd.c97
1 files changed, 72 insertions, 25 deletions
diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c
index dffcf34d18d..70f70ea133d 100644
--- a/drivers/usb/gadget/dummy_hcd.c
+++ b/drivers/usb/gadget/dummy_hcd.c
@@ -63,16 +63,20 @@ MODULE_LICENSE("GPL");
struct dummy_hcd_module_parameters {
bool is_super_speed;
bool is_high_speed;
+ unsigned int num;
};
static struct dummy_hcd_module_parameters mod_data = {
.is_super_speed = false,
.is_high_speed = true,
+ .num = 1,
};
module_param_named(is_super_speed, mod_data.is_super_speed, bool, S_IRUGO);
MODULE_PARM_DESC(is_super_speed, "true to simulate SuperSpeed connection");
module_param_named(is_high_speed, mod_data.is_high_speed, bool, S_IRUGO);
MODULE_PARM_DESC(is_high_speed, "true to simulate HighSpeed connection");
+module_param_named(num, mod_data.num, uint, S_IRUGO);
+MODULE_PARM_DESC(num, "number of emulated controllers");
/*-------------------------------------------------------------------------*/
/* gadget side driver data structres */
@@ -2634,6 +2638,7 @@ static struct platform_device *the_hcd_pdev[MAX_NUM_UDC];
static int __init init(void)
{
int retval = -ENOMEM;
+ int i;
if (usb_disabled())
return -ENODEV;
@@ -2641,12 +2646,29 @@ static int __init init(void)
if (!mod_data.is_high_speed && mod_data.is_super_speed)
return -EINVAL;
- the_hcd_pdev[0] = platform_device_alloc(driver_name, 0);
- if (!the_hcd_pdev[0])
- return retval;
- the_udc_pdev[0] = platform_device_alloc(gadget_name, 0);
- if (!the_udc_pdev[0])
- goto err_alloc_udc;
+ if (mod_data.num < 1 || mod_data.num > MAX_NUM_UDC) {
+ pr_err("Number of emulated UDC must be in range of 1…%d\n",
+ MAX_NUM_UDC);
+ return -EINVAL;
+ }
+ for (i = 0; i < mod_data.num; i++) {
+ the_hcd_pdev[i] = platform_device_alloc(driver_name, i);
+ if (!the_hcd_pdev[i]) {
+ i--;
+ while (i >= 0)
+ platform_device_put(the_hcd_pdev[i--]);
+ return retval;
+ }
+ }
+ for (i = 0; i < mod_data.num; i++) {
+ the_udc_pdev[i] = platform_device_alloc(gadget_name, i);
+ if (!the_udc_pdev[i]) {
+ i--;
+ while (i >= 0)
+ platform_device_put(the_udc_pdev[i--]);
+ goto err_alloc_udc;
+ }
+ }
retval = platform_driver_register(&dummy_hcd_driver);
if (retval < 0)
@@ -2655,9 +2677,15 @@ static int __init init(void)
if (retval < 0)
goto err_register_udc_driver;
- retval = platform_device_add(the_hcd_pdev[0]);
- if (retval < 0)
- goto err_add_hcd;
+ for (i = 0; i < mod_data.num; i++) {
+ retval = platform_device_add(the_hcd_pdev[i]);
+ if (retval < 0) {
+ i--;
+ while (i >= 0)
+ platform_device_del(the_hcd_pdev[i--]);
+ goto err_add_hcd;
+ }
+ }
if (!the_controller.hs_hcd ||
(!the_controller.ss_hcd && mod_data.is_super_speed)) {
/*
@@ -2667,39 +2695,58 @@ static int __init init(void)
retval = -EINVAL;
goto err_add_udc;
}
- retval = platform_device_add(the_udc_pdev[0]);
- if (retval < 0)
- goto err_add_udc;
- if (!platform_get_drvdata(the_udc_pdev[0])) {
- /*
- * The udc was added successfully but its probe function failed
- * for some reason.
- */
- retval = -EINVAL;
- goto err_probe_udc;
+
+
+ for (i = 0; i < mod_data.num; i++) {
+ retval = platform_device_add(the_udc_pdev[i]);
+ if (retval < 0) {
+ i--;
+ while (i >= 0)
+ platform_device_del(the_udc_pdev[i]);
+ goto err_add_udc;
+ }
+ }
+
+ for (i = 0; i < mod_data.num; i++) {
+ if (!platform_get_drvdata(the_udc_pdev[i])) {
+ /*
+ * The udc was added successfully but its probe
+ * function failed for some reason.
+ */
+ retval = -EINVAL;
+ goto err_probe_udc;
+ }
}
return retval;
err_probe_udc:
- platform_device_del(the_udc_pdev[0]);
+ for (i = 0; i < mod_data.num; i++)
+ platform_device_del(the_udc_pdev[i]);
err_add_udc:
- platform_device_del(the_hcd_pdev[0]);
+ for (i = 0; i < mod_data.num; i++)
+ platform_device_del(the_hcd_pdev[i]);
err_add_hcd:
platform_driver_unregister(&dummy_udc_driver);
err_register_udc_driver:
platform_driver_unregister(&dummy_hcd_driver);
err_register_hcd_driver:
- platform_device_put(the_udc_pdev[0]);
+ for (i = 0; i < mod_data.num; i++)
+ platform_device_put(the_udc_pdev[i]);
err_alloc_udc:
- platform_device_put(the_hcd_pdev[0]);
+ for (i = 0; i < mod_data.num; i++)
+ platform_device_put(the_hcd_pdev[i]);
return retval;
}
module_init(init);
static void __exit cleanup(void)
{
- platform_device_unregister(the_udc_pdev[0]);
- platform_device_unregister(the_hcd_pdev[0]);
+ int i;
+
+ for (i = 0; i < mod_data.num; i++) {
+ platform_device_unregister(the_udc_pdev[i]);
+ platform_device_unregister(the_hcd_pdev[i]);
+ }
platform_driver_unregister(&dummy_udc_driver);
platform_driver_unregister(&dummy_hcd_driver);
}