linux/drivers/usb/gadget/udc-core.c
<<
>>
Prefs
   1/**
   2 * udc.c - Core UDC Framework
   3 *
   4 * Copyright (C) 2010 Texas Instruments
   5 * Author: Felipe Balbi <balbi@ti.com>
   6 *
   7 * This program is free software: you can redistribute it and/or modify
   8 * it under the terms of the GNU General Public License version 2  of
   9 * the License as published by the Free Software Foundation.
  10 *
  11 * This program is distributed in the hope that it will be useful,
  12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14 * GNU General Public License for more details.
  15 *
  16 * You should have received a copy of the GNU General Public License
  17 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  18 */
  19
  20#include <linux/kernel.h>
  21#include <linux/module.h>
  22#include <linux/device.h>
  23#include <linux/list.h>
  24#include <linux/err.h>
  25
  26#include <linux/usb/ch9.h>
  27#include <linux/usb/gadget.h>
  28
  29/**
  30 * struct usb_udc - describes one usb device controller
  31 * @driver - the gadget driver pointer. For use by the class code
  32 * @dev - the child device to the actual controller
  33 * @gadget - the gadget. For use by the class code
  34 * @list - for use by the udc class driver
  35 *
  36 * This represents the internal data structure which is used by the UDC-class
  37 * to hold information about udc driver and gadget together.
  38 */
  39struct usb_udc {
  40        struct usb_gadget_driver        *driver;
  41        struct usb_gadget               *gadget;
  42        struct device                   dev;
  43        struct list_head                list;
  44};
  45
  46static struct class *udc_class;
  47static LIST_HEAD(udc_list);
  48static DEFINE_MUTEX(udc_lock);
  49
  50/* ------------------------------------------------------------------------- */
  51
  52/**
  53 * usb_gadget_start - tells usb device controller to start up
  54 * @gadget: The gadget we want to get started
  55 * @driver: The driver we want to bind to @gadget
  56 * @bind: The bind function for @driver
  57 *
  58 * This call is issued by the UDC Class driver when it's about
  59 * to register a gadget driver to the device controller, before
  60 * calling gadget driver's bind() method.
  61 *
  62 * It allows the controller to be powered off until strictly
  63 * necessary to have it powered on.
  64 *
  65 * Returns zero on success, else negative errno.
  66 */
  67static inline int usb_gadget_start(struct usb_gadget *gadget,
  68                struct usb_gadget_driver *driver,
  69                int (*bind)(struct usb_gadget *))
  70{
  71        return gadget->ops->start(driver, bind);
  72}
  73
  74/**
  75 * usb_gadget_udc_start - tells usb device controller to start up
  76 * @gadget: The gadget we want to get started
  77 * @driver: The driver we want to bind to @gadget
  78 *
  79 * This call is issued by the UDC Class driver when it's about
  80 * to register a gadget driver to the device controller, before
  81 * calling gadget driver's bind() method.
  82 *
  83 * It allows the controller to be powered off until strictly
  84 * necessary to have it powered on.
  85 *
  86 * Returns zero on success, else negative errno.
  87 */
  88static inline int usb_gadget_udc_start(struct usb_gadget *gadget,
  89                struct usb_gadget_driver *driver)
  90{
  91        return gadget->ops->udc_start(gadget, driver);
  92}
  93
  94/**
  95 * usb_gadget_stop - tells usb device controller we don't need it anymore
  96 * @gadget: The device we want to stop activity
  97 * @driver: The driver to unbind from @gadget
  98 *
  99 * This call is issued by the UDC Class driver after calling
 100 * gadget driver's unbind() method.
 101 *
 102 * The details are implementation specific, but it can go as
 103 * far as powering off UDC completely and disable its data
 104 * line pullups.
 105 */
 106static inline void usb_gadget_stop(struct usb_gadget *gadget,
 107                struct usb_gadget_driver *driver)
 108{
 109        gadget->ops->stop(driver);
 110}
 111
 112/**
 113 * usb_gadget_udc_stop - tells usb device controller we don't need it anymore
 114 * @gadget: The device we want to stop activity
 115 * @driver: The driver to unbind from @gadget
 116 *
 117 * This call is issued by the UDC Class driver after calling
 118 * gadget driver's unbind() method.
 119 *
 120 * The details are implementation specific, but it can go as
 121 * far as powering off UDC completely and disable its data
 122 * line pullups.
 123 */
 124static inline void usb_gadget_udc_stop(struct usb_gadget *gadget,
 125                struct usb_gadget_driver *driver)
 126{
 127        gadget->ops->udc_stop(gadget, driver);
 128}
 129
 130/**
 131 * usb_udc_release - release the usb_udc struct
 132 * @dev: the dev member within usb_udc
 133 *
 134 * This is called by driver's core in order to free memory once the last
 135 * reference is released.
 136 */
 137static void usb_udc_release(struct device *dev)
 138{
 139        struct usb_udc *udc;
 140
 141        udc = container_of(dev, struct usb_udc, dev);
 142        dev_dbg(dev, "releasing '%s'\n", dev_name(dev));
 143        kfree(udc);
 144}
 145
 146static const struct attribute_group *usb_udc_attr_groups[];
 147/**
 148 * usb_add_gadget_udc - adds a new gadget to the udc class driver list
 149 * @parent: the parent device to this udc. Usually the controller
 150 * driver's device.
 151 * @gadget: the gadget to be added to the list
 152 *
 153 * Returns zero on success, negative errno otherwise.
 154 */
 155int usb_add_gadget_udc(struct device *parent, struct usb_gadget *gadget)
 156{
 157        struct usb_udc          *udc;
 158        int                     ret = -ENOMEM;
 159
 160        udc = kzalloc(sizeof(*udc), GFP_KERNEL);
 161        if (!udc)
 162                goto err1;
 163
 164        device_initialize(&udc->dev);
 165        udc->dev.release = usb_udc_release;
 166        udc->dev.class = udc_class;
 167        udc->dev.groups = usb_udc_attr_groups;
 168        udc->dev.parent = parent;
 169        ret = dev_set_name(&udc->dev, "%s", kobject_name(&parent->kobj));
 170        if (ret)
 171                goto err2;
 172
 173        udc->gadget = gadget;
 174
 175        mutex_lock(&udc_lock);
 176        list_add_tail(&udc->list, &udc_list);
 177
 178        ret = device_add(&udc->dev);
 179        if (ret)
 180                goto err3;
 181
 182        mutex_unlock(&udc_lock);
 183
 184        return 0;
 185err3:
 186        list_del(&udc->list);
 187        mutex_unlock(&udc_lock);
 188
 189err2:
 190        put_device(&udc->dev);
 191
 192err1:
 193        return ret;
 194}
 195EXPORT_SYMBOL_GPL(usb_add_gadget_udc);
 196
 197static int udc_is_newstyle(struct usb_udc *udc)
 198{
 199        if (udc->gadget->ops->udc_start && udc->gadget->ops->udc_stop)
 200                return 1;
 201        return 0;
 202}
 203
 204
 205static void usb_gadget_remove_driver(struct usb_udc *udc)
 206{
 207        dev_dbg(&udc->dev, "unregistering UDC driver [%s]\n",
 208                        udc->gadget->name);
 209
 210        kobject_uevent(&udc->dev.kobj, KOBJ_CHANGE);
 211
 212        if (udc_is_newstyle(udc)) {
 213                udc->driver->disconnect(udc->gadget);
 214                udc->driver->unbind(udc->gadget);
 215                usb_gadget_udc_stop(udc->gadget, udc->driver);
 216                usb_gadget_disconnect(udc->gadget);
 217        } else {
 218                usb_gadget_stop(udc->gadget, udc->driver);
 219        }
 220
 221        udc->driver = NULL;
 222        udc->dev.driver = NULL;
 223}
 224
 225/**
 226 * usb_del_gadget_udc - deletes @udc from udc_list
 227 * @gadget: the gadget to be removed.
 228 *
 229 * This, will call usb_gadget_unregister_driver() if
 230 * the @udc is still busy.
 231 */
 232void usb_del_gadget_udc(struct usb_gadget *gadget)
 233{
 234        struct usb_udc          *udc = NULL;
 235
 236        mutex_lock(&udc_lock);
 237        list_for_each_entry(udc, &udc_list, list)
 238                if (udc->gadget == gadget)
 239                        goto found;
 240
 241        dev_err(gadget->dev.parent, "gadget not registered.\n");
 242        mutex_unlock(&udc_lock);
 243
 244        return;
 245
 246found:
 247        dev_vdbg(gadget->dev.parent, "unregistering gadget\n");
 248
 249        list_del(&udc->list);
 250        mutex_unlock(&udc_lock);
 251
 252        if (udc->driver)
 253                usb_gadget_remove_driver(udc);
 254
 255        kobject_uevent(&udc->dev.kobj, KOBJ_REMOVE);
 256        device_unregister(&udc->dev);
 257}
 258EXPORT_SYMBOL_GPL(usb_del_gadget_udc);
 259
 260/* ------------------------------------------------------------------------- */
 261
 262int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
 263                int (*bind)(struct usb_gadget *))
 264{
 265        struct usb_udc          *udc = NULL;
 266        int                     ret;
 267
 268        if (!driver || !bind || !driver->setup)
 269                return -EINVAL;
 270
 271        mutex_lock(&udc_lock);
 272        list_for_each_entry(udc, &udc_list, list) {
 273                /* For now we take the first one */
 274                if (!udc->driver)
 275                        goto found;
 276        }
 277
 278        pr_debug("couldn't find an available UDC\n");
 279        mutex_unlock(&udc_lock);
 280        return -ENODEV;
 281
 282found:
 283        dev_dbg(&udc->dev, "registering UDC driver [%s]\n",
 284                        driver->function);
 285
 286        udc->driver = driver;
 287        udc->dev.driver = &driver->driver;
 288
 289        if (udc_is_newstyle(udc)) {
 290                ret = bind(udc->gadget);
 291                if (ret)
 292                        goto err1;
 293                ret = usb_gadget_udc_start(udc->gadget, driver);
 294                if (ret) {
 295                        driver->unbind(udc->gadget);
 296                        goto err1;
 297                }
 298                usb_gadget_connect(udc->gadget);
 299        } else {
 300
 301                ret = usb_gadget_start(udc->gadget, driver, bind);
 302                if (ret)
 303                        goto err1;
 304
 305        }
 306
 307        kobject_uevent(&udc->dev.kobj, KOBJ_CHANGE);
 308        mutex_unlock(&udc_lock);
 309        return 0;
 310
 311err1:
 312        dev_err(&udc->dev, "failed to start %s: %d\n",
 313                        udc->driver->function, ret);
 314        udc->driver = NULL;
 315        udc->dev.driver = NULL;
 316        mutex_unlock(&udc_lock);
 317        return ret;
 318}
 319EXPORT_SYMBOL_GPL(usb_gadget_probe_driver);
 320
 321int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
 322{
 323        struct usb_udc          *udc = NULL;
 324        int                     ret = -ENODEV;
 325
 326        if (!driver || !driver->unbind)
 327                return -EINVAL;
 328
 329        mutex_lock(&udc_lock);
 330        list_for_each_entry(udc, &udc_list, list)
 331                if (udc->driver == driver) {
 332                        usb_gadget_remove_driver(udc);
 333                        ret = 0;
 334                        break;
 335                }
 336
 337        mutex_unlock(&udc_lock);
 338        return ret;
 339}
 340EXPORT_SYMBOL_GPL(usb_gadget_unregister_driver);
 341
 342/* ------------------------------------------------------------------------- */
 343
 344static ssize_t usb_udc_srp_store(struct device *dev,
 345                struct device_attribute *attr, const char *buf, size_t n)
 346{
 347        struct usb_udc          *udc = container_of(dev, struct usb_udc, dev);
 348
 349        if (sysfs_streq(buf, "1"))
 350                usb_gadget_wakeup(udc->gadget);
 351
 352        return n;
 353}
 354static DEVICE_ATTR(srp, S_IWUSR, NULL, usb_udc_srp_store);
 355
 356static ssize_t usb_udc_softconn_store(struct device *dev,
 357                struct device_attribute *attr, const char *buf, size_t n)
 358{
 359        struct usb_udc          *udc = container_of(dev, struct usb_udc, dev);
 360
 361        if (sysfs_streq(buf, "connect")) {
 362                usb_gadget_connect(udc->gadget);
 363        } else if (sysfs_streq(buf, "disconnect")) {
 364                usb_gadget_disconnect(udc->gadget);
 365        } else {
 366                dev_err(dev, "unsupported command '%s'\n", buf);
 367                return -EINVAL;
 368        }
 369
 370        return n;
 371}
 372static DEVICE_ATTR(soft_connect, S_IWUSR, NULL, usb_udc_softconn_store);
 373
 374#define USB_UDC_SPEED_ATTR(name, param)                                 \
 375ssize_t usb_udc_##param##_show(struct device *dev,                      \
 376                struct device_attribute *attr, char *buf)               \
 377{                                                                       \
 378        struct usb_udc *udc = container_of(dev, struct usb_udc, dev);   \
 379        return snprintf(buf, PAGE_SIZE, "%s\n",                         \
 380                        usb_speed_string(udc->gadget->param));          \
 381}                                                                       \
 382static DEVICE_ATTR(name, S_IRUSR, usb_udc_##param##_show, NULL)
 383
 384static USB_UDC_SPEED_ATTR(current_speed, speed);
 385static USB_UDC_SPEED_ATTR(maximum_speed, max_speed);
 386
 387/* TODO: Scheduled for removal in 3.8. */
 388static ssize_t usb_udc_is_dualspeed_show(struct device *dev,
 389                struct device_attribute *attr, char *buf)
 390{
 391        struct usb_udc          *udc = container_of(dev, struct usb_udc, dev);
 392        return snprintf(buf, PAGE_SIZE, "%d\n",
 393                        gadget_is_dualspeed(udc->gadget));
 394}
 395static DEVICE_ATTR(is_dualspeed, S_IRUSR, usb_udc_is_dualspeed_show, NULL);
 396
 397#define USB_UDC_ATTR(name)                                      \
 398ssize_t usb_udc_##name##_show(struct device *dev,               \
 399                struct device_attribute *attr, char *buf)       \
 400{                                                               \
 401        struct usb_udc          *udc = container_of(dev, struct usb_udc, dev); \
 402        struct usb_gadget       *gadget = udc->gadget;          \
 403                                                                \
 404        return snprintf(buf, PAGE_SIZE, "%d\n", gadget->name);  \
 405}                                                               \
 406static DEVICE_ATTR(name, S_IRUGO, usb_udc_##name##_show, NULL)
 407
 408static USB_UDC_ATTR(is_otg);
 409static USB_UDC_ATTR(is_a_peripheral);
 410static USB_UDC_ATTR(b_hnp_enable);
 411static USB_UDC_ATTR(a_hnp_support);
 412static USB_UDC_ATTR(a_alt_hnp_support);
 413
 414static struct attribute *usb_udc_attrs[] = {
 415        &dev_attr_srp.attr,
 416        &dev_attr_soft_connect.attr,
 417        &dev_attr_current_speed.attr,
 418        &dev_attr_maximum_speed.attr,
 419
 420        &dev_attr_is_dualspeed.attr,
 421        &dev_attr_is_otg.attr,
 422        &dev_attr_is_a_peripheral.attr,
 423        &dev_attr_b_hnp_enable.attr,
 424        &dev_attr_a_hnp_support.attr,
 425        &dev_attr_a_alt_hnp_support.attr,
 426        NULL,
 427};
 428
 429static const struct attribute_group usb_udc_attr_group = {
 430        .attrs = usb_udc_attrs,
 431};
 432
 433static const struct attribute_group *usb_udc_attr_groups[] = {
 434        &usb_udc_attr_group,
 435        NULL,
 436};
 437
 438static int usb_udc_uevent(struct device *dev, struct kobj_uevent_env *env)
 439{
 440        struct usb_udc          *udc = container_of(dev, struct usb_udc, dev);
 441        int                     ret;
 442
 443        ret = add_uevent_var(env, "USB_UDC_NAME=%s", udc->gadget->name);
 444        if (ret) {
 445                dev_err(dev, "failed to add uevent USB_UDC_NAME\n");
 446                return ret;
 447        }
 448
 449        if (udc->driver) {
 450                ret = add_uevent_var(env, "USB_UDC_DRIVER=%s",
 451                                udc->driver->function);
 452                if (ret) {
 453                        dev_err(dev, "failed to add uevent USB_UDC_DRIVER\n");
 454                        return ret;
 455                }
 456        }
 457
 458        return 0;
 459}
 460
 461static int __init usb_udc_init(void)
 462{
 463        udc_class = class_create(THIS_MODULE, "udc");
 464        if (IS_ERR(udc_class)) {
 465                pr_err("failed to create udc class --> %ld\n",
 466                                PTR_ERR(udc_class));
 467                return PTR_ERR(udc_class);
 468        }
 469
 470        udc_class->dev_uevent = usb_udc_uevent;
 471        return 0;
 472}
 473subsys_initcall(usb_udc_init);
 474
 475static void __exit usb_udc_exit(void)
 476{
 477        class_destroy(udc_class);
 478}
 479module_exit(usb_udc_exit);
 480
 481MODULE_DESCRIPTION("UDC Framework");
 482MODULE_AUTHOR("Felipe Balbi <balbi@ti.com>");
 483MODULE_LICENSE("GPL v2");
 484