Luca Ceresoli | f6fcefa | 2020-01-29 16:19:51 +0100 | [diff] [blame] | 1 | ================================ |
| 2 | I2C muxes and complex topologies |
| 3 | ================================ |
Peter Rosin | 2254d24 | 2016-05-04 22:15:30 +0200 | [diff] [blame] | 4 | |
Luca Ceresoli | 2f07c05 | 2020-01-29 16:19:29 +0100 | [diff] [blame] | 5 | There are a couple of reasons for building more complex I2C topologies |
| 6 | than a straight-forward I2C bus with one adapter and one or more devices. |
Peter Rosin | 2254d24 | 2016-05-04 22:15:30 +0200 | [diff] [blame] | 7 | |
| 8 | 1. A mux may be needed on the bus to prevent address collisions. |
| 9 | |
| 10 | 2. The bus may be accessible from some external bus master, and arbitration |
| 11 | may be needed to determine if it is ok to access the bus. |
| 12 | |
| 13 | 3. A device (particularly RF tuners) may want to avoid the digital noise |
Luca Ceresoli | 2f07c05 | 2020-01-29 16:19:29 +0100 | [diff] [blame] | 14 | from the I2C bus, at least most of the time, and sits behind a gate |
Peter Rosin | 2254d24 | 2016-05-04 22:15:30 +0200 | [diff] [blame] | 15 | that has to be operated before the device can be accessed. |
| 16 | |
| 17 | Etc |
Mauro Carvalho Chehab | ccf988b | 2019-07-26 09:51:16 -0300 | [diff] [blame] | 18 | === |
Peter Rosin | 2254d24 | 2016-05-04 22:15:30 +0200 | [diff] [blame] | 19 | |
Luca Ceresoli | 2f07c05 | 2020-01-29 16:19:29 +0100 | [diff] [blame] | 20 | These constructs are represented as I2C adapter trees by Linux, where |
Peter Rosin | 2254d24 | 2016-05-04 22:15:30 +0200 | [diff] [blame] | 21 | each adapter has a parent adapter (except the root adapter) and zero or |
| 22 | more child adapters. The root adapter is the actual adapter that issues |
Luca Ceresoli | 2f07c05 | 2020-01-29 16:19:29 +0100 | [diff] [blame] | 23 | I2C transfers, and all adapters with a parent are part of an "i2c-mux" |
Peter Rosin | 2254d24 | 2016-05-04 22:15:30 +0200 | [diff] [blame] | 24 | object (quoted, since it can also be an arbitrator or a gate). |
| 25 | |
| 26 | Depending of the particular mux driver, something happens when there is |
Luca Ceresoli | 2f07c05 | 2020-01-29 16:19:29 +0100 | [diff] [blame] | 27 | an I2C transfer on one of its child adapters. The mux driver can |
Peter Rosin | 2254d24 | 2016-05-04 22:15:30 +0200 | [diff] [blame] | 28 | obviously operate a mux, but it can also do arbitration with an external |
| 29 | bus master or open a gate. The mux driver has two operations for this, |
| 30 | select and deselect. select is called before the transfer and (the |
| 31 | optional) deselect is called after the transfer. |
| 32 | |
| 33 | |
| 34 | Locking |
| 35 | ======= |
| 36 | |
Luca Ceresoli | 2f07c05 | 2020-01-29 16:19:29 +0100 | [diff] [blame] | 37 | There are two variants of locking available to I2C muxes, they can be |
Peter Rosin | 2254d24 | 2016-05-04 22:15:30 +0200 | [diff] [blame] | 38 | mux-locked or parent-locked muxes. As is evident from below, it can be |
| 39 | useful to know if a mux is mux-locked or if it is parent-locked. The |
| 40 | following list was correct at the time of writing: |
| 41 | |
Mauro Carvalho Chehab | ccf988b | 2019-07-26 09:51:16 -0300 | [diff] [blame] | 42 | In drivers/i2c/muxes/: |
| 43 | |
| 44 | ====================== ============================================= |
Peter Rosin | 2254d24 | 2016-05-04 22:15:30 +0200 | [diff] [blame] | 45 | i2c-arb-gpio-challenge Parent-locked |
| 46 | i2c-mux-gpio Normally parent-locked, mux-locked iff |
| 47 | all involved gpio pins are controlled by the |
Luca Ceresoli | 2f07c05 | 2020-01-29 16:19:29 +0100 | [diff] [blame] | 48 | same I2C root adapter that they mux. |
Peter Rosin | 234fa0a | 2017-08-02 11:48:46 +0200 | [diff] [blame] | 49 | i2c-mux-gpmux Normally parent-locked, mux-locked iff |
| 50 | specified in device-tree. |
| 51 | i2c-mux-ltc4306 Mux-locked |
| 52 | i2c-mux-mlxcpld Parent-locked |
Peter Rosin | 2254d24 | 2016-05-04 22:15:30 +0200 | [diff] [blame] | 53 | i2c-mux-pca9541 Parent-locked |
| 54 | i2c-mux-pca954x Parent-locked |
| 55 | i2c-mux-pinctrl Normally parent-locked, mux-locked iff |
| 56 | all involved pinctrl devices are controlled |
Luca Ceresoli | 2f07c05 | 2020-01-29 16:19:29 +0100 | [diff] [blame] | 57 | by the same I2C root adapter that they mux. |
Peter Rosin | 2254d24 | 2016-05-04 22:15:30 +0200 | [diff] [blame] | 58 | i2c-mux-reg Parent-locked |
Mauro Carvalho Chehab | ccf988b | 2019-07-26 09:51:16 -0300 | [diff] [blame] | 59 | ====================== ============================================= |
Peter Rosin | 2254d24 | 2016-05-04 22:15:30 +0200 | [diff] [blame] | 60 | |
Mauro Carvalho Chehab | ccf988b | 2019-07-26 09:51:16 -0300 | [diff] [blame] | 61 | In drivers/iio/: |
| 62 | |
| 63 | ====================== ============================================= |
Peter Rosin | 234fa0a | 2017-08-02 11:48:46 +0200 | [diff] [blame] | 64 | gyro/mpu3050 Mux-locked |
Peter Rosin | 1ffcfaf | 2016-05-04 22:15:31 +0200 | [diff] [blame] | 65 | imu/inv_mpu6050/ Mux-locked |
Mauro Carvalho Chehab | ccf988b | 2019-07-26 09:51:16 -0300 | [diff] [blame] | 66 | ====================== ============================================= |
Peter Rosin | 2254d24 | 2016-05-04 22:15:30 +0200 | [diff] [blame] | 67 | |
Mauro Carvalho Chehab | ccf988b | 2019-07-26 09:51:16 -0300 | [diff] [blame] | 68 | In drivers/media/: |
| 69 | |
| 70 | ======================= ============================================= |
Peter Rosin | 234fa0a | 2017-08-02 11:48:46 +0200 | [diff] [blame] | 71 | dvb-frontends/lgdt3306a Mux-locked |
Peter Rosin | 2254d24 | 2016-05-04 22:15:30 +0200 | [diff] [blame] | 72 | dvb-frontends/m88ds3103 Parent-locked |
| 73 | dvb-frontends/rtl2830 Parent-locked |
Peter Rosin | 1cf79db | 2016-05-04 22:15:33 +0200 | [diff] [blame] | 74 | dvb-frontends/rtl2832 Mux-locked |
Antti Palosaari | e6d7ffc | 2016-05-04 22:15:32 +0200 | [diff] [blame] | 75 | dvb-frontends/si2168 Mux-locked |
Peter Rosin | 2254d24 | 2016-05-04 22:15:30 +0200 | [diff] [blame] | 76 | usb/cx231xx/ Parent-locked |
Mauro Carvalho Chehab | ccf988b | 2019-07-26 09:51:16 -0300 | [diff] [blame] | 77 | ======================= ============================================= |
Peter Rosin | 2254d24 | 2016-05-04 22:15:30 +0200 | [diff] [blame] | 78 | |
| 79 | |
| 80 | Mux-locked muxes |
| 81 | ---------------- |
| 82 | |
| 83 | Mux-locked muxes does not lock the entire parent adapter during the |
| 84 | full select-transfer-deselect transaction, only the muxes on the parent |
| 85 | adapter are locked. Mux-locked muxes are mostly interesting if the |
Luca Ceresoli | 2f07c05 | 2020-01-29 16:19:29 +0100 | [diff] [blame] | 86 | select and/or deselect operations must use I2C transfers to complete |
Peter Rosin | 2254d24 | 2016-05-04 22:15:30 +0200 | [diff] [blame] | 87 | their tasks. Since the parent adapter is not fully locked during the |
Luca Ceresoli | 2f07c05 | 2020-01-29 16:19:29 +0100 | [diff] [blame] | 88 | full transaction, unrelated I2C transfers may interleave the different |
Peter Rosin | 2254d24 | 2016-05-04 22:15:30 +0200 | [diff] [blame] | 89 | stages of the transaction. This has the benefit that the mux driver |
| 90 | may be easier and cleaner to implement, but it has some caveats. |
| 91 | |
Mauro Carvalho Chehab | ccf988b | 2019-07-26 09:51:16 -0300 | [diff] [blame] | 92 | ==== ===================================================================== |
Peter Rosin | 2254d24 | 2016-05-04 22:15:30 +0200 | [diff] [blame] | 93 | ML1. If you build a topology with a mux-locked mux being the parent |
| 94 | of a parent-locked mux, this might break the expectation from the |
| 95 | parent-locked mux that the root adapter is locked during the |
| 96 | transaction. |
| 97 | |
| 98 | ML2. It is not safe to build arbitrary topologies with two (or more) |
| 99 | mux-locked muxes that are not siblings, when there are address |
| 100 | collisions between the devices on the child adapters of these |
| 101 | non-sibling muxes. |
| 102 | |
| 103 | I.e. the select-transfer-deselect transaction targeting e.g. device |
| 104 | address 0x42 behind mux-one may be interleaved with a similar |
| 105 | operation targeting device address 0x42 behind mux-two. The |
| 106 | intension with such a topology would in this hypothetical example |
| 107 | be that mux-one and mux-two should not be selected simultaneously, |
| 108 | but mux-locked muxes do not guarantee that in all topologies. |
| 109 | |
| 110 | ML3. A mux-locked mux cannot be used by a driver for auto-closing |
| 111 | gates/muxes, i.e. something that closes automatically after a given |
Luca Ceresoli | 2f07c05 | 2020-01-29 16:19:29 +0100 | [diff] [blame] | 112 | number (one, in most cases) of I2C transfers. Unrelated I2C transfers |
Peter Rosin | 2254d24 | 2016-05-04 22:15:30 +0200 | [diff] [blame] | 113 | may creep in and close prematurely. |
| 114 | |
Luca Ceresoli | 2f07c05 | 2020-01-29 16:19:29 +0100 | [diff] [blame] | 115 | ML4. If any non-I2C operation in the mux driver changes the I2C mux state, |
Peter Rosin | 2254d24 | 2016-05-04 22:15:30 +0200 | [diff] [blame] | 116 | the driver has to lock the root adapter during that operation. |
| 117 | Otherwise garbage may appear on the bus as seen from devices |
Luca Ceresoli | 2f07c05 | 2020-01-29 16:19:29 +0100 | [diff] [blame] | 118 | behind the mux, when an unrelated I2C transfer is in flight during |
| 119 | the non-I2C mux-changing operation. |
Mauro Carvalho Chehab | ccf988b | 2019-07-26 09:51:16 -0300 | [diff] [blame] | 120 | ==== ===================================================================== |
Peter Rosin | 2254d24 | 2016-05-04 22:15:30 +0200 | [diff] [blame] | 121 | |
| 122 | |
| 123 | Mux-locked Example |
| 124 | ------------------ |
| 125 | |
Mauro Carvalho Chehab | ccf988b | 2019-07-26 09:51:16 -0300 | [diff] [blame] | 126 | |
| 127 | :: |
| 128 | |
Peter Rosin | 2254d24 | 2016-05-04 22:15:30 +0200 | [diff] [blame] | 129 | .----------. .--------. |
| 130 | .--------. | mux- |-----| dev D1 | |
| 131 | | root |--+--| locked | '--------' |
| 132 | '--------' | | mux M1 |--. .--------. |
| 133 | | '----------' '--| dev D2 | |
| 134 | | .--------. '--------' |
| 135 | '--| dev D3 | |
| 136 | '--------' |
| 137 | |
| 138 | When there is an access to D1, this happens: |
| 139 | |
Luca Ceresoli | 48ca3b7 | 2020-01-29 16:19:31 +0100 | [diff] [blame] | 140 | 1. Someone issues an I2C transfer to D1. |
Peter Rosin | 2254d24 | 2016-05-04 22:15:30 +0200 | [diff] [blame] | 141 | 2. M1 locks muxes on its parent (the root adapter in this case). |
| 142 | 3. M1 calls ->select to ready the mux. |
Luca Ceresoli | 48ca3b7 | 2020-01-29 16:19:31 +0100 | [diff] [blame] | 143 | 4. M1 (presumably) does some I2C transfers as part of its select. |
| 144 | These transfers are normal I2C transfers that locks the parent |
Peter Rosin | 2254d24 | 2016-05-04 22:15:30 +0200 | [diff] [blame] | 145 | adapter. |
Luca Ceresoli | 48ca3b7 | 2020-01-29 16:19:31 +0100 | [diff] [blame] | 146 | 5. M1 feeds the I2C transfer from step 1 to its parent adapter as a |
| 147 | normal I2C transfer that locks the parent adapter. |
Peter Rosin | 2254d24 | 2016-05-04 22:15:30 +0200 | [diff] [blame] | 148 | 6. M1 calls ->deselect, if it has one. |
| 149 | 7. Same rules as in step 4, but for ->deselect. |
| 150 | 8. M1 unlocks muxes on its parent. |
| 151 | |
| 152 | This means that accesses to D2 are lockout out for the full duration |
| 153 | of the entire operation. But accesses to D3 are possibly interleaved |
| 154 | at any point. |
| 155 | |
| 156 | |
| 157 | Parent-locked muxes |
| 158 | ------------------- |
| 159 | |
| 160 | Parent-locked muxes lock the parent adapter during the full select- |
| 161 | transfer-deselect transaction. The implication is that the mux driver |
Luca Ceresoli | 2f07c05 | 2020-01-29 16:19:29 +0100 | [diff] [blame] | 162 | has to ensure that any and all I2C transfers through that parent |
| 163 | adapter during the transaction are unlocked I2C transfers (using e.g. |
Peter Rosin | 2254d24 | 2016-05-04 22:15:30 +0200 | [diff] [blame] | 164 | __i2c_transfer), or a deadlock will follow. There are a couple of |
| 165 | caveats. |
| 166 | |
Mauro Carvalho Chehab | ccf988b | 2019-07-26 09:51:16 -0300 | [diff] [blame] | 167 | ==== ==================================================================== |
Peter Rosin | 2254d24 | 2016-05-04 22:15:30 +0200 | [diff] [blame] | 168 | PL1. If you build a topology with a parent-locked mux being the child |
| 169 | of another mux, this might break a possible assumption from the |
| 170 | child mux that the root adapter is unused between its select op |
| 171 | and the actual transfer (e.g. if the child mux is auto-closing |
Luca Ceresoli | 48ca3b7 | 2020-01-29 16:19:31 +0100 | [diff] [blame] | 172 | and the parent mux issues I2C transfers as part of its select). |
Peter Rosin | 2254d24 | 2016-05-04 22:15:30 +0200 | [diff] [blame] | 173 | This is especially the case if the parent mux is mux-locked, but |
| 174 | it may also happen if the parent mux is parent-locked. |
| 175 | |
| 176 | PL2. If select/deselect calls out to other subsystems such as gpio, |
Luca Ceresoli | 2f07c05 | 2020-01-29 16:19:29 +0100 | [diff] [blame] | 177 | pinctrl, regmap or iio, it is essential that any I2C transfers |
Peter Rosin | 2254d24 | 2016-05-04 22:15:30 +0200 | [diff] [blame] | 178 | caused by these subsystems are unlocked. This can be convoluted to |
| 179 | accomplish, maybe even impossible if an acceptably clean solution |
| 180 | is sought. |
Mauro Carvalho Chehab | ccf988b | 2019-07-26 09:51:16 -0300 | [diff] [blame] | 181 | ==== ==================================================================== |
Peter Rosin | 2254d24 | 2016-05-04 22:15:30 +0200 | [diff] [blame] | 182 | |
| 183 | |
| 184 | Parent-locked Example |
| 185 | --------------------- |
| 186 | |
Mauro Carvalho Chehab | ccf988b | 2019-07-26 09:51:16 -0300 | [diff] [blame] | 187 | :: |
| 188 | |
Peter Rosin | 2254d24 | 2016-05-04 22:15:30 +0200 | [diff] [blame] | 189 | .----------. .--------. |
| 190 | .--------. | parent- |-----| dev D1 | |
| 191 | | root |--+--| locked | '--------' |
| 192 | '--------' | | mux M1 |--. .--------. |
| 193 | | '----------' '--| dev D2 | |
| 194 | | .--------. '--------' |
| 195 | '--| dev D3 | |
| 196 | '--------' |
| 197 | |
| 198 | When there is an access to D1, this happens: |
| 199 | |
Luca Ceresoli | 48ca3b7 | 2020-01-29 16:19:31 +0100 | [diff] [blame] | 200 | 1. Someone issues an I2C transfer to D1. |
Mauro Carvalho Chehab | ccf988b | 2019-07-26 09:51:16 -0300 | [diff] [blame] | 201 | 2. M1 locks muxes on its parent (the root adapter in this case). |
| 202 | 3. M1 locks its parent adapter. |
| 203 | 4. M1 calls ->select to ready the mux. |
Luca Ceresoli | 48ca3b7 | 2020-01-29 16:19:31 +0100 | [diff] [blame] | 204 | 5. If M1 does any I2C transfers (on this root adapter) as part of |
| 205 | its select, those transfers must be unlocked I2C transfers so |
Mauro Carvalho Chehab | ccf988b | 2019-07-26 09:51:16 -0300 | [diff] [blame] | 206 | that they do not deadlock the root adapter. |
Luca Ceresoli | 48ca3b7 | 2020-01-29 16:19:31 +0100 | [diff] [blame] | 207 | 6. M1 feeds the I2C transfer from step 1 to the root adapter as an |
| 208 | unlocked I2C transfer, so that it does not deadlock the parent |
Mauro Carvalho Chehab | ccf988b | 2019-07-26 09:51:16 -0300 | [diff] [blame] | 209 | adapter. |
| 210 | 7. M1 calls ->deselect, if it has one. |
| 211 | 8. Same rules as in step 5, but for ->deselect. |
| 212 | 9. M1 unlocks its parent adapter. |
| 213 | 10. M1 unlocks muxes on its parent. |
Peter Rosin | 2254d24 | 2016-05-04 22:15:30 +0200 | [diff] [blame] | 214 | |
| 215 | |
| 216 | This means that accesses to both D2 and D3 are locked out for the full |
| 217 | duration of the entire operation. |
| 218 | |
| 219 | |
| 220 | Complex Examples |
| 221 | ================ |
| 222 | |
| 223 | Parent-locked mux as parent of parent-locked mux |
| 224 | ------------------------------------------------ |
| 225 | |
Mauro Carvalho Chehab | ccf988b | 2019-07-26 09:51:16 -0300 | [diff] [blame] | 226 | This is a useful topology, but it can be bad:: |
Peter Rosin | 2254d24 | 2016-05-04 22:15:30 +0200 | [diff] [blame] | 227 | |
| 228 | .----------. .----------. .--------. |
| 229 | .--------. | parent- |-----| parent- |-----| dev D1 | |
| 230 | | root |--+--| locked | | locked | '--------' |
| 231 | '--------' | | mux M1 |--. | mux M2 |--. .--------. |
| 232 | | '----------' | '----------' '--| dev D2 | |
| 233 | | .--------. | .--------. '--------' |
| 234 | '--| dev D4 | '--| dev D3 | |
| 235 | '--------' '--------' |
| 236 | |
| 237 | When any device is accessed, all other devices are locked out for |
| 238 | the full duration of the operation (both muxes lock their parent, |
| 239 | and specifically when M2 requests its parent to lock, M1 passes |
| 240 | the buck to the root adapter). |
| 241 | |
| 242 | This topology is bad if M2 is an auto-closing mux and M1->select |
Luca Ceresoli | 2f07c05 | 2020-01-29 16:19:29 +0100 | [diff] [blame] | 243 | issues any unlocked I2C transfers on the root adapter that may leak |
Peter Rosin | 2254d24 | 2016-05-04 22:15:30 +0200 | [diff] [blame] | 244 | through and be seen by the M2 adapter, thus closing M2 prematurely. |
| 245 | |
| 246 | |
| 247 | Mux-locked mux as parent of mux-locked mux |
| 248 | ------------------------------------------ |
| 249 | |
Mauro Carvalho Chehab | ccf988b | 2019-07-26 09:51:16 -0300 | [diff] [blame] | 250 | This is a good topology:: |
Peter Rosin | 2254d24 | 2016-05-04 22:15:30 +0200 | [diff] [blame] | 251 | |
| 252 | .----------. .----------. .--------. |
| 253 | .--------. | mux- |-----| mux- |-----| dev D1 | |
| 254 | | root |--+--| locked | | locked | '--------' |
| 255 | '--------' | | mux M1 |--. | mux M2 |--. .--------. |
| 256 | | '----------' | '----------' '--| dev D2 | |
| 257 | | .--------. | .--------. '--------' |
| 258 | '--| dev D4 | '--| dev D3 | |
| 259 | '--------' '--------' |
| 260 | |
| 261 | When device D1 is accessed, accesses to D2 are locked out for the |
| 262 | full duration of the operation (muxes on the top child adapter of M1 |
| 263 | are locked). But accesses to D3 and D4 are possibly interleaved at |
| 264 | any point. Accesses to D3 locks out D1 and D2, but accesses to D4 |
| 265 | are still possibly interleaved. |
| 266 | |
| 267 | |
| 268 | Mux-locked mux as parent of parent-locked mux |
| 269 | --------------------------------------------- |
| 270 | |
Mauro Carvalho Chehab | ccf988b | 2019-07-26 09:51:16 -0300 | [diff] [blame] | 271 | This is probably a bad topology:: |
Peter Rosin | 2254d24 | 2016-05-04 22:15:30 +0200 | [diff] [blame] | 272 | |
| 273 | .----------. .----------. .--------. |
| 274 | .--------. | mux- |-----| parent- |-----| dev D1 | |
| 275 | | root |--+--| locked | | locked | '--------' |
| 276 | '--------' | | mux M1 |--. | mux M2 |--. .--------. |
| 277 | | '----------' | '----------' '--| dev D2 | |
| 278 | | .--------. | .--------. '--------' |
| 279 | '--| dev D4 | '--| dev D3 | |
| 280 | '--------' '--------' |
| 281 | |
| 282 | When device D1 is accessed, accesses to D2 and D3 are locked out |
| 283 | for the full duration of the operation (M1 locks child muxes on the |
| 284 | root adapter). But accesses to D4 are possibly interleaved at any |
| 285 | point. |
| 286 | |
| 287 | This kind of topology is generally not suitable and should probably |
| 288 | be avoided. The reason is that M2 probably assumes that there will |
Luca Ceresoli | 2f07c05 | 2020-01-29 16:19:29 +0100 | [diff] [blame] | 289 | be no I2C transfers during its calls to ->select and ->deselect, and |
Peter Rosin | 2254d24 | 2016-05-04 22:15:30 +0200 | [diff] [blame] | 290 | if there are, any such transfers might appear on the slave side of M2 |
Luca Ceresoli | 2f07c05 | 2020-01-29 16:19:29 +0100 | [diff] [blame] | 291 | as partial I2C transfers, i.e. garbage or worse. This might cause |
Peter Rosin | 2254d24 | 2016-05-04 22:15:30 +0200 | [diff] [blame] | 292 | device lockups and/or other problems. |
| 293 | |
| 294 | The topology is especially troublesome if M2 is an auto-closing |
| 295 | mux. In that case, any interleaved accesses to D4 might close M2 |
Luca Ceresoli | 48ca3b7 | 2020-01-29 16:19:31 +0100 | [diff] [blame] | 296 | prematurely, as might any I2C transfers part of M1->select. |
Peter Rosin | 2254d24 | 2016-05-04 22:15:30 +0200 | [diff] [blame] | 297 | |
| 298 | But if M2 is not making the above stated assumption, and if M2 is not |
| 299 | auto-closing, the topology is fine. |
| 300 | |
| 301 | |
| 302 | Parent-locked mux as parent of mux-locked mux |
| 303 | --------------------------------------------- |
| 304 | |
Mauro Carvalho Chehab | ccf988b | 2019-07-26 09:51:16 -0300 | [diff] [blame] | 305 | This is a good topology:: |
Peter Rosin | 2254d24 | 2016-05-04 22:15:30 +0200 | [diff] [blame] | 306 | |
| 307 | .----------. .----------. .--------. |
| 308 | .--------. | parent- |-----| mux- |-----| dev D1 | |
| 309 | | root |--+--| locked | | locked | '--------' |
| 310 | '--------' | | mux M1 |--. | mux M2 |--. .--------. |
| 311 | | '----------' | '----------' '--| dev D2 | |
| 312 | | .--------. | .--------. '--------' |
| 313 | '--| dev D4 | '--| dev D3 | |
| 314 | '--------' '--------' |
| 315 | |
| 316 | When D1 is accessed, accesses to D2 are locked out for the full |
| 317 | duration of the operation (muxes on the top child adapter of M1 |
| 318 | are locked). Accesses to D3 and D4 are possibly interleaved at |
| 319 | any point, just as is expected for mux-locked muxes. |
| 320 | |
| 321 | When D3 or D4 are accessed, everything else is locked out. For D3 |
| 322 | accesses, M1 locks the root adapter. For D4 accesses, the root |
| 323 | adapter is locked directly. |
| 324 | |
| 325 | |
| 326 | Two mux-locked sibling muxes |
| 327 | ---------------------------- |
| 328 | |
Mauro Carvalho Chehab | ccf988b | 2019-07-26 09:51:16 -0300 | [diff] [blame] | 329 | This is a good topology:: |
Peter Rosin | 2254d24 | 2016-05-04 22:15:30 +0200 | [diff] [blame] | 330 | |
| 331 | .--------. |
| 332 | .----------. .--| dev D1 | |
| 333 | | mux- |--' '--------' |
| 334 | .--| locked | .--------. |
| 335 | | | mux M1 |-----| dev D2 | |
| 336 | | '----------' '--------' |
| 337 | | .----------. .--------. |
| 338 | .--------. | | mux- |-----| dev D3 | |
| 339 | | root |--+--| locked | '--------' |
| 340 | '--------' | | mux M2 |--. .--------. |
| 341 | | '----------' '--| dev D4 | |
| 342 | | .--------. '--------' |
| 343 | '--| dev D5 | |
| 344 | '--------' |
| 345 | |
| 346 | When D1 is accessed, accesses to D2, D3 and D4 are locked out. But |
| 347 | accesses to D5 may be interleaved at any time. |
| 348 | |
| 349 | |
| 350 | Two parent-locked sibling muxes |
| 351 | ------------------------------- |
| 352 | |
Mauro Carvalho Chehab | ccf988b | 2019-07-26 09:51:16 -0300 | [diff] [blame] | 353 | This is a good topology:: |
Peter Rosin | 2254d24 | 2016-05-04 22:15:30 +0200 | [diff] [blame] | 354 | |
Peter Rosin | f10a59e | 2016-11-10 15:03:21 +0100 | [diff] [blame] | 355 | .--------. |
Peter Rosin | 2254d24 | 2016-05-04 22:15:30 +0200 | [diff] [blame] | 356 | .----------. .--| dev D1 | |
| 357 | | parent- |--' '--------' |
| 358 | .--| locked | .--------. |
| 359 | | | mux M1 |-----| dev D2 | |
| 360 | | '----------' '--------' |
| 361 | | .----------. .--------. |
| 362 | .--------. | | parent- |-----| dev D3 | |
| 363 | | root |--+--| locked | '--------' |
| 364 | '--------' | | mux M2 |--. .--------. |
| 365 | | '----------' '--| dev D4 | |
| 366 | | .--------. '--------' |
| 367 | '--| dev D5 | |
| 368 | '--------' |
| 369 | |
| 370 | When any device is accessed, accesses to all other devices are locked |
| 371 | out. |
| 372 | |
| 373 | |
| 374 | Mux-locked and parent-locked sibling muxes |
| 375 | ------------------------------------------ |
| 376 | |
Mauro Carvalho Chehab | ccf988b | 2019-07-26 09:51:16 -0300 | [diff] [blame] | 377 | This is a good topology:: |
Peter Rosin | 2254d24 | 2016-05-04 22:15:30 +0200 | [diff] [blame] | 378 | |
Peter Rosin | f10a59e | 2016-11-10 15:03:21 +0100 | [diff] [blame] | 379 | .--------. |
Peter Rosin | 2254d24 | 2016-05-04 22:15:30 +0200 | [diff] [blame] | 380 | .----------. .--| dev D1 | |
| 381 | | mux- |--' '--------' |
| 382 | .--| locked | .--------. |
| 383 | | | mux M1 |-----| dev D2 | |
| 384 | | '----------' '--------' |
| 385 | | .----------. .--------. |
| 386 | .--------. | | parent- |-----| dev D3 | |
| 387 | | root |--+--| locked | '--------' |
| 388 | '--------' | | mux M2 |--. .--------. |
| 389 | | '----------' '--| dev D4 | |
| 390 | | .--------. '--------' |
| 391 | '--| dev D5 | |
| 392 | '--------' |
| 393 | |
| 394 | When D1 or D2 are accessed, accesses to D3 and D4 are locked out while |
| 395 | accesses to D5 may interleave. When D3 or D4 are accessed, accesses to |
| 396 | all other devices are locked out. |