<feed xmlns='http://www.w3.org/2005/Atom'>
<title>kernel/drivers/net/ipa/ipa_clock.c, branch linux-6.9.y</title>
<subtitle>Hosts the 0x221E linux distro kernel.</subtitle>
<id>https://universe.0xinfinity.dev/distro/kernel/atom?h=linux-6.9.y</id>
<link rel='self' href='https://universe.0xinfinity.dev/distro/kernel/atom?h=linux-6.9.y'/>
<link rel='alternate' type='text/html' href='https://universe.0xinfinity.dev/distro/kernel/'/>
<updated>2021-08-22T08:44:17Z</updated>
<entry>
<title>net: ipa: rename "ipa_clock.c"</title>
<updated>2021-08-22T08:44:17Z</updated>
<author>
<name>Alex Elder</name>
<email>elder@linaro.org</email>
</author>
<published>2021-08-20T16:01:29Z</published>
<link rel='alternate' type='text/html' href='https://universe.0xinfinity.dev/distro/kernel/commit/?id=2775cbc5afeb63f1ddd8c05df216763450772ad9'/>
<id>urn:sha1:2775cbc5afeb63f1ddd8c05df216763450772ad9</id>
<content type='text'>
Finally, rename "ipa_clock.c" to be "ipa_power.c" and "ipa_clock.h"
to be "ipa_power.h".

Signed-off-by: Alex Elder &lt;elder@linaro.org&gt;
Signed-off-by: David S. Miller &lt;davem@davemloft.net&gt;
</content>
</entry>
<entry>
<title>net: ipa: rename ipa_clock_* symbols</title>
<updated>2021-08-22T08:44:17Z</updated>
<author>
<name>Alex Elder</name>
<email>elder@linaro.org</email>
</author>
<published>2021-08-20T16:01:28Z</published>
<link rel='alternate' type='text/html' href='https://universe.0xinfinity.dev/distro/kernel/commit/?id=7aa0e8b8bd5b252c94900b19f2af8b7ec8a4e11d'/>
<id>urn:sha1:7aa0e8b8bd5b252c94900b19f2af8b7ec8a4e11d</id>
<content type='text'>
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() -&gt; ipa_power_enable()
  ipa_clock_disable() -&gt; ipa_power_disable()
  ipa_clock_rate() -&gt; ipa_core_clock_rate()
  ipa_clock_init() -&gt; ipa_power_init()
  ipa_clock_exit() -&gt; 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: Alex Elder &lt;elder@linaro.org&gt;
Signed-off-by: David S. Miller &lt;davem@davemloft.net&gt;
</content>
</entry>
<entry>
<title>net: ipa: use autosuspend</title>
<updated>2021-08-22T08:44:17Z</updated>
<author>
<name>Alex Elder</name>
<email>elder@linaro.org</email>
</author>
<published>2021-08-20T16:01:27Z</published>
<link rel='alternate' type='text/html' href='https://universe.0xinfinity.dev/distro/kernel/commit/?id=1aac309d32075e73d1f93208b38cd2d5f03e0a5c'/>
<id>urn:sha1:1aac309d32075e73d1f93208b38cd2d5f03e0a5c</id>
<content type='text'>
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 -&gt;runtime_suspend
callback will occur if idle.

Signed-off-by: Alex Elder &lt;elder@linaro.org&gt;
Signed-off-by: David S. Miller &lt;davem@davemloft.net&gt;
</content>
</entry>
<entry>
<title>net: ipa: kill ipa_clock_get()</title>
<updated>2021-08-20T13:45:47Z</updated>
<author>
<name>Alex Elder</name>
<email>elder@linaro.org</email>
</author>
<published>2021-08-19T22:19:27Z</published>
<link rel='alternate' type='text/html' href='https://universe.0xinfinity.dev/distro/kernel/commit/?id=c3f115aa5e1b6459e2ccd711277435397dd7c6e9'/>
<id>urn:sha1:c3f115aa5e1b6459e2ccd711277435397dd7c6e9</id>
<content type='text'>
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: Alex Elder &lt;elder@linaro.org&gt;
Signed-off-by: David S. Miller &lt;davem@davemloft.net&gt;
</content>
</entry>
<entry>
<title>net: ipa: fix TX queue race</title>
<updated>2021-08-20T13:43:39Z</updated>
<author>
<name>Alex Elder</name>
<email>elder@linaro.org</email>
</author>
<published>2021-08-19T21:12:28Z</published>
<link rel='alternate' type='text/html' href='https://universe.0xinfinity.dev/distro/kernel/commit/?id=b8e36e13ea5e464414b3e6465045cf0689500448'/>
<id>urn:sha1:b8e36e13ea5e464414b3e6465045cf0689500448</id>
<content type='text'>
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       &lt;-- 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:                     &gt; 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  &lt;-- 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: 6b51f802d652b ("net: ipa: ensure hardware has power in ipa_start_xmit()")
Signed-off-by: Alex Elder &lt;elder@linaro.org&gt;
Signed-off-by: David S. Miller &lt;davem@davemloft.net&gt;
</content>
</entry>
<entry>
<title>net: ipa: distinguish system from runtime suspend</title>
<updated>2021-08-14T13:13:38Z</updated>
<author>
<name>Alex Elder</name>
<email>elder@linaro.org</email>
</author>
<published>2021-08-12T19:50:31Z</published>
<link rel='alternate' type='text/html' href='https://universe.0xinfinity.dev/distro/kernel/commit/?id=b9c532c11cab21d23a67c2d80a02a444c9e07ac6'/>
<id>urn:sha1:b9c532c11cab21d23a67c2d80a02a444c9e07ac6</id>
<content type='text'>
Add a new flag that is set when the hardware is suspended due to a
system suspend operation, distingishing it from runtime suspend.
Use it in the SUSPEND IPA interrupt handler to determine whether to
trigger a system resume because of the event.  Define new suspend
and resume power management callback functions to set and clear the
new flag, respectively.

Signed-off-by: Alex Elder &lt;elder@linaro.org&gt;
Signed-off-by: David S. Miller &lt;davem@davemloft.net&gt;
</content>
</entry>
<entry>
<title>net: ipa: enable wakeup in ipa_power_setup()</title>
<updated>2021-08-14T13:13:38Z</updated>
<author>
<name>Alex Elder</name>
<email>elder@linaro.org</email>
</author>
<published>2021-08-12T19:50:30Z</published>
<link rel='alternate' type='text/html' href='https://universe.0xinfinity.dev/distro/kernel/commit/?id=d430fe4bac024812f50b8a2ad7a3639128c9db06'/>
<id>urn:sha1:d430fe4bac024812f50b8a2ad7a3639128c9db06</id>
<content type='text'>
Move the call to enable the IPA interrupt as a wakeup interrupt into
ipa_power_setup(), disable it in ipa_power_teardown().

Signed-off-by: Alex Elder &lt;elder@linaro.org&gt;
Signed-off-by: David S. Miller &lt;davem@davemloft.net&gt;
</content>
</entry>
<entry>
<title>net: ipa: kill ipa_clock_get_additional()</title>
<updated>2021-08-11T12:31:56Z</updated>
<author>
<name>Alex Elder</name>
<email>elder@linaro.org</email>
</author>
<published>2021-08-10T19:27:04Z</published>
<link rel='alternate' type='text/html' href='https://universe.0xinfinity.dev/distro/kernel/commit/?id=0d08026ac6099ef8bd73412005830ce7280b7c80'/>
<id>urn:sha1:0d08026ac6099ef8bd73412005830ce7280b7c80</id>
<content type='text'>
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: Alex Elder &lt;elder@linaro.org&gt;
Signed-off-by: David S. Miller &lt;davem@davemloft.net&gt;
</content>
</entry>
<entry>
<title>net: ipa: kill IPA clock reference count</title>
<updated>2021-08-11T12:31:56Z</updated>
<author>
<name>Alex Elder</name>
<email>elder@linaro.org</email>
</author>
<published>2021-08-10T19:27:03Z</published>
<link rel='alternate' type='text/html' href='https://universe.0xinfinity.dev/distro/kernel/commit/?id=a71aeff3dd0a7d127967d42a86b42b0aa21a90dc'/>
<id>urn:sha1:a71aeff3dd0a7d127967d42a86b42b0aa21a90dc</id>
<content type='text'>
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: Alex Elder &lt;elder@linaro.org&gt;
Signed-off-by: David S. Miller &lt;davem@davemloft.net&gt;
</content>
</entry>
<entry>
<title>net: ipa: use runtime PM core</title>
<updated>2021-08-11T12:31:56Z</updated>
<author>
<name>Alex Elder</name>
<email>elder@linaro.org</email>
</author>
<published>2021-08-10T19:27:01Z</published>
<link rel='alternate' type='text/html' href='https://universe.0xinfinity.dev/distro/kernel/commit/?id=63de79f031dedeb64fb1a5fc7f07f5f51fcbf7a0'/>
<id>urn:sha1:63de79f031dedeb64fb1a5fc7f07f5f51fcbf7a0</id>
<content type='text'>
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 -&gt;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 -&gt;runtime_resume power
operation, and pm_runtime_put() when the last IPA clock reference
is dropped.

Introduce ipa_runtime_idle() as the -&gt;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: Alex Elder &lt;elder@linaro.org&gt;
Signed-off-by: David S. Miller &lt;davem@davemloft.net&gt;
</content>
</entry>
</feed>
