diff options
author | Kishon Vijay Abraham I <kishon@ti.com> | 2015-02-23 18:39:48 +0530 |
---|---|---|
committer | Marek Vasut <marex@denx.de> | 2015-04-14 05:48:08 +0200 |
commit | 103fa06cfea51403db4005dbf4835b870b48db85 (patch) | |
tree | 4e80f69f28c1d6e6acb84d01d3466235c5f7c8ae /drivers/usb/gadget | |
parent | 45d9337ec351abc2f146437bc5fe8365d0dd3307 (diff) | |
download | u-boot-imx-103fa06cfea51403db4005dbf4835b870b48db85.zip u-boot-imx-103fa06cfea51403db4005dbf4835b870b48db85.tar.gz u-boot-imx-103fa06cfea51403db4005dbf4835b870b48db85.tar.bz2 |
usb: gadget: udc: make udc-core compile in u-boot build
Make udc-core compile in u-boot by removing all linux specific
stuff and having only the bare minimal udc-core required for
usb gadget drivers. Also modified the file header to a format that is
generally being used in u-boot.
Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
Reviewed-by: Lukasz Majewski <l.majewski@samsung.com>
Diffstat (limited to 'drivers/usb/gadget')
-rw-r--r-- | drivers/usb/gadget/udc/udc-core.c | 335 |
1 files changed, 26 insertions, 309 deletions
diff --git a/drivers/usb/gadget/udc/udc-core.c b/drivers/usb/gadget/udc/udc-core.c index e31d574..875e998 100644 --- a/drivers/usb/gadget/udc/udc-core.c +++ b/drivers/usb/gadget/udc/udc-core.c @@ -1,33 +1,27 @@ /** - * udc.c - Core UDC Framework + * udc-core.c - Core UDC Framework + * + * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com * - * Copyright (C) 2010 Texas Instruments * Author: Felipe Balbi <balbi@ti.com> * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 of - * the License as published by the Free Software Foundation. + * Taken from Linux Kernel v3.19-rc1 (drivers/usb/gadget/udc-core.c) and ported + * to uboot. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * commit 02e8c96627 : usb: gadget: udc: core: prepend udc_attach_driver with + * usb_ * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. + * SPDX-License-Identifier: GPL-2.0 */ -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/device.h> -#include <linux/list.h> -#include <linux/err.h> -#include <linux/dma-mapping.h> -#include <linux/workqueue.h> +#include <linux/compat.h> +#include <malloc.h> +#include <asm/cache.h> +#include <asm/dma-mapping.h> +#include <common.h> #include <linux/usb/ch9.h> #include <linux/usb/gadget.h> -#include <linux/usb.h> /** * struct usb_udc - describes one usb device controller @@ -48,38 +42,18 @@ struct usb_udc { static struct class *udc_class; static LIST_HEAD(udc_list); -static DEFINE_MUTEX(udc_lock); +DEFINE_MUTEX(udc_lock); /* ------------------------------------------------------------------------- */ -#ifdef CONFIG_HAS_DMA - int usb_gadget_map_request(struct usb_gadget *gadget, struct usb_request *req, int is_in) { if (req->length == 0) return 0; - if (req->num_sgs) { - int mapped; - - mapped = dma_map_sg(&gadget->dev, req->sg, req->num_sgs, - is_in ? DMA_TO_DEVICE : DMA_FROM_DEVICE); - if (mapped == 0) { - dev_err(&gadget->dev, "failed to map SGs\n"); - return -EFAULT; - } - - req->num_mapped_sgs = mapped; - } else { - req->dma = dma_map_single(&gadget->dev, req->buf, req->length, - is_in ? DMA_TO_DEVICE : DMA_FROM_DEVICE); - - if (dma_mapping_error(&gadget->dev, req->dma)) { - dev_err(&gadget->dev, "failed to map buffer\n"); - return -EFAULT; - } - } + req->dma = dma_map_single(req->buf, req->length, + is_in ? DMA_TO_DEVICE : DMA_FROM_DEVICE); return 0; } @@ -91,20 +65,11 @@ void usb_gadget_unmap_request(struct usb_gadget *gadget, if (req->length == 0) return; - if (req->num_mapped_sgs) { - dma_unmap_sg(&gadget->dev, req->sg, req->num_mapped_sgs, - is_in ? DMA_TO_DEVICE : DMA_FROM_DEVICE); - - req->num_mapped_sgs = 0; - } else { - dma_unmap_single(&gadget->dev, req->dma, req->length, - is_in ? DMA_TO_DEVICE : DMA_FROM_DEVICE); - } + dma_unmap_single((void *)req->dma, req->length, + is_in ? DMA_TO_DEVICE : DMA_FROM_DEVICE); } EXPORT_SYMBOL_GPL(usb_gadget_unmap_request); -#endif /* CONFIG_HAS_DMA */ - /* ------------------------------------------------------------------------- */ /** @@ -117,39 +82,16 @@ EXPORT_SYMBOL_GPL(usb_gadget_unmap_request); void usb_gadget_giveback_request(struct usb_ep *ep, struct usb_request *req) { - if (likely(req->status == 0)) - usb_led_activity(USB_LED_EVENT_GADGET); - req->complete(ep, req); } EXPORT_SYMBOL_GPL(usb_gadget_giveback_request); /* ------------------------------------------------------------------------- */ -static void usb_gadget_state_work(struct work_struct *work) -{ - struct usb_gadget *gadget = work_to_gadget(work); - struct usb_udc *udc = NULL; - - mutex_lock(&udc_lock); - list_for_each_entry(udc, &udc_list, list) - if (udc->gadget == gadget) - goto found; - mutex_unlock(&udc_lock); - - return; - -found: - mutex_unlock(&udc_lock); - - sysfs_notify(&udc->dev.kobj, NULL, "state"); -} - void usb_gadget_set_state(struct usb_gadget *gadget, enum usb_device_state state) { gadget->state = state; - schedule_work(&gadget->work); } EXPORT_SYMBOL_GPL(usb_gadget_set_state); @@ -219,17 +161,9 @@ static void usb_udc_release(struct device *dev) struct usb_udc *udc; udc = container_of(dev, struct usb_udc, dev); - dev_dbg(dev, "releasing '%s'\n", dev_name(dev)); kfree(udc); } -static const struct attribute_group *usb_udc_attr_groups[]; - -static void usb_udc_nop_release(struct device *dev) -{ - dev_vdbg(dev, "%s\n", __func__); -} - /** * usb_add_gadget_udc_release - adds a new gadget to the udc class driver list * @parent: the parent device to this udc. Usually the controller driver's @@ -250,59 +184,23 @@ int usb_add_gadget_udc_release(struct device *parent, struct usb_gadget *gadget, goto err1; dev_set_name(&gadget->dev, "gadget"); - INIT_WORK(&gadget->work, usb_gadget_state_work); gadget->dev.parent = parent; -#ifdef CONFIG_HAS_DMA - dma_set_coherent_mask(&gadget->dev, parent->coherent_dma_mask); - gadget->dev.dma_parms = parent->dma_parms; - gadget->dev.dma_mask = parent->dma_mask; -#endif - - if (release) - gadget->dev.release = release; - else - gadget->dev.release = usb_udc_nop_release; - - ret = device_register(&gadget->dev); - if (ret) - goto err2; - - device_initialize(&udc->dev); udc->dev.release = usb_udc_release; udc->dev.class = udc_class; - udc->dev.groups = usb_udc_attr_groups; udc->dev.parent = parent; - ret = dev_set_name(&udc->dev, "%s", kobject_name(&parent->kobj)); - if (ret) - goto err3; udc->gadget = gadget; mutex_lock(&udc_lock); list_add_tail(&udc->list, &udc_list); - ret = device_add(&udc->dev); - if (ret) - goto err4; - usb_gadget_set_state(gadget, USB_STATE_NOTATTACHED); mutex_unlock(&udc_lock); return 0; -err4: - list_del(&udc->list); - mutex_unlock(&udc_lock); - -err3: - put_device(&udc->dev); - -err2: - put_device(&gadget->dev); - kfree(udc); - err1: return ret; } @@ -327,16 +225,12 @@ static void usb_gadget_remove_driver(struct usb_udc *udc) dev_dbg(&udc->dev, "unregistering UDC driver [%s]\n", udc->driver->function); - kobject_uevent(&udc->dev.kobj, KOBJ_CHANGE); - usb_gadget_disconnect(udc->gadget); udc->driver->disconnect(udc->gadget); udc->driver->unbind(udc->gadget); usb_gadget_udc_stop(udc); udc->driver = NULL; - udc->dev.driver = NULL; - udc->gadget->dev.driver = NULL; } /** @@ -368,11 +262,6 @@ found: if (udc->driver) usb_gadget_remove_driver(udc); - - kobject_uevent(&udc->dev.kobj, KOBJ_REMOVE); - flush_work(&gadget->work); - device_unregister(&udc->dev); - device_unregister(&gadget->dev); } EXPORT_SYMBOL_GPL(usb_del_gadget_udc); @@ -386,10 +275,8 @@ static int udc_bind_to_driver(struct usb_udc *udc, struct usb_gadget_driver *dri driver->function); udc->driver = driver; - udc->dev.driver = &driver->driver; - udc->gadget->dev.driver = &driver->driver; - ret = driver->bind(udc->gadget, driver); + ret = driver->bind(udc->gadget); if (ret) goto err1; ret = usb_gadget_udc_start(udc); @@ -399,43 +286,14 @@ static int udc_bind_to_driver(struct usb_udc *udc, struct usb_gadget_driver *dri } usb_gadget_connect(udc->gadget); - kobject_uevent(&udc->dev.kobj, KOBJ_CHANGE); return 0; err1: if (ret != -EISNAM) dev_err(&udc->dev, "failed to start %s: %d\n", udc->driver->function, ret); udc->driver = NULL; - udc->dev.driver = NULL; - udc->gadget->dev.driver = NULL; - return ret; -} - -int usb_udc_attach_driver(const char *name, struct usb_gadget_driver *driver) -{ - struct usb_udc *udc = NULL; - int ret = -ENODEV; - - mutex_lock(&udc_lock); - list_for_each_entry(udc, &udc_list, list) { - ret = strcmp(name, dev_name(&udc->dev)); - if (!ret) - break; - } - if (ret) { - ret = -ENODEV; - goto out; - } - if (udc->driver) { - ret = -EBUSY; - goto out; - } - ret = udc_bind_to_driver(udc, driver); -out: - mutex_unlock(&udc_lock); return ret; } -EXPORT_SYMBOL_GPL(usb_udc_attach_driver); int usb_gadget_probe_driver(struct usb_gadget_driver *driver) { @@ -452,7 +310,7 @@ int usb_gadget_probe_driver(struct usb_gadget_driver *driver) goto found; } - pr_debug("couldn't find an available UDC\n"); + printf("couldn't find an available UDC\n"); mutex_unlock(&udc_lock); return -ENODEV; found: @@ -462,6 +320,12 @@ found: } EXPORT_SYMBOL_GPL(usb_gadget_probe_driver); +int usb_gadget_register_driver(struct usb_gadget_driver *driver) +{ + return usb_gadget_probe_driver(driver); +} +EXPORT_SYMBOL_GPL(usb_gadget_register_driver); + int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) { struct usb_udc *udc = NULL; @@ -485,153 +349,6 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) } EXPORT_SYMBOL_GPL(usb_gadget_unregister_driver); -/* ------------------------------------------------------------------------- */ - -static ssize_t usb_udc_srp_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t n) -{ - struct usb_udc *udc = container_of(dev, struct usb_udc, dev); - - if (sysfs_streq(buf, "1")) - usb_gadget_wakeup(udc->gadget); - - return n; -} -static DEVICE_ATTR(srp, S_IWUSR, NULL, usb_udc_srp_store); - -static ssize_t usb_udc_softconn_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t n) -{ - struct usb_udc *udc = container_of(dev, struct usb_udc, dev); - - if (!udc->driver) { - dev_err(dev, "soft-connect without a gadget driver\n"); - return -EOPNOTSUPP; - } - - if (sysfs_streq(buf, "connect")) { - usb_gadget_udc_start(udc); - usb_gadget_connect(udc->gadget); - } else if (sysfs_streq(buf, "disconnect")) { - usb_gadget_disconnect(udc->gadget); - udc->driver->disconnect(udc->gadget); - usb_gadget_udc_stop(udc); - } else { - dev_err(dev, "unsupported command '%s'\n", buf); - return -EINVAL; - } - - return n; -} -static DEVICE_ATTR(soft_connect, S_IWUSR, NULL, usb_udc_softconn_store); - -static ssize_t state_show(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct usb_udc *udc = container_of(dev, struct usb_udc, dev); - struct usb_gadget *gadget = udc->gadget; - - return sprintf(buf, "%s\n", usb_state_string(gadget->state)); -} -static DEVICE_ATTR_RO(state); - -#define USB_UDC_SPEED_ATTR(name, param) \ -ssize_t name##_show(struct device *dev, \ - struct device_attribute *attr, char *buf) \ -{ \ - struct usb_udc *udc = container_of(dev, struct usb_udc, dev); \ - return snprintf(buf, PAGE_SIZE, "%s\n", \ - usb_speed_string(udc->gadget->param)); \ -} \ -static DEVICE_ATTR_RO(name) - -static USB_UDC_SPEED_ATTR(current_speed, speed); -static USB_UDC_SPEED_ATTR(maximum_speed, max_speed); - -#define USB_UDC_ATTR(name) \ -ssize_t name##_show(struct device *dev, \ - struct device_attribute *attr, char *buf) \ -{ \ - struct usb_udc *udc = container_of(dev, struct usb_udc, dev); \ - struct usb_gadget *gadget = udc->gadget; \ - \ - return snprintf(buf, PAGE_SIZE, "%d\n", gadget->name); \ -} \ -static DEVICE_ATTR_RO(name) - -static USB_UDC_ATTR(is_otg); -static USB_UDC_ATTR(is_a_peripheral); -static USB_UDC_ATTR(b_hnp_enable); -static USB_UDC_ATTR(a_hnp_support); -static USB_UDC_ATTR(a_alt_hnp_support); - -static struct attribute *usb_udc_attrs[] = { - &dev_attr_srp.attr, - &dev_attr_soft_connect.attr, - &dev_attr_state.attr, - &dev_attr_current_speed.attr, - &dev_attr_maximum_speed.attr, - - &dev_attr_is_otg.attr, - &dev_attr_is_a_peripheral.attr, - &dev_attr_b_hnp_enable.attr, - &dev_attr_a_hnp_support.attr, - &dev_attr_a_alt_hnp_support.attr, - NULL, -}; - -static const struct attribute_group usb_udc_attr_group = { - .attrs = usb_udc_attrs, -}; - -static const struct attribute_group *usb_udc_attr_groups[] = { - &usb_udc_attr_group, - NULL, -}; - -static int usb_udc_uevent(struct device *dev, struct kobj_uevent_env *env) -{ - struct usb_udc *udc = container_of(dev, struct usb_udc, dev); - int ret; - - ret = add_uevent_var(env, "USB_UDC_NAME=%s", udc->gadget->name); - if (ret) { - dev_err(dev, "failed to add uevent USB_UDC_NAME\n"); - return ret; - } - - if (udc->driver) { - ret = add_uevent_var(env, "USB_UDC_DRIVER=%s", - udc->driver->function); - if (ret) { - dev_err(dev, "failed to add uevent USB_UDC_DRIVER\n"); - return ret; - } - } - - return 0; -} - -static int __init usb_udc_init(void) -{ - udc_class = class_create(THIS_MODULE, "udc"); - if (IS_ERR(udc_class)) { - pr_err("failed to create udc class --> %ld\n", - PTR_ERR(udc_class)); - return PTR_ERR(udc_class); - } - - udc_class->dev_uevent = usb_udc_uevent; - return 0; -} -subsys_initcall(usb_udc_init); - -static void __exit usb_udc_exit(void) -{ - class_destroy(udc_class); -} -module_exit(usb_udc_exit); - MODULE_DESCRIPTION("UDC Framework"); MODULE_AUTHOR("Felipe Balbi <balbi@ti.com>"); MODULE_LICENSE("GPL v2"); |