1. 12 Mar, 2022 1 commit
  2. 11 Mar, 2022 7 commits
  3. 03 Feb, 2022 1 commit
    • Alex Elder's avatar
      net: ipa: request IPA register values be retained · 34a08176
      Alex Elder authored
      In some cases, the IPA hardware needs to request the always-on
      subsystem (AOSS) to coordinate with the IPA microcontroller to
      retain IPA register values at power collapse.  This is done by
      issuing a QMP request to the AOSS microcontroller.  A similar
      request ondoes that request.
      
      We must get and hold the "QMP" handle early, because we might get
      back EPROBE_DEFER for that.  But the actual request should be sent
      while we know the IPA clock is active, and when we know the
      microcontroller is operational.
      
      Fixes: 1aac309d
      
       ("net: ipa: use autosuspend")
      Signed-off-by: default avatarAlex Elder <elder@linaro.org>
      Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
      34a08176
  4. 22 Aug, 2021 3 commits
    • Alex Elder's avatar
      net: ipa: rename "ipa_clock.c" · 2775cbc5
      Alex Elder authored
      
      Finally, rename "ipa_clock.c" to be "ipa_power.c" and "ipa_clock.h"
      to be "ipa_power.h".
      Signed-off-by: default avatarAlex Elder <elder@linaro.org>
      Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
      2775cbc5
    • Alex Elder's avatar
      net: ipa: rename ipa_clock_* symbols · 7aa0e8b8
      Alex Elder authored
      
      Rename a number of functions to clarify that there is no longer a
      notion of an "IPA clock," but rather that the functions are more
      generally related to IPA power management.
      
        ipa_clock_enable() -> ipa_power_enable()
        ipa_clock_disable() -> ipa_power_disable()
        ipa_clock_rate() -> ipa_core_clock_rate()
        ipa_clock_init() -> ipa_power_init()
        ipa_clock_exit() -> ipa_power_exit()
      
      Rename the ipa_clock structure to be ipa_power.  Rename all
      variables and fields using that structure type "power" rather
      than "clock".
      
      Rename the ipa_clock_data structure to be ipa_power_data, and more
      broadly, just substitute "power" for "clock" in places that
      previously represented things related to the "IPA clock".
      
      Update comments throughout.
      Signed-off-by: default avatarAlex Elder <elder@linaro.org>
      Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
      7aa0e8b8
    • Alex Elder's avatar
      net: ipa: use autosuspend · 1aac309d
      Alex Elder authored
      
      Use runtime power management autosuspend.
      
      Up until this point, we only suspended the IPA hardware for system
      suspend; now we'll suspend it aggressively using runtime power
      management, setting the initial autosuspend delay to half a second
      of inactivity.
      
      Replace pm_runtime_put() calls with pm_runtime_put_autosuspend(),
      call pm_runtime_mark_last_busy() before each of those.  In places
      where we're shutting things down, or decrementing power references
      for errors, use pm_runtime_put_noidle() instead.
      
      Finally, remove ipa_runtime_idle(), so the ->runtime_suspend
      callback will occur if idle.
      Signed-off-by: default avatarAlex Elder <elder@linaro.org>
      Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
      1aac309d
  5. 20 Aug, 2021 2 commits
    • Alex Elder's avatar
      net: ipa: kill ipa_clock_get() · c3f115aa
      Alex Elder authored
      
      The only remaining user of the ipa_clock_{get,put}() interface is
      ipa_isr_thread().  Replace calls to ipa_clock_get() there calling
      pm_runtime_get_sync() instead.  And call pm_runtime_put() there
      rather than ipa_clock_put().  Warn if we ever get an error.
      
      With that, we can get rid of ipa_clock_get() and ipa_clock_put().
      Signed-off-by: default avatarAlex Elder <elder@linaro.org>
      Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
      c3f115aa
    • Alex Elder's avatar
      net: ipa: fix TX queue race · b8e36e13
      Alex Elder authored
      Jakub Kicinski pointed out a race condition in ipa_start_xmit() in a
      recently-accepted series of patches:
        https://lore.kernel.org/netdev/20210812195035.2816276-1-elder@linaro.org/
      We are stopping the modem TX queue in that function if the power
      state is not active.  We restart the TX queue again once hardware
      resume is complete.
      
        TX path                       Power Management
        -------                       ----------------
        pm_runtime_get(); no power    Start resume
        Stop TX queue                      ...
        pm_runtime_put()              Resume complete
        return NETDEV_TX_BUSY         Start TX queue
      
        pm_runtime_get()
        Power present, transmit
        pm_runtime_put()              (auto-suspend)
      
      The issue is that the power management (resume) activity and the
      network transmit activity can occur concurrently, and there's a
      chance the queue will be stopped *after* it has been started again.
      
        TX path                       Power Management
        -------                       ----------------
                                      Resume underway
        pm_runtime_get(); no power         ...
                                      Resume complete
                                      Start TX queue
        Stop TX queue       <-- No more transmits after this
        pm_runtime_put()
        return NETDEV_TX_BUSY
      
      We address this using a STARTED flag to indicate when the TX queue
      has been started from the resume path, and a spinlock to make the
      flag and queue updates happen atomically.
      
        TX path                       Power Management
        -------                       ----------------
                                      Resume underway
        pm_runtime_get(); no power    Resume complete
                                      start TX queue     \
        If STARTED flag is *not* set:                     > atomic
            Stop TX queue             set STARTED flag   /
        pm_runtime_put()
        return NETDEV_TX_BUSY
      
      A second flag is used to address a different race that involves
      another path requesting power.
      
        TX path            Other path              Power Management
        -------            ----------              ----------------
                           pm_runtime_get_sync()   Resume
                                                   Start TX queue   \ atomic
                                                   Set STARTED flag /
                           (do its thing)
                           pm_runtime_put()
                                                   (auto-suspend)
        pm_runtime_get()                           Mark delayed resume
        STARTED *is* set, so
          do *not* stop TX queue  <-- Queue should be stopped here
        pm_runtime_put()
        return NETDEV_TX_BUSY                      Suspend done, resume
                                                   Resume complete
        pm_runtime_get()
        Stop TX queue
          (STARTED is *not* set)                   Start TX queue   \ atomic
        pm_runtime_put()                           Set STARTED flag /
        return NETDEV_TX_BUSY
      
      So a STOPPED flag is set in the transmit path when it has stopped
      the TX queue, and this pair of operations is also protected by the
      spinlock.  The resume path only restarts the TX queue if the STOPPED
      flag is set.  This case isn't a major problem, but it avoids the
      "non-trivial amount of useless work" done by the networking stack
      when NETDEV_TX_BUSY is returned.
      
      Fixes: 6b51f802
      
       ("net: ipa: ensure hardware has power in ipa_start_xmit()")
      Signed-off-by: default avatarAlex Elder <elder@linaro.org>
      Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
      b8e36e13
  6. 14 Aug, 2021 2 commits
  7. 11 Aug, 2021 6 commits
    • Alex Elder's avatar
      net: ipa: kill ipa_clock_get_additional() · 0d08026a
      Alex Elder authored
      
      Now that ipa_clock_get_additional() is a trivial wrapper around
      pm_runtime_get_if_active(), just open-code it in its only caller
      and delete the function.
      Signed-off-by: default avatarAlex Elder <elder@linaro.org>
      Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
      0d08026a
    • Alex Elder's avatar
      net: ipa: kill IPA clock reference count · a71aeff3
      Alex Elder authored
      
      The runtime power management core code maintains a usage count.  This
      count mirrors the IPA clock reference count, and there's no need to
      maintain both.  So get rid of the IPA clock reference count and just
      rely on the runtime PM usage count to determine when the hardware
      should be suspended or resumed.
      
      Use pm_runtime_get_if_active() in ipa_clock_get_additional().  We
      care whether power is active, regardless of whether it's in use, so
      pass true for its ign_usage_count argument.
      
      The IPA clock mutex is just used to make enabling/disabling the
      clock and updating the reference count occur atomically.  Without
      the reference count, there's no need for the mutex, so get rid of
      that too.
      Signed-off-by: default avatarAlex Elder <elder@linaro.org>
      Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
      a71aeff3
    • Alex Elder's avatar
      net: ipa: use runtime PM core · 63de79f0
      Alex Elder authored
      
      Use the runtime power management core to cause hardware suspend and
      resume to occur.  Enable it in ipa_clock_init() (without autosuspend),
      and disable it in ipa_clock_exit().
      
      Use ipa_runtime_suspend() as the ->runtime_suspend power operation,
      and arrange for it to be called by having ipa_clock_get() call
      pm_runtime_get_sync() when the first clock reference is taken.
      Similarly, use ipa_runtime_resume() as the ->runtime_resume power
      operation, and pm_runtime_put() when the last IPA clock reference
      is dropped.
      
      Introduce ipa_runtime_idle() as the ->runtime_idle power operation,
      and have it return a non-zero value; this way suspend will never
      occur except when forced.
      
      Use pm_runtime_force_suspend() and pm_runtime_force_resume() as the
      system suspend and resume callbacks, and remove ipa_suspend() and
      ipa_resume().
      
      Store a pointer to the device structure passed to ipa_clock_init(),
      so it can be used by ipa_clock_exit() to disable runtime power
      management.
      
      For now we preserve IPA clock reference counting.
      Signed-off-by: default avatarAlex Elder <elder@linaro.org>
      Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
      63de79f0
    • Alex Elder's avatar
      net: ipa: resume in ipa_clock_get() · 2abb0c7f
      Alex Elder authored
      
      Introduce ipa_runtime_suspend() and ipa_runtime_resume(), which
      encapsulate the activities necessary for suspending and resuming
      the IPA hardware.  Call these functions from ipa_clock_get() and
      ipa_clock_put() when the first reference is taken or last one is
      dropped.
      
      When the very first clock reference is taken (for ipa_config()),
      setup isn't complete yet, so (as before) only the core clock gets
      enabled.
      
      When the last clock reference is dropped (after ipa_deconfig()),
      ipa_teardown() will have made the setup_complete flag false, so
      there too, the core clock will be stopped without affecting GSI
      or the endpoints.
      
      Otherwise these new functions will perform the desired suspend and
      resume actions once setup is complete.
      Signed-off-by: default avatarAlex Elder <elder@linaro.org>
      Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
      2abb0c7f
    • Alex Elder's avatar
      net: ipa: disable clock in suspend · 1016c6b8
      Alex Elder authored
      
      Disable the IPA clock rather than dropping a reference to it in the
      system suspend callback.  This forces the suspend to occur without
      affecting existing references.
      
      Similarly, enable the clock rather than taking a reference in
      ipa_resume(), forcing a resume without changing the reference count.
      Signed-off-by: default avatarAlex Elder <elder@linaro.org>
      Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
      1016c6b8
    • Alex Elder's avatar
      net: ipa: have ipa_clock_get() return a value · 7ebd168c
      Alex Elder authored
      
      We currently assume no errors occur when enabling or disabling the
      IPA core clock and interconnects.  And although this commit exposes
      errors that could occur, we generally assume this won't happen in
      practice.
      
      This commit changes ipa_clock_get() and ipa_clock_put() so each
      returns a value.  The values returned are meant to mimic what the
      runtime power management functions return, so we can set up error
      handling here before we make the switch.  Have ipa_clock_get()
      increment the reference count even if it returns an error, to match
      the behavior of pm_runtime_get().
      
      More details follow.
      
      When taking a reference in ipa_clock_get(), return 0 for the first
      reference, 1 for subsequent references, or a negative error code if
      an error occurs.  Note that if ipa_clock_get() returns an error, we
      must not touch hardware; in some cases such errors now cause entire
      blocks of code to be skipped.
      
      When dropping a reference in ipa_clock_put(), we return 0 or an
      error code.  The error would come from ipa_clock_disable(), which
      now returns what ipa_interconnect_disable() returns (either 0 or a
      negative error code).  For now, callers ignore the return value;
      if an error occurs, a message will have already been logged, and
      little more can actually be done to improve the situation.
      Signed-off-by: default avatarAlex Elder <elder@linaro.org>
      Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
      7ebd168c
  8. 05 Aug, 2021 4 commits
    • Alex Elder's avatar
      net: ipa: move IPA flags field · afb08b7e
      Alex Elder authored
      
      The ipa->flags field is only ever used in "ipa_clock.c", related to
      suspend/resume activity.
      
      Move the definition of the ipa_flag enumerated type to "ipa_clock.c".
      And move the flags field from the ipa structure and to the ipa_clock
      structure.  Rename the type and its values to include "power" or
      "POWER" in the name.
      Signed-off-by: default avatarAlex Elder <elder@linaro.org>
      Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
      afb08b7e
    • Alex Elder's avatar
      net: ipa: move ipa_suspend_handler() · afe1baa8
      Alex Elder authored
      
      Move ipa_suspend_handler() into "ipa_clock.c" from "ipa_main.c", to
      group with the reset of the suspend/resume code.  This IPA interrupt
      is triggered if an IPA RX endpoint is suspended but has a packet to
      be delivered.
      
      Introduce ipa_power_setup() and ipa_power_teardown() to add and
      remove the handler for the IPA SUSPEND interrupt at the same place
      as before, while allowing the handler to remain private.
      
      The "power" naming convention will be adopted elsewhere in this
      file as well (soon).
      Signed-off-by: default avatarAlex Elder <elder@linaro.org>
      Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
      afe1baa8
    • Alex Elder's avatar
      net: ipa: move IPA power operations to ipa_clock.c · 73ff316d
      Alex Elder authored
      
      Move ipa_suspend() and ipa_resume(), as well as the definition of
      the ipa_pm_ops structure into "ipa_clock.c".  Make ipa_pm_ops public
      and declare it as extern in "ipa_clock.h".
      
      This is part of centralizing IPA power management functionality into
      "ipa_clock.c" (the file will eventually get a name change).
      Signed-off-by: default avatarAlex Elder <elder@linaro.org>
      Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
      73ff316d
    • Alex Elder's avatar
      net: ipa: improve IPA clock error messages · 8ee7c40a
      Alex Elder authored
      
      Rearrange messages reported when errors occur in the IPA clock code,
      so that the specific interconnect is identified when an error occurs
      enabling or disabling it, or the core clock is indicated when an
      error occurs enabling it.
      
      Have ipa_interconnect_disable() return zero or the negative error
      value returned by the first interconnect that produced an error
      when disabled.  For now, the callers ignore the returned value.
      Signed-off-by: default avatarAlex Elder <elder@linaro.org>
      Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
      8ee7c40a
  9. 13 Feb, 2021 1 commit
  10. 18 Jan, 2021 7 commits
  11. 23 Dec, 2020 1 commit
  12. 21 Nov, 2020 2 commits
  13. 19 Sep, 2020 2 commits
  14. 14 Jul, 2020 1 commit
    • Alex Elder's avatar
      net: ipa: fix kerneldoc comments · e3eea08e
      Alex Elder authored
      
      This commit affects comments (and in one case, whitespace) only.
      
      Throughout the IPA code, return statements are documented using
      "@Return:", whereas they should use "Return:" instead.  Fix these
      mistakes.
      
      In function definitions, some parameters are missing their comment
      to describe them.  And in structure definitions, some fields are
      missing their comment to describe them.  Add these missing
      descriptions.
      
      Some arguments changed name and type along the way, but their
      descriptions were not updated (an endpoint pointer is now used in
      many places that previously used an endpoint ID).  Fix these
      incorrect parameter descriptions.
      
      In the description for the ipa_clock structure, one field had a
      semicolon instead of a colon in its description.  Fix this.
      
      Add a missing function description for ipa_gsi_endpoint_data_empty().
      
      All of these issues were identified when building with "W=1".
      Signed-off-by: default avatarAlex Elder <elder@linaro.org>
      Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
      e3eea08e