xref: /OK3568_Linux_fs/kernel/Documentation/driver-api/soundwire/locking.rst (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun=================
2*4882a593SmuzhiyunSoundWire Locking
3*4882a593Smuzhiyun=================
4*4882a593Smuzhiyun
5*4882a593SmuzhiyunThis document explains locking mechanism of the SoundWire Bus. Bus uses
6*4882a593Smuzhiyunfollowing locks in order to avoid race conditions in Bus operations on
7*4882a593Smuzhiyunshared resources.
8*4882a593Smuzhiyun
9*4882a593Smuzhiyun  - Bus lock
10*4882a593Smuzhiyun
11*4882a593Smuzhiyun  - Message lock
12*4882a593Smuzhiyun
13*4882a593SmuzhiyunBus lock
14*4882a593Smuzhiyun========
15*4882a593Smuzhiyun
16*4882a593SmuzhiyunSoundWire Bus lock is a mutex and is part of Bus data structure
17*4882a593Smuzhiyun(sdw_bus) which is used for every Bus instance. This lock is used to
18*4882a593Smuzhiyunserialize each of the following operations(s) within SoundWire Bus instance.
19*4882a593Smuzhiyun
20*4882a593Smuzhiyun  - Addition and removal of Slave(s), changing Slave status.
21*4882a593Smuzhiyun
22*4882a593Smuzhiyun  - Prepare, Enable, Disable and De-prepare stream operations.
23*4882a593Smuzhiyun
24*4882a593Smuzhiyun  - Access of Stream data structure.
25*4882a593Smuzhiyun
26*4882a593SmuzhiyunMessage lock
27*4882a593Smuzhiyun============
28*4882a593Smuzhiyun
29*4882a593SmuzhiyunSoundWire message transfer lock. This mutex is part of
30*4882a593SmuzhiyunBus data structure (sdw_bus). This lock is used to serialize the message
31*4882a593Smuzhiyuntransfers (read/write) within a SoundWire Bus instance.
32*4882a593Smuzhiyun
33*4882a593SmuzhiyunBelow examples show how locks are acquired.
34*4882a593Smuzhiyun
35*4882a593SmuzhiyunExample 1
36*4882a593Smuzhiyun---------
37*4882a593Smuzhiyun
38*4882a593SmuzhiyunMessage transfer.
39*4882a593Smuzhiyun
40*4882a593Smuzhiyun  1. For every message transfer
41*4882a593Smuzhiyun
42*4882a593Smuzhiyun     a. Acquire Message lock.
43*4882a593Smuzhiyun
44*4882a593Smuzhiyun     b. Transfer message (Read/Write) to Slave1 or broadcast message on
45*4882a593Smuzhiyun        Bus in case of bank switch.
46*4882a593Smuzhiyun
47*4882a593Smuzhiyun     c. Release Message lock
48*4882a593Smuzhiyun
49*4882a593Smuzhiyun     ::
50*4882a593Smuzhiyun
51*4882a593Smuzhiyun	+----------+                    +---------+
52*4882a593Smuzhiyun	|          |                    |         |
53*4882a593Smuzhiyun	|   Bus    |                    | Master  |
54*4882a593Smuzhiyun	|          |                    | Driver  |
55*4882a593Smuzhiyun	|          |                    |         |
56*4882a593Smuzhiyun	+----+-----+                    +----+----+
57*4882a593Smuzhiyun	     |                               |
58*4882a593Smuzhiyun	     |     bus->ops->xfer_msg()      |
59*4882a593Smuzhiyun	     <-------------------------------+   a. Acquire Message lock
60*4882a593Smuzhiyun	     |                               |   b. Transfer message
61*4882a593Smuzhiyun	     |                               |
62*4882a593Smuzhiyun	     +------------------------------->   c. Release Message lock
63*4882a593Smuzhiyun	     |    return success/error       |   d. Return success/error
64*4882a593Smuzhiyun	     |                               |
65*4882a593Smuzhiyun	     +                               +
66*4882a593Smuzhiyun
67*4882a593SmuzhiyunExample 2
68*4882a593Smuzhiyun---------
69*4882a593Smuzhiyun
70*4882a593SmuzhiyunPrepare operation.
71*4882a593Smuzhiyun
72*4882a593Smuzhiyun  1. Acquire lock for Bus instance associated with Master 1.
73*4882a593Smuzhiyun
74*4882a593Smuzhiyun  2. For every message transfer in Prepare operation
75*4882a593Smuzhiyun
76*4882a593Smuzhiyun     a. Acquire Message lock.
77*4882a593Smuzhiyun
78*4882a593Smuzhiyun     b. Transfer message (Read/Write) to Slave1 or broadcast message on
79*4882a593Smuzhiyun        Bus in case of bank switch.
80*4882a593Smuzhiyun
81*4882a593Smuzhiyun     c. Release Message lock.
82*4882a593Smuzhiyun
83*4882a593Smuzhiyun  3. Release lock for Bus instance associated with Master 1 ::
84*4882a593Smuzhiyun
85*4882a593Smuzhiyun	+----------+                    +---------+
86*4882a593Smuzhiyun	|          |                    |         |
87*4882a593Smuzhiyun	|   Bus    |                    | Master  |
88*4882a593Smuzhiyun	|          |                    | Driver  |
89*4882a593Smuzhiyun	|          |                    |         |
90*4882a593Smuzhiyun	+----+-----+                    +----+----+
91*4882a593Smuzhiyun	     |                               |
92*4882a593Smuzhiyun	     |    sdw_prepare_stream()       |
93*4882a593Smuzhiyun	     <-------------------------------+   1. Acquire bus lock
94*4882a593Smuzhiyun	     |                               |   2. Perform stream prepare
95*4882a593Smuzhiyun	     |                               |
96*4882a593Smuzhiyun	     |                               |
97*4882a593Smuzhiyun	     |     bus->ops->xfer_msg()      |
98*4882a593Smuzhiyun	     <-------------------------------+   a. Acquire Message lock
99*4882a593Smuzhiyun	     |                               |   b. Transfer message
100*4882a593Smuzhiyun	     |                               |
101*4882a593Smuzhiyun	     +------------------------------->   c. Release Message lock
102*4882a593Smuzhiyun	     |    return success/error       |   d. Return success/error
103*4882a593Smuzhiyun	     |                               |
104*4882a593Smuzhiyun	     |                               |
105*4882a593Smuzhiyun	     |    return success/error       |   3. Release bus lock
106*4882a593Smuzhiyun	     +------------------------------->   4. Return success/error
107*4882a593Smuzhiyun	     |                               |
108*4882a593Smuzhiyun	     +                               +
109