Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

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