Commit Graph

13 Commits

Author SHA1 Message Date
Alex Elder
1aac309d32 net: ipa: use autosuspend
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: Alex Elder <elder@linaro.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2021-08-22 09:44:17 +01:00
Alex Elder
c3f115aa5e net: ipa: kill ipa_clock_get()
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 <elder@linaro.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2021-08-20 14:45:47 +01:00
Alex Elder
7ebd168c3b net: ipa: have ipa_clock_get() return a value
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: Alex Elder <elder@linaro.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2021-08-11 13:31:55 +01:00
Alex Elder
176086d870 net: ipa: kill ipa_interrupt_process_all()
Now that ipa_isr_thread() is a simple wrapper that gets a clock
reference around ipa_interrupt_process_all(), get rid of the
called function and just open-code it in ipa_isr_thread().

Signed-off-by: Alex Elder <elder@linaro.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2021-07-27 21:02:06 +01:00
Alex Elder
fe6a327979 net: ipa: get rid of some unneeded IPA interrupt code
The pending IPA interrupts are checked by ipa_isr_thread(), and
interrupts are processed only if an enabled interrupt has a
condition pending.  But ipa_interrupt_process_all() now makes the
same check, so the one in ipa_isr_thread() can just be skipped.

Also in ipa_isr_thread(), any interrupt conditions pending which are
not enabled are cleared.  Here too, ipa_interrupt_process_all() now
clears such excess interrupt conditions, so ipa_isr_thread() doesn't
have to.

Signed-off-by: Alex Elder <elder@linaro.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2021-07-27 21:02:06 +01:00
Alex Elder
e70e410f8e net: ipa: clear disabled IPA interrupt conditions
We ignore any IPA interrupt that has no handler.  If any interrupt
conditions without a handler exist when an IPA interrupt occurs,
clear those conditions.  Add a debug message to report which ones
are being cleared.

Signed-off-by: Alex Elder <elder@linaro.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2021-07-27 21:02:06 +01:00
Alex Elder
937a0da432 net: ipa: make IPA interrupt handler threaded only
When the IPA interrupt handler runs, the IPA core clock must already
be operational, and the interconnect providing access by the AP to
IPA config space must be enabled too.

Currently we ensure this by taking a top-level "stay awake" IPA
clock reference, but that will soon go away.  In preparation for
that, move all handling for the IPA IRQ into the thread function.

Signed-off-by: Alex Elder <elder@linaro.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2021-07-27 21:02:06 +01:00
Alex Elder
1118a14710 net: ipa: set up IPA interrupts earlier
Initialization of the IPA driver has several phases:
   - "init" phase can be done without any access to IPA hardware
   - "config" phase requires the IPA hardware to be clocked
   - "setup" phase requires the GSI layer to be functional

Currently, initialization for the IPA interrupt handling code occurs
in the setup phase.  It requires access to the IPA hardware but does
not need GSI, so it can be moved to the config phase instead.

Call the interrupt configuration function early in ipa_config()
rather than from ipa_setup().  Rename ipa_interrupt_setup() to be
ipa_interrupt_config(), and ipa_interrupt_teardown() to be
ipa_interupt_deconfig(), so their names properly indicate when
they get called.

Signed-off-by: Alex Elder <elder@linaro.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2021-07-26 23:09:18 +01:00
Alex Elder
5bc5588466 net: ipa: use WARN_ON() rather than assertions
I've added commented assertions to record certain properties that
can be assumed to hold in certain places in the IPA code.  Convert
these into real WARN_ON() calls so the assertions are actually
checked, using the standard WARN_ON() mechanism.

Where errors can be returned, return an error if a warning is
triggered.

Signed-off-by: Alex Elder <elder@linaro.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2021-07-26 22:38:11 +01:00
Alex Elder
e666aa978a net: ipa: support IPA interrupt addresses for IPA v4.7
Starting with IPA v4.7, registers related to IPA interrupts are
located at a fixed offset 0x1000 above than the addresses used for
earlier versions.  Define and use functions to provide the offset to
use for these registers based on IPA version.

Signed-off-by: Alex Elder <elder@linaro.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2021-03-25 17:22:30 -07:00
Alex Elder
f3ae1616c5 net: ipa: fix two inconsistent IPA register names
Rename two suspend IRQ registers so they follow the IPA_REG_IRQ_xxx
naming convention used elsewhere.

Signed-off-by: Alex Elder <elder@linaro.org>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2020-11-18 15:53:48 -08:00
Alex Elder
d1b5126af0 net: ipa: enable wakeup on IPA interrupt
Now that we handle wakeup interrupts properly, arrange for the IPA
interrupt to be treated as a wakeup interrupt.

Signed-off-by: Alex Elder <elder@linaro.org>
Reviewed-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-18 17:47:07 -07:00
Alex Elder
ba764c4dad soc: qcom: ipa: clocking, interrupts, and memory
This patch incorporates three source files (and their headers).  They're
grouped into one patch mainly for the purpose of making the number and
size of patches in this series somewhat reasonable.

  - "ipa_clock.c" and "ipa_clock.h" implement clocking for the IPA device.
    The IPA has a single core clock managed by the common clock framework.
    In addition, the IPA has three buses whose bandwidth is managed by the
    Linux interconnect framework.  At this time the core clock and all
    three buses are either on or off; we don't yet do any more fine-grained
    management than that.  The core clock and interconnects are enabled
    and disabled as a unit, using a unified clock-like abstraction,
    ipa_clock_get()/ipa_clock_put().

  - "ipa_interrupt.c" and "ipa_interrupt.h" implement IPA interrupts.
    There are two hardware IRQs used by the IPA driver (the other is
    the GSI interrupt, described in a separate patch).  Several types
    of interrupt are handled by the IPA IRQ handler; these are not part
    of data/fast path.

  - The IPA has a region of local memory that is accessible by the AP
    (and modem).  Within that region are areas with certain defined
    purposes.  "ipa_mem.c" and "ipa_mem.h" define those regions, and
    implement their initialization.

Signed-off-by: Alex Elder <elder@linaro.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-03-08 22:07:09 -07:00