xref: /OK3568_Linux_fs/kernel/Documentation/usb/dwc3.rst (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun===========
2*4882a593SmuzhiyunDWC3 driver
3*4882a593Smuzhiyun===========
4*4882a593Smuzhiyun
5*4882a593Smuzhiyun
6*4882a593SmuzhiyunTODO
7*4882a593Smuzhiyun~~~~
8*4882a593Smuzhiyun
9*4882a593SmuzhiyunPlease pick something while reading :)
10*4882a593Smuzhiyun
11*4882a593Smuzhiyun- Convert interrupt handler to per-ep-thread-irq
12*4882a593Smuzhiyun
13*4882a593Smuzhiyun  As it turns out some DWC3-commands ~1ms to complete. Currently we spin
14*4882a593Smuzhiyun  until the command completes which is bad.
15*4882a593Smuzhiyun
16*4882a593Smuzhiyun  Implementation idea:
17*4882a593Smuzhiyun
18*4882a593Smuzhiyun  - dwc core implements a demultiplexing irq chip for interrupts per
19*4882a593Smuzhiyun    endpoint. The interrupt numbers are allocated during probe and belong
20*4882a593Smuzhiyun    to the device. If MSI provides per-endpoint interrupt this dummy
21*4882a593Smuzhiyun    interrupt chip can be replaced with "real" interrupts.
22*4882a593Smuzhiyun  - interrupts are requested / allocated on usb_ep_enable() and removed on
23*4882a593Smuzhiyun    usb_ep_disable(). Worst case are 32 interrupts, the lower limit is two
24*4882a593Smuzhiyun    for ep0/1.
25*4882a593Smuzhiyun  - dwc3_send_gadget_ep_cmd() will sleep in wait_for_completion_timeout()
26*4882a593Smuzhiyun    until the command completes.
27*4882a593Smuzhiyun  - the interrupt handler is split into the following pieces:
28*4882a593Smuzhiyun
29*4882a593Smuzhiyun    - primary handler of the device
30*4882a593Smuzhiyun      goes through every event and calls generic_handle_irq() for event
31*4882a593Smuzhiyun      it. On return from generic_handle_irq() in acknowledges the event
32*4882a593Smuzhiyun      counter so interrupt goes away (eventually).
33*4882a593Smuzhiyun
34*4882a593Smuzhiyun    - threaded handler of the device
35*4882a593Smuzhiyun      none
36*4882a593Smuzhiyun
37*4882a593Smuzhiyun    - primary handler of the EP-interrupt
38*4882a593Smuzhiyun      reads the event and tries to process it. Everything that requires
39*4882a593Smuzhiyun      sleeping is handed over to the Thread. The event is saved in an
40*4882a593Smuzhiyun      per-endpoint data-structure.
41*4882a593Smuzhiyun      We probably have to pay attention not to process events once we
42*4882a593Smuzhiyun      handed something to thread so we don't process event X prio Y
43*4882a593Smuzhiyun      where X > Y.
44*4882a593Smuzhiyun
45*4882a593Smuzhiyun    - threaded handler of the EP-interrupt
46*4882a593Smuzhiyun      handles the remaining EP work which might sleep such as waiting
47*4882a593Smuzhiyun      for command completion.
48*4882a593Smuzhiyun
49*4882a593Smuzhiyun  Latency:
50*4882a593Smuzhiyun
51*4882a593Smuzhiyun   There should be no increase in latency since the interrupt-thread has a
52*4882a593Smuzhiyun   high priority and will be run before an average task in user land
53*4882a593Smuzhiyun   (except the user changed priorities).
54