1. 06 Apr, 2023 3 commits
    • Douglas Anderson's avatar
      drm/msm/dp: Return IRQ_NONE for unhandled interrupts · bfc12020
      Douglas Anderson authored
      If our interrupt handler gets called and we don't really handle the
      interrupt then we should return IRQ_NONE. The current interrupt
      handler didn't do this, so let's fix it.
      
      NOTE: for some of the cases it's clear that we should return IRQ_NONE
      and some cases it's clear that we should return IRQ_HANDLED. However,
      there are a few that fall somewhere in between. Specifically, the
      documentation for when to return IRQ_NONE vs. IRQ_HANDLED is probably
      best spelled out in the commit message of commit d9e4ad5b ("Document
      that IRQ_NONE should be returned when IRQ not actually handled"). That
      commit makes it clear that we should return IRQ_HANDLED if we've done
      something to make the interrupt stop happening.
      
      The case where it's unclear is, for instance, in dp_aux_isr() after
      we've read the interrupt using dp_catalog_aux_get_irq() and confirmed
      that "isr" is non-zero. The function dp_catalog_aux_get_irq() not only
      reads the interrupts but it also "ack"s all the interrupts that are
      returned. For an "unknown" interrupt this has a very good chance of
      actually stopping the interrupt from happening. That would mean we've
      identified that it's our device and done something to stop them from
      happening and should return IRQ_HANDLED. Specifically, it should be
      noted that most interrupts that need "ack"ing are ones that are
      one-time events and doing an "ack" is enough to clear them. However,
      since these interrupts are unknown then, by definition, it's unknown
      if "ack"ing them is truly enough to clear them. It's possible that we
      also need to remove the original source of the interrupt. In this
      case, IRQ_NONE would be a better choice.
      
      Given that returning an occasional IRQ_NONE isn't the absolute end of
      the world, however, let's choose that course of action. The IRQ
      framework will forgive a few IRQ_NONE returns now and again (and it
      won't even log them, which is why we have to log them ourselves). This
      means that if we _do_ end hitting an interrupt where "ack"ing isn't
      enough the kernel will eventually detect the problem and shut our
      device down.
      Signed-off-by: default avatarDouglas Anderson <dianders@chromium.org>
      Tested-by: default avatarKuogee Hsieh <quic_khsieh@quicinc.com>
      Reviewed-by: default avatarKuogee Hsieh <quic_khsieh@quicinc.com>
      Patchwork: https://patchwork.freedesktop.org/patch/520660/
      Link: https://lore.kernel.org/r/20230126170745.v2.2.I2d7aec2fadb9c237cd0090a47d6a8ba2054bf0f8@changeid
      [DB: reformatted commit message to make checkpatch happy]
      Signed-off-by: default avatarDmitry Baryshkov <dmitry.baryshkov@linaro.org>
      bfc12020
    • Douglas Anderson's avatar
      drm/msm/dp: Clean up handling of DP AUX interrupts · b20566cd
      Douglas Anderson authored
      The DP AUX interrupt handling was a bit of a mess.
      * There were two functions (one for "native" transfers and one for
        "i2c" transfers) that were quite similar. It was hard to say how
        many of the differences between the two functions were on purpose
        and how many of them were just an accident of how they were coded.
      * Each function sometimes used "else if" to test for error bits and
        sometimes didn't and again it was hard to say if this was on purpose
        or just an accident.
      * The two functions wouldn't notice whether "unknown" bits were
        set. For instance, there seems to be a bit "DP_INTR_PLL_UNLOCKED"
        and if it was set there would be no indication.
      * The two functions wouldn't notice if more than one error was set.
      
      Let's fix this by being more consistent / explicit about what we're
      doing.
      
      By design this could cause different handling for AUX transfers,
      though I'm not actually aware of any bug fixed as a result of
      this patch (this patch was created because we simply noticed how odd
      the old code was by code inspection). Specific notes here:
      1. In the old native transfer case if we got "done + wrong address"
         we'd ignore the "wrong address" (because of the "else if"). Now we
         won't.
      2. In the old native transfer case if we got "done + timeout" we'd
         ignore the "timeout" (because of the "else if"). Now we won't.
      3. In the old native transfer case we'd see "nack_defer" and translate
         it to the error number for "nack". This differed from the i2c
         transfer case where "nack_defer" was given the error number for
         "nack_defer". This 100% can't matter because the only user of this
         error number treats "nack defer" the same as "nack", so it's clear
         that the difference between the "native" and "i2c" was pointless
         here.
      4. In the old i2c transfer case if we got "done" plus any error
         besides "nack" or "defer" then we'd ignore the error. Now we don't.
      5. If there is more than one error signaled by the hardware it's
         possible that we'll report a different one than we used to. I don't
         know if this matters. If someone is aware of a case this matters we
         should document it and change the code to make it explicit.
      6. One quirk we keep (I don't know if this is important) is that in
         the i2c transfer case if we see "done + defer" we report that as a
         "nack". That seemed too intentional in the old code to just drop.
      
      After this change we will add extra logging, including:
      * A warning if we see more than one error bit set.
      * A warning if we see an unexpected interrupt.
      * A warning if we get an AUX transfer interrupt when shouldn't.
      
      It actually turns out that as a result of this change then at boot we
      sometimes see an error:
        [drm:dp_aux_isr] *ERROR* Unexpected DP AUX IRQ 0x01000000 when not busy
      That means that, during init, we are seeing DP_INTR_PLL_UNLOCKED. For
      now I'm going to say that leaving this error reported in the logs is
      OK-ish and hopefully it will encourage someone to track down what's
      going on at init time.
      
      One last note here is that this change renames one of the interrupt
      bits. The bit named "i2c done" clearly was used for native transfers
      being done too, so I renamed it to indicate this.
      Signed-off-by: default avatarDouglas Anderson <dianders@chromium.org>
      Tested-by: default avatarKuogee Hsieh <quic_khsieh@quicinc.com>
      Reviewed-by: default avatarKuogee Hsieh <quic_khsieh@quicinc.com>
      Patchwork: https://patchwork.freedesktop.org/patch/520658/
      Link: https://lore.kernel.org/r/20230126170745.v2.1.I90ffed3ddd21e818ae534f820cb4d6d8638859ab@changeidSigned-off-by: default avatarDmitry Baryshkov <dmitry.baryshkov@linaro.org>
      b20566cd
    • Jessica Zhang's avatar
  2. 03 Apr, 2023 2 commits
  3. 31 Mar, 2023 2 commits
  4. 30 Mar, 2023 1 commit
  5. 28 Mar, 2023 12 commits
  6. 25 Mar, 2023 17 commits
  7. 21 Mar, 2023 1 commit
  8. 20 Mar, 2023 2 commits