]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/usb/gadget/ci13xxx_udc.c
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/wfg/writeback
[karo-tx-linux.git] / drivers / usb / gadget / ci13xxx_udc.c
index baaf87ed7685fd356464664a5a1706f81bbfeab5..1265a8502ea0fe90348bdcdfa41b2f4df337c02d 100644 (file)
@@ -857,7 +857,7 @@ static void dbg_print(u8 addr, const char *name, int status, const char *extra)
        stamp = stamp * 1000000 + tval.tv_usec;
 
        scnprintf(dbg_data.buf[dbg_data.idx], DBG_DATA_MSG,
-                 "%04X\t» %02X %-7.7s %4i «\t%s\n",
+                 "%04X\t? %02X %-7.7s %4i ?\t%s\n",
                  stamp, addr, name, status, extra);
 
        dbg_inc(&dbg_data.idx);
@@ -865,7 +865,7 @@ static void dbg_print(u8 addr, const char *name, int status, const char *extra)
        write_unlock_irqrestore(&dbg_data.lck, flags);
 
        if (dbg_data.tty != 0)
-               pr_notice("%04X\t» %02X %-7.7s %4i «\t%s\n",
+               pr_notice("%04X\t? %02X %-7.7s %4i ?\t%s\n",
                          stamp, addr, name, status, extra);
 }
 
@@ -1025,15 +1025,15 @@ static ssize_t show_inters(struct device *dev, struct device_attribute *attr,
 
        n += scnprintf(buf + n, PAGE_SIZE - n, "*test = %d\n",
                       isr_statistics.test);
-       n += scnprintf(buf + n, PAGE_SIZE - n, "» ui  = %d\n",
+       n += scnprintf(buf + n, PAGE_SIZE - n, "? ui  = %d\n",
                       isr_statistics.ui);
-       n += scnprintf(buf + n, PAGE_SIZE - n, "» uei = %d\n",
+       n += scnprintf(buf + n, PAGE_SIZE - n, "? uei = %d\n",
                       isr_statistics.uei);
-       n += scnprintf(buf + n, PAGE_SIZE - n, "» pci = %d\n",
+       n += scnprintf(buf + n, PAGE_SIZE - n, "? pci = %d\n",
                       isr_statistics.pci);
-       n += scnprintf(buf + n, PAGE_SIZE - n, "» uri = %d\n",
+       n += scnprintf(buf + n, PAGE_SIZE - n, "? uri = %d\n",
                       isr_statistics.uri);
-       n += scnprintf(buf + n, PAGE_SIZE - n, "» sli = %d\n",
+       n += scnprintf(buf + n, PAGE_SIZE - n, "? sli = %d\n",
                       isr_statistics.sli);
        n += scnprintf(buf + n, PAGE_SIZE - n, "*none = %d\n",
                       isr_statistics.none);
@@ -1214,12 +1214,13 @@ static DEVICE_ATTR(qheads, S_IRUSR, show_qheads, NULL);
  *
  * Check "device.h" for details
  */
+#define DUMP_ENTRIES   512
 static ssize_t show_registers(struct device *dev,
                              struct device_attribute *attr, char *buf)
 {
        struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev);
        unsigned long flags;
-       u32 dump[512];
+       u32 *dump;
        unsigned i, k, n = 0;
 
        dbg_trace("[%s] %p\n", __func__, buf);
@@ -1228,8 +1229,14 @@ static ssize_t show_registers(struct device *dev,
                return 0;
        }
 
+       dump = kmalloc(sizeof(u32) * DUMP_ENTRIES, GFP_KERNEL);
+       if (!dump) {
+               dev_err(dev, "%s: out of memory\n", __func__);
+               return 0;
+       }
+
        spin_lock_irqsave(udc->lock, flags);
-       k = hw_register_read(dump, sizeof(dump)/sizeof(u32));
+       k = hw_register_read(dump, DUMP_ENTRIES);
        spin_unlock_irqrestore(udc->lock, flags);
 
        for (i = 0; i < k; i++) {
@@ -1237,6 +1244,7 @@ static ssize_t show_registers(struct device *dev,
                               "reg[0x%04X] = 0x%08X\n",
                               i * (unsigned)sizeof(u32), dump[i]);
        }
+       kfree(dump);
 
        return n;
 }
@@ -2515,6 +2523,9 @@ static int ci13xxx_vbus_draw(struct usb_gadget *_gadget, unsigned mA)
        return -ENOTSUPP;
 }
 
+static int ci13xxx_start(struct usb_gadget_driver *driver,
+               int (*bind)(struct usb_gadget *));
+static int ci13xxx_stop(struct usb_gadget_driver *driver);
 /**
  * Device operations part of the API to the USB controller hardware,
  * which don't involve endpoints (or i/o)
@@ -2524,17 +2535,19 @@ static const struct usb_gadget_ops usb_gadget_ops = {
        .vbus_session   = ci13xxx_vbus_session,
        .wakeup         = ci13xxx_wakeup,
        .vbus_draw      = ci13xxx_vbus_draw,
+       .start          = ci13xxx_start,
+       .stop           = ci13xxx_stop,
 };
 
 /**
- * usb_gadget_probe_driver: register a gadget driver
+ * ci13xxx_start: register a gadget driver
  * @driver: the driver being registered
  * @bind: the driver's bind callback
  *
- * Check usb_gadget_probe_driver() at <linux/usb/gadget.h> for details.
+ * Check ci13xxx_start() at <linux/usb/gadget.h> for details.
  * Interrupts are enabled here.
  */
-int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
+static int ci13xxx_start(struct usb_gadget_driver *driver,
                int (*bind)(struct usb_gadget *))
 {
        struct ci13xxx *udc = _udc;
@@ -2615,10 +2628,13 @@ int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
        if (retval)
                goto done;
        spin_unlock_irqrestore(udc->lock, flags);
-       retval = usb_ep_enable(&udc->ep0out.ep, &ctrl_endpt_out_desc);
+       udc->ep0out.ep.desc = &ctrl_endpt_out_desc;
+       retval = usb_ep_enable(&udc->ep0out.ep);
        if (retval)
                return retval;
-       retval = usb_ep_enable(&udc->ep0in.ep, &ctrl_endpt_in_desc);
+
+       udc->ep0in.ep.desc = &ctrl_endpt_in_desc;
+       retval = usb_ep_enable(&udc->ep0in.ep);
        if (retval)
                return retval;
        spin_lock_irqsave(udc->lock, flags);
@@ -2657,14 +2673,13 @@ int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
        spin_unlock_irqrestore(udc->lock, flags);
        return retval;
 }
-EXPORT_SYMBOL(usb_gadget_probe_driver);
 
 /**
- * usb_gadget_unregister_driver: unregister a gadget driver
+ * ci13xxx_stop: unregister a gadget driver
  *
  * Check usb_gadget_unregister_driver() at "usb_gadget.h" for details
  */
-int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
+static int ci13xxx_stop(struct usb_gadget_driver *driver)
 {
        struct ci13xxx *udc = _udc;
        unsigned long i, flags;
@@ -2726,7 +2741,6 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
 
        return 0;
 }
-EXPORT_SYMBOL(usb_gadget_unregister_driver);
 
 /******************************************************************************
  * BUS block
@@ -2901,12 +2915,23 @@ static int udc_probe(struct ci13xxx_udc_driver *driver, struct device *dev,
                if (retval)
                        goto remove_dbg;
        }
+
+       retval = usb_add_gadget_udc(dev, &udc->gadget);
+       if (retval)
+               goto remove_trans;
+
        pm_runtime_no_callbacks(&udc->gadget.dev);
        pm_runtime_enable(&udc->gadget.dev);
 
        _udc = udc;
        return retval;
 
+remove_trans:
+       if (udc->transceiver) {
+               otg_set_peripheral(udc->transceiver, &udc->gadget);
+               otg_put_transceiver(udc->transceiver);
+       }
+
        err("error = %i", retval);
 remove_dbg:
 #ifdef CONFIG_USB_GADGET_DEBUG_FILES
@@ -2936,6 +2961,7 @@ static void udc_remove(void)
                err("EINVAL");
                return;
        }
+       usb_del_gadget_udc(&udc->gadget);
 
        if (udc->transceiver) {
                otg_set_peripheral(udc->transceiver, &udc->gadget);