Merge changes I71923764,I0a311bac into msm-3.0

* changes:
  usb: gadget: allow android gadget to bind/unbind several times
  usb: gadget: ci13xxx_msm: allow to be loaded/unloaded as module
This commit is contained in:
Linux Build Service Account
2012-03-25 06:22:34 -07:00
committed by QuIC Gerrit Code Review
3 changed files with 104 additions and 43 deletions
+65 -32
View File
@@ -470,7 +470,7 @@ static int serial_function_bind_config(struct android_usb_function *f,
}
bind_config:
for (i = 0; i < ports; i++) {
for (i = 0; i < ports; i++) {
err = gser_bind_config(c, i);
if (err) {
pr_err("serial: bind_config failed for port %d", i);
@@ -989,6 +989,31 @@ static struct android_usb_function *supported_functions[] = {
NULL
};
static void android_cleanup_functions(struct android_usb_function **functions)
{
struct android_usb_function *f;
struct device_attribute **attrs;
struct device_attribute *attr;
while (*functions) {
f = *functions++;
if (f->dev) {
device_destroy(android_class, f->dev->devt);
kfree(f->dev_name);
} else
continue;
if (f->cleanup)
f->cleanup(f);
attrs = f->attributes;
if (attrs) {
while ((attr = *attrs++))
device_remove_file(f->dev, attr);
}
}
}
static int android_init_functions(struct android_usb_function **functions,
struct usb_composite_dev *cdev)
@@ -998,16 +1023,21 @@ static int android_init_functions(struct android_usb_function **functions,
struct device_attribute **attrs;
struct device_attribute *attr;
int err = 0;
int index = 0;
int index = 1; /* index 0 is for android0 device */
for (; (f = *functions++); index++) {
f->dev_name = kasprintf(GFP_KERNEL, "f_%s", f->name);
if (!f->dev_name) {
err = -ENOMEM;
goto err_out;
}
f->dev = device_create(android_class, dev->dev,
MKDEV(0, index), f, f->dev_name);
if (IS_ERR(f->dev)) {
pr_err("%s: Failed to create dev %s", __func__,
f->dev_name);
err = PTR_ERR(f->dev);
f->dev = NULL;
goto err_create;
}
@@ -1016,7 +1046,7 @@ static int android_init_functions(struct android_usb_function **functions,
if (err) {
pr_err("%s: Failed to init %s", __func__,
f->name);
goto err_out;
goto err_init;
}
}
@@ -1028,35 +1058,26 @@ static int android_init_functions(struct android_usb_function **functions,
if (err) {
pr_err("%s: Failed to create function %s attributes",
__func__, f->name);
goto err_out;
goto err_attrs;
}
}
return 0;
err_out:
err_attrs:
for (attr = *(attrs -= 2); attrs != f->attributes; attr = *(attrs--))
device_remove_file(f->dev, attr);
if (f->cleanup)
f->cleanup(f);
err_init:
device_destroy(android_class, f->dev->devt);
err_create:
f->dev = NULL;
kfree(f->dev_name);
err_out:
android_cleanup_functions(dev->functions);
return err;
}
static void android_cleanup_functions(struct android_usb_function **functions)
{
struct android_usb_function *f;
while (*functions) {
f = *functions++;
if (f->dev) {
device_destroy(android_class, f->dev->devt);
kfree(f->dev_name);
}
if (f->cleanup)
f->cleanup(f);
}
}
static int
android_bind_enabled_functions(struct android_dev *dev,
struct usb_configuration *c)
@@ -1393,6 +1414,9 @@ static int android_usb_unbind(struct usb_composite_dev *cdev)
{
struct android_dev *dev = _android_dev;
manufacturer_string[0] = '\0';
product_string[0] = '\0';
serial_string[0] = '0';
cancel_work_sync(&dev->work);
android_cleanup_functions(dev->functions);
return 0;
@@ -1502,15 +1526,29 @@ static int __devinit android_probe(struct platform_device *pdev)
{
struct android_usb_platform_data *pdata = pdev->dev.platform_data;
struct android_dev *dev = _android_dev;
int ret = 0;
dev->pdata = pdata;
ret = usb_composite_probe(&android_usb_driver, android_bind);
if (ret) {
pr_err("%s(): Failed to register android "
"composite driver\n", __func__);
}
return ret;
}
static int android_remove(struct platform_device *pdev)
{
usb_composite_unregister(&android_usb_driver);
return 0;
}
static struct platform_driver android_platform_driver = {
.probe = android_probe,
.driver = { .name = "android_usb"},
.probe = android_probe,
.remove = android_remove,
};
static int __init init(void)
@@ -1550,13 +1588,7 @@ static int __init init(void)
"platform driver\n", __func__);
goto err_probe;
}
ret = usb_composite_probe(&android_usb_driver, android_bind);
if (ret) {
pr_err("%s(): Failed to register android"
"composite driver\n", __func__);
platform_driver_unregister(&android_platform_driver);
goto err_probe;
}
return ret;
err_probe:
@@ -1570,9 +1602,10 @@ module_init(init);
static void __exit cleanup(void)
{
usb_composite_unregister(&android_usb_driver);
class_destroy(android_class);
platform_driver_unregister(&android_platform_driver);
android_destroy_device(_android_dev);
kfree(_android_dev);
class_destroy(android_class);
_android_dev = NULL;
}
module_exit(cleanup);
+33 -10
View File
@@ -1,4 +1,4 @@
/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
/* Copyright (c) 2010-2012, Code Aurora Forum. 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 version 2 and
@@ -21,6 +21,12 @@
#define MSM_USB_BASE (udc->regs)
struct ci13xxx_udc_context {
int irq;
void __iomem *regs;
};
static struct ci13xxx_udc_context _udc_ctxt;
static irqreturn_t msm_udc_irq(int irq, void *data)
{
return udc_irq();
@@ -56,8 +62,6 @@ static struct ci13xxx_udc_driver ci13xxx_msm_udc_driver = {
static int ci13xxx_msm_probe(struct platform_device *pdev)
{
struct resource *res;
void __iomem *regs;
int irq;
int ret;
dev_dbg(&pdev->dev, "ci13xxx_msm_probe\n");
@@ -68,26 +72,27 @@ static int ci13xxx_msm_probe(struct platform_device *pdev)
return -ENXIO;
}
regs = ioremap(res->start, resource_size(res));
if (!regs) {
_udc_ctxt.regs = ioremap(res->start, resource_size(res));
if (!_udc_ctxt.regs) {
dev_err(&pdev->dev, "ioremap failed\n");
return -ENOMEM;
}
ret = udc_probe(&ci13xxx_msm_udc_driver, &pdev->dev, regs);
ret = udc_probe(&ci13xxx_msm_udc_driver, &pdev->dev, _udc_ctxt.regs);
if (ret < 0) {
dev_err(&pdev->dev, "udc_probe failed\n");
goto iounmap;
}
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
_udc_ctxt.irq = platform_get_irq(pdev, 0);
if (_udc_ctxt.irq < 0) {
dev_err(&pdev->dev, "IRQ not found\n");
ret = -ENXIO;
goto udc_remove;
}
ret = request_irq(irq, msm_udc_irq, IRQF_SHARED, pdev->name, pdev);
ret = request_irq(_udc_ctxt.irq, msm_udc_irq, IRQF_SHARED, pdev->name,
pdev);
if (ret < 0) {
dev_err(&pdev->dev, "request_irq failed\n");
goto udc_remove;
@@ -101,14 +106,24 @@ static int ci13xxx_msm_probe(struct platform_device *pdev)
udc_remove:
udc_remove();
iounmap:
iounmap(regs);
iounmap(_udc_ctxt.regs);
return ret;
}
int ci13xxx_msm_remove(struct platform_device *pdev)
{
pm_runtime_disable(&pdev->dev);
free_irq(_udc_ctxt.irq, pdev);
udc_remove();
iounmap(_udc_ctxt.regs);
return 0;
}
static struct platform_driver ci13xxx_msm_driver = {
.probe = ci13xxx_msm_probe,
.driver = { .name = "msm_hsusb", },
.remove = ci13xxx_msm_remove,
};
static int __init ci13xxx_msm_init(void)
@@ -116,3 +131,11 @@ static int __init ci13xxx_msm_init(void)
return platform_driver_register(&ci13xxx_msm_driver);
}
module_init(ci13xxx_msm_init);
static void __exit ci13xxx_msm_exit(void)
{
platform_driver_unregister(&ci13xxx_msm_driver);
}
module_exit(ci13xxx_msm_exit);
MODULE_LICENSE("GPL v2");
+6 -1
View File
@@ -1634,6 +1634,8 @@ static struct usb_gadget_driver composite_driver = {
int usb_composite_probe(struct usb_composite_driver *driver,
int (*bind)(struct usb_composite_dev *cdev))
{
int retval;
if (!driver || !driver->dev || !bind || composite)
return -EINVAL;
@@ -1648,7 +1650,10 @@ int usb_composite_probe(struct usb_composite_driver *driver,
composite = driver;
composite_gadget_bind = bind;
return usb_gadget_probe_driver(&composite_driver, composite_bind);
retval = usb_gadget_probe_driver(&composite_driver, composite_bind);
if (retval)
composite = NULL;
return retval;
}
/**