Commit 5f6901eb3c38a3c8e8896830270a05a5904ace3a

Authored by George Cherian
Committed by Sekhar Nori
1 parent ee89bcd3f1

usb: dwc3: gadget: Adapt gadget to drd library

Adapt the dwc3 gadget to use drd library functions.
In preparation to support DRD on dwc3.

Signed-off-by: George Cherian <george.cherian@ti.com>
[nsekhar@ti.com: fix sparse warnings]
Signed-off-by: Sekhar Nori <nsekhar@ti.com>

Showing 1 changed file with 101 additions and 28 deletions Side-by-side Diff

drivers/usb/dwc3/gadget.c
... ... @@ -29,6 +29,7 @@
29 29  
30 30 #include <linux/usb/ch9.h>
31 31 #include <linux/usb/gadget.h>
  32 +#include <linux/usb/drd.h>
32 33  
33 34 #include "core.h"
34 35 #include "gadget.h"
... ... @@ -2754,6 +2755,89 @@
2754 2755 return ret;
2755 2756 }
2756 2757  
  2758 +static void dwc3_gadget_release(struct device *dev)
  2759 +{
  2760 + struct usb_gadget *gadget = container_of(dev, struct usb_gadget, dev);
  2761 + struct dwc3_gadget *dwc_gadget = gadget_to_dwc_gadget(gadget);
  2762 + struct dwc3 *dwc = dwc_gadget->dwc;
  2763 +
  2764 + dev_dbg(dev, "releasing '%s'\n", dev_name(dev));
  2765 + dwc3_gadget_free_endpoints(dwc);
  2766 + dma_free_coherent(dwc->dev, DWC3_EP0_BOUNCE_SIZE,
  2767 + dwc->ep0_bounce, dwc->ep0_bounce_addr);
  2768 + kfree(dwc->setup_buf);
  2769 + dma_free_coherent(dwc->dev, sizeof(*dwc->ep0_trb),
  2770 + dwc->ep0_trb, dwc->ep0_trb_addr);
  2771 + dma_free_coherent(dwc->dev, sizeof(*dwc->ctrl_req),
  2772 + dwc->ctrl_req, dwc->ctrl_req_addr);
  2773 + usb_drd_unregister_udc(dwc->dev);
  2774 + kfree(dwc_gadget);
  2775 +}
  2776 +
  2777 +static int dwc3_gadget_setup(void *data)
  2778 +{
  2779 + struct dwc3 *dwc = data;
  2780 + struct dwc3_gadget *dwc_gadget;
  2781 + struct usb_drd_gadget *drd_gadget;
  2782 + struct usb_drd_setup *gadget_setup;
  2783 + int ret;
  2784 +
  2785 + drd_gadget = kzalloc(sizeof(*drd_gadget), GFP_KERNEL);
  2786 + if (!drd_gadget) {
  2787 + ret = -ENOMEM;
  2788 + goto err1;
  2789 + }
  2790 +
  2791 + gadget_setup = kzalloc(sizeof(*gadget_setup), GFP_KERNEL);
  2792 + if (!gadget_setup) {
  2793 + ret = -ENOMEM;
  2794 + goto err2;
  2795 + }
  2796 +
  2797 + dwc_gadget = kzalloc(sizeof(*dwc_gadget), GFP_KERNEL);
  2798 + if (!dwc_gadget) {
  2799 + ret = -ENOMEM;
  2800 + goto err3;
  2801 + }
  2802 +
  2803 + drd_gadget->g_driver = dwc->gadget_driver;
  2804 +
  2805 + /*
  2806 + * Pass the DWC3 specific routines for
  2807 + * switching roles to the drd library
  2808 + */
  2809 + gadget_setup->ll_start = NULL;
  2810 + gadget_setup->ll_stop = NULL;
  2811 + gadget_setup->ll_release = dwc3_gadget_release;
  2812 + gadget_setup->data = (void *)dwc;
  2813 + drd_gadget->gadget_setup = gadget_setup;
  2814 +
  2815 + dwc_gadget->gadget.ops = &dwc3_gadget_ops;
  2816 + dwc_gadget->gadget.max_speed = USB_SPEED_SUPER;
  2817 + dwc_gadget->gadget.speed = USB_SPEED_UNKNOWN;
  2818 + dwc_gadget->gadget.sg_supported = true;
  2819 + dwc_gadget->gadget.name = "dwc3-gadget";
  2820 + dwc_gadget->dwc = dwc;
  2821 + drd_gadget->gadget = &dwc_gadget->gadget;
  2822 +
  2823 + /*
  2824 + * Per databook, DWC3 needs buffer size to be aligned to MaxPacketSize
  2825 + * on ep out.
  2826 + */
  2827 + dwc_gadget->gadget.quirk_ep_out_aligned_size = true;
  2828 + dwc->dwc_gadget = dwc_gadget;
  2829 + usb_drd_register_udc(dwc->dev, drd_gadget);
  2830 +
  2831 + return 0;
  2832 +
  2833 +err3:
  2834 + kfree(gadget_setup);
  2835 +err2:
  2836 + kfree(drd_gadget);
  2837 +err1:
  2838 + return ret;
  2839 +}
  2840 +
2757 2841 /**
2758 2842 * dwc3_gadget_init - Initializes gadget related registers
2759 2843 * @dwc: pointer to our controller context structure
... ... @@ -2763,7 +2847,6 @@
2763 2847 int dwc3_gadget_init(struct dwc3 *dwc)
2764 2848 {
2765 2849 int ret;
2766   - struct dwc3_gadget *dwc_gadget;
2767 2850  
2768 2851 dwc->ctrl_req = dma_alloc_coherent(dwc->dev, sizeof(*dwc->ctrl_req),
2769 2852 &dwc->ctrl_req_addr, GFP_KERNEL);
2770 2853  
2771 2854  
2772 2855  
... ... @@ -2797,26 +2880,11 @@
2797 2880 goto err3;
2798 2881 }
2799 2882  
2800   - dwc_gadget = kzalloc(sizeof(*dwc_gadget), GFP_KERNEL);
2801   - if (!dwc_gadget) {
2802   - ret = -ENOMEM;
  2883 + ret = dwc3_gadget_setup(dwc);
  2884 + if (ret)
2803 2885 goto err3;
2804   - }
2805 2886  
2806   - dwc_gadget->gadget.ops = &dwc3_gadget_ops;
2807   - dwc_gadget->gadget.max_speed = USB_SPEED_SUPER;
2808   - dwc_gadget->gadget.speed = USB_SPEED_UNKNOWN;
2809   - dwc_gadget->gadget.sg_supported = true;
2810   - dwc_gadget->gadget.name = "dwc3-gadget";
2811   - dwc_gadget->dwc = dwc;
2812   -
2813 2887 /*
2814   - * Per databook, DWC3 needs buffer size to be aligned to MaxPacketSize
2815   - * on ep out.
2816   - */
2817   - dwc_gadget->gadget.quirk_ep_out_aligned_size = true;
2818   -
2819   - /*
2820 2888 * REVISIT: Here we should clear all pending IRQs to be
2821 2889 * sure we're starting from a well known location.
2822 2890 */
... ... @@ -2825,7 +2893,8 @@
2825 2893 if (ret)
2826 2894 goto err4;
2827 2895  
2828   - ret = usb_add_gadget_udc(dwc->dev, &dwc_gadget->gadget);
  2896 + ret = usb_add_gadget_udc_release(dwc->dev, &dwc->dwc_gadget->gadget,
  2897 + dwc3_gadget_release);
2829 2898 if (ret) {
2830 2899 dev_err(dwc->dev, "failed to register udc\n");
2831 2900 goto err4;
... ... @@ -2834,6 +2903,7 @@
2834 2903 return 0;
2835 2904  
2836 2905 err4:
  2906 + usb_drd_unregister_udc(dwc->dev);
2837 2907 dwc3_gadget_free_endpoints(dwc);
2838 2908 dma_free_coherent(dwc->dev, DWC3_EP0_BOUNCE_SIZE,
2839 2909 dwc->ep0_bounce, dwc->ep0_bounce_addr);
2840 2910  
2841 2911  
2842 2912  
2843 2913  
2844 2914  
... ... @@ -2859,20 +2929,23 @@
2859 2929 {
2860 2930 struct dwc3_gadget *dwc_gadget = dwc->dwc_gadget;
2861 2931  
2862   - usb_del_gadget_udc(&dwc_gadget->gadget);
2863 2932  
2864   - dwc3_gadget_free_endpoints(dwc);
  2933 + if (usb_drd_get_state(dwc->dev) & DRD_DEVICE_REGISTERED) {
  2934 + usb_del_gadget_udc(&dwc_gadget->gadget);
2865 2935  
2866   - dma_free_coherent(dwc->dev, DWC3_EP0_BOUNCE_SIZE,
2867   - dwc->ep0_bounce, dwc->ep0_bounce_addr);
  2936 + dwc3_gadget_free_endpoints(dwc);
2868 2937  
2869   - kfree(dwc->setup_buf);
  2938 + dma_free_coherent(dwc->dev, DWC3_EP0_BOUNCE_SIZE,
  2939 + dwc->ep0_bounce, dwc->ep0_bounce_addr);
2870 2940  
2871   - dma_free_coherent(dwc->dev, sizeof(*dwc->ep0_trb),
2872   - dwc->ep0_trb, dwc->ep0_trb_addr);
  2941 + kfree(dwc->setup_buf);
2873 2942  
2874   - dma_free_coherent(dwc->dev, sizeof(*dwc->ctrl_req),
2875   - dwc->ctrl_req, dwc->ctrl_req_addr);
  2943 + dma_free_coherent(dwc->dev, sizeof(*dwc->ep0_trb),
  2944 + dwc->ep0_trb, dwc->ep0_trb_addr);
  2945 +
  2946 + dma_free_coherent(dwc->dev, sizeof(*dwc->ctrl_req),
  2947 + dwc->ctrl_req, dwc->ctrl_req_addr);
  2948 + }
2876 2949 }
2877 2950  
2878 2951 int dwc3_gadget_suspend(struct dwc3 *dwc)