diff options
Diffstat (limited to 'drivers/usb/gadget/ci13xxx_udc.c')
-rw-r--r-- | drivers/usb/gadget/ci13xxx_udc.c | 62 |
1 files changed, 44 insertions, 18 deletions
diff --git a/drivers/usb/gadget/ci13xxx_udc.c b/drivers/usb/gadget/ci13xxx_udc.c index baaf87ed7685..1265a8502ea0 100644 --- a/drivers/usb/gadget/ci13xxx_udc.c +++ b/drivers/usb/gadget/ci13xxx_udc.c | |||
@@ -857,7 +857,7 @@ static void dbg_print(u8 addr, const char *name, int status, const char *extra) | |||
857 | stamp = stamp * 1000000 + tval.tv_usec; | 857 | stamp = stamp * 1000000 + tval.tv_usec; |
858 | 858 | ||
859 | scnprintf(dbg_data.buf[dbg_data.idx], DBG_DATA_MSG, | 859 | scnprintf(dbg_data.buf[dbg_data.idx], DBG_DATA_MSG, |
860 | "%04X\t» %02X %-7.7s %4i «\t%s\n", | 860 | "%04X\t? %02X %-7.7s %4i ?\t%s\n", |
861 | stamp, addr, name, status, extra); | 861 | stamp, addr, name, status, extra); |
862 | 862 | ||
863 | dbg_inc(&dbg_data.idx); | 863 | dbg_inc(&dbg_data.idx); |
@@ -865,7 +865,7 @@ static void dbg_print(u8 addr, const char *name, int status, const char *extra) | |||
865 | write_unlock_irqrestore(&dbg_data.lck, flags); | 865 | write_unlock_irqrestore(&dbg_data.lck, flags); |
866 | 866 | ||
867 | if (dbg_data.tty != 0) | 867 | if (dbg_data.tty != 0) |
868 | pr_notice("%04X\t» %02X %-7.7s %4i «\t%s\n", | 868 | pr_notice("%04X\t? %02X %-7.7s %4i ?\t%s\n", |
869 | stamp, addr, name, status, extra); | 869 | stamp, addr, name, status, extra); |
870 | } | 870 | } |
871 | 871 | ||
@@ -1025,15 +1025,15 @@ static ssize_t show_inters(struct device *dev, struct device_attribute *attr, | |||
1025 | 1025 | ||
1026 | n += scnprintf(buf + n, PAGE_SIZE - n, "*test = %d\n", | 1026 | n += scnprintf(buf + n, PAGE_SIZE - n, "*test = %d\n", |
1027 | isr_statistics.test); | 1027 | isr_statistics.test); |
1028 | n += scnprintf(buf + n, PAGE_SIZE - n, "» ui = %d\n", | 1028 | n += scnprintf(buf + n, PAGE_SIZE - n, "? ui = %d\n", |
1029 | isr_statistics.ui); | 1029 | isr_statistics.ui); |
1030 | n += scnprintf(buf + n, PAGE_SIZE - n, "» uei = %d\n", | 1030 | n += scnprintf(buf + n, PAGE_SIZE - n, "? uei = %d\n", |
1031 | isr_statistics.uei); | 1031 | isr_statistics.uei); |
1032 | n += scnprintf(buf + n, PAGE_SIZE - n, "» pci = %d\n", | 1032 | n += scnprintf(buf + n, PAGE_SIZE - n, "? pci = %d\n", |
1033 | isr_statistics.pci); | 1033 | isr_statistics.pci); |
1034 | n += scnprintf(buf + n, PAGE_SIZE - n, "» uri = %d\n", | 1034 | n += scnprintf(buf + n, PAGE_SIZE - n, "? uri = %d\n", |
1035 | isr_statistics.uri); | 1035 | isr_statistics.uri); |
1036 | n += scnprintf(buf + n, PAGE_SIZE - n, "» sli = %d\n", | 1036 | n += scnprintf(buf + n, PAGE_SIZE - n, "? sli = %d\n", |
1037 | isr_statistics.sli); | 1037 | isr_statistics.sli); |
1038 | n += scnprintf(buf + n, PAGE_SIZE - n, "*none = %d\n", | 1038 | n += scnprintf(buf + n, PAGE_SIZE - n, "*none = %d\n", |
1039 | isr_statistics.none); | 1039 | isr_statistics.none); |
@@ -1214,12 +1214,13 @@ static DEVICE_ATTR(qheads, S_IRUSR, show_qheads, NULL); | |||
1214 | * | 1214 | * |
1215 | * Check "device.h" for details | 1215 | * Check "device.h" for details |
1216 | */ | 1216 | */ |
1217 | #define DUMP_ENTRIES 512 | ||
1217 | static ssize_t show_registers(struct device *dev, | 1218 | static ssize_t show_registers(struct device *dev, |
1218 | struct device_attribute *attr, char *buf) | 1219 | struct device_attribute *attr, char *buf) |
1219 | { | 1220 | { |
1220 | struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev); | 1221 | struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev); |
1221 | unsigned long flags; | 1222 | unsigned long flags; |
1222 | u32 dump[512]; | 1223 | u32 *dump; |
1223 | unsigned i, k, n = 0; | 1224 | unsigned i, k, n = 0; |
1224 | 1225 | ||
1225 | dbg_trace("[%s] %p\n", __func__, buf); | 1226 | dbg_trace("[%s] %p\n", __func__, buf); |
@@ -1228,8 +1229,14 @@ static ssize_t show_registers(struct device *dev, | |||
1228 | return 0; | 1229 | return 0; |
1229 | } | 1230 | } |
1230 | 1231 | ||
1232 | dump = kmalloc(sizeof(u32) * DUMP_ENTRIES, GFP_KERNEL); | ||
1233 | if (!dump) { | ||
1234 | dev_err(dev, "%s: out of memory\n", __func__); | ||
1235 | return 0; | ||
1236 | } | ||
1237 | |||
1231 | spin_lock_irqsave(udc->lock, flags); | 1238 | spin_lock_irqsave(udc->lock, flags); |
1232 | k = hw_register_read(dump, sizeof(dump)/sizeof(u32)); | 1239 | k = hw_register_read(dump, DUMP_ENTRIES); |
1233 | spin_unlock_irqrestore(udc->lock, flags); | 1240 | spin_unlock_irqrestore(udc->lock, flags); |
1234 | 1241 | ||
1235 | for (i = 0; i < k; i++) { | 1242 | for (i = 0; i < k; i++) { |
@@ -1237,6 +1244,7 @@ static ssize_t show_registers(struct device *dev, | |||
1237 | "reg[0x%04X] = 0x%08X\n", | 1244 | "reg[0x%04X] = 0x%08X\n", |
1238 | i * (unsigned)sizeof(u32), dump[i]); | 1245 | i * (unsigned)sizeof(u32), dump[i]); |
1239 | } | 1246 | } |
1247 | kfree(dump); | ||
1240 | 1248 | ||
1241 | return n; | 1249 | return n; |
1242 | } | 1250 | } |
@@ -2515,6 +2523,9 @@ static int ci13xxx_vbus_draw(struct usb_gadget *_gadget, unsigned mA) | |||
2515 | return -ENOTSUPP; | 2523 | return -ENOTSUPP; |
2516 | } | 2524 | } |
2517 | 2525 | ||
2526 | static int ci13xxx_start(struct usb_gadget_driver *driver, | ||
2527 | int (*bind)(struct usb_gadget *)); | ||
2528 | static int ci13xxx_stop(struct usb_gadget_driver *driver); | ||
2518 | /** | 2529 | /** |
2519 | * Device operations part of the API to the USB controller hardware, | 2530 | * Device operations part of the API to the USB controller hardware, |
2520 | * which don't involve endpoints (or i/o) | 2531 | * which don't involve endpoints (or i/o) |
@@ -2524,17 +2535,19 @@ static const struct usb_gadget_ops usb_gadget_ops = { | |||
2524 | .vbus_session = ci13xxx_vbus_session, | 2535 | .vbus_session = ci13xxx_vbus_session, |
2525 | .wakeup = ci13xxx_wakeup, | 2536 | .wakeup = ci13xxx_wakeup, |
2526 | .vbus_draw = ci13xxx_vbus_draw, | 2537 | .vbus_draw = ci13xxx_vbus_draw, |
2538 | .start = ci13xxx_start, | ||
2539 | .stop = ci13xxx_stop, | ||
2527 | }; | 2540 | }; |
2528 | 2541 | ||
2529 | /** | 2542 | /** |
2530 | * usb_gadget_probe_driver: register a gadget driver | 2543 | * ci13xxx_start: register a gadget driver |
2531 | * @driver: the driver being registered | 2544 | * @driver: the driver being registered |
2532 | * @bind: the driver's bind callback | 2545 | * @bind: the driver's bind callback |
2533 | * | 2546 | * |
2534 | * Check usb_gadget_probe_driver() at <linux/usb/gadget.h> for details. | 2547 | * Check ci13xxx_start() at <linux/usb/gadget.h> for details. |
2535 | * Interrupts are enabled here. | 2548 | * Interrupts are enabled here. |
2536 | */ | 2549 | */ |
2537 | int usb_gadget_probe_driver(struct usb_gadget_driver *driver, | 2550 | static int ci13xxx_start(struct usb_gadget_driver *driver, |
2538 | int (*bind)(struct usb_gadget *)) | 2551 | int (*bind)(struct usb_gadget *)) |
2539 | { | 2552 | { |
2540 | struct ci13xxx *udc = _udc; | 2553 | struct ci13xxx *udc = _udc; |
@@ -2615,10 +2628,13 @@ int usb_gadget_probe_driver(struct usb_gadget_driver *driver, | |||
2615 | if (retval) | 2628 | if (retval) |
2616 | goto done; | 2629 | goto done; |
2617 | spin_unlock_irqrestore(udc->lock, flags); | 2630 | spin_unlock_irqrestore(udc->lock, flags); |
2618 | retval = usb_ep_enable(&udc->ep0out.ep, &ctrl_endpt_out_desc); | 2631 | udc->ep0out.ep.desc = &ctrl_endpt_out_desc; |
2632 | retval = usb_ep_enable(&udc->ep0out.ep); | ||
2619 | if (retval) | 2633 | if (retval) |
2620 | return retval; | 2634 | return retval; |
2621 | retval = usb_ep_enable(&udc->ep0in.ep, &ctrl_endpt_in_desc); | 2635 | |
2636 | udc->ep0in.ep.desc = &ctrl_endpt_in_desc; | ||
2637 | retval = usb_ep_enable(&udc->ep0in.ep); | ||
2622 | if (retval) | 2638 | if (retval) |
2623 | return retval; | 2639 | return retval; |
2624 | spin_lock_irqsave(udc->lock, flags); | 2640 | spin_lock_irqsave(udc->lock, flags); |
@@ -2657,14 +2673,13 @@ int usb_gadget_probe_driver(struct usb_gadget_driver *driver, | |||
2657 | spin_unlock_irqrestore(udc->lock, flags); | 2673 | spin_unlock_irqrestore(udc->lock, flags); |
2658 | return retval; | 2674 | return retval; |
2659 | } | 2675 | } |
2660 | EXPORT_SYMBOL(usb_gadget_probe_driver); | ||
2661 | 2676 | ||
2662 | /** | 2677 | /** |
2663 | * usb_gadget_unregister_driver: unregister a gadget driver | 2678 | * ci13xxx_stop: unregister a gadget driver |
2664 | * | 2679 | * |
2665 | * Check usb_gadget_unregister_driver() at "usb_gadget.h" for details | 2680 | * Check usb_gadget_unregister_driver() at "usb_gadget.h" for details |
2666 | */ | 2681 | */ |
2667 | int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) | 2682 | static int ci13xxx_stop(struct usb_gadget_driver *driver) |
2668 | { | 2683 | { |
2669 | struct ci13xxx *udc = _udc; | 2684 | struct ci13xxx *udc = _udc; |
2670 | unsigned long i, flags; | 2685 | unsigned long i, flags; |
@@ -2726,7 +2741,6 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) | |||
2726 | 2741 | ||
2727 | return 0; | 2742 | return 0; |
2728 | } | 2743 | } |
2729 | EXPORT_SYMBOL(usb_gadget_unregister_driver); | ||
2730 | 2744 | ||
2731 | /****************************************************************************** | 2745 | /****************************************************************************** |
2732 | * BUS block | 2746 | * BUS block |
@@ -2901,12 +2915,23 @@ static int udc_probe(struct ci13xxx_udc_driver *driver, struct device *dev, | |||
2901 | if (retval) | 2915 | if (retval) |
2902 | goto remove_dbg; | 2916 | goto remove_dbg; |
2903 | } | 2917 | } |
2918 | |||
2919 | retval = usb_add_gadget_udc(dev, &udc->gadget); | ||
2920 | if (retval) | ||
2921 | goto remove_trans; | ||
2922 | |||
2904 | pm_runtime_no_callbacks(&udc->gadget.dev); | 2923 | pm_runtime_no_callbacks(&udc->gadget.dev); |
2905 | pm_runtime_enable(&udc->gadget.dev); | 2924 | pm_runtime_enable(&udc->gadget.dev); |
2906 | 2925 | ||
2907 | _udc = udc; | 2926 | _udc = udc; |
2908 | return retval; | 2927 | return retval; |
2909 | 2928 | ||
2929 | remove_trans: | ||
2930 | if (udc->transceiver) { | ||
2931 | otg_set_peripheral(udc->transceiver, &udc->gadget); | ||
2932 | otg_put_transceiver(udc->transceiver); | ||
2933 | } | ||
2934 | |||
2910 | err("error = %i", retval); | 2935 | err("error = %i", retval); |
2911 | remove_dbg: | 2936 | remove_dbg: |
2912 | #ifdef CONFIG_USB_GADGET_DEBUG_FILES | 2937 | #ifdef CONFIG_USB_GADGET_DEBUG_FILES |
@@ -2936,6 +2961,7 @@ static void udc_remove(void) | |||
2936 | err("EINVAL"); | 2961 | err("EINVAL"); |
2937 | return; | 2962 | return; |
2938 | } | 2963 | } |
2964 | usb_del_gadget_udc(&udc->gadget); | ||
2939 | 2965 | ||
2940 | if (udc->transceiver) { | 2966 | if (udc->transceiver) { |
2941 | otg_set_peripheral(udc->transceiver, &udc->gadget); | 2967 | otg_set_peripheral(udc->transceiver, &udc->gadget); |