Commit 3c6ccdde authored by Alex Elder's avatar Alex Elder Committed by David S. Miller

net: ipa: repurpose CLOCK_HELD flag

The previous patch causes a system resume to be triggered when a
packet is available for receipt on a suspended RX endpoint.

The CLOCK_HELD flag was previously used to indicate that an extra
clock reference was held, preventing suspend.  But we no longer need
such a flag:
  - We take an initial reference in ipa_config().
  - That reference is held until ipa_suspend() releases it.
  - A subsequent system resume leads to a reference getting
    re-acquired in ipa_resume().
  - This can repeat until ultimately the module is removed, where
    ipa_remove() releases the reference.
We no longer need a special flag to determine whether this extra
reference is held--it is, provided probe has completed successfully
and the driver is not suspended (or removed).

On the other hand, once suspended, it's possible for more than one
endpoint to trip the IPA SUSPEND interrupt, and we only want to
trigger the system resume once.  So repurpose the Boolean CLOCK_HELD
flag to record whether the IPA SUSPEND handler should initiate a
system resume.

The flag will be be cleared each time ipa_suspend() is called,
*before* any endpoints are suspended.  And it will be set inside the
IPA SUSPEND interrupt handler exactly once per suspend.

Rename the flag IPA_FLAG_RESUMED to reflect its new purpose.
Signed-off-by: default avatarAlex Elder <elder@linaro.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 8529b4b0
...@@ -29,11 +29,11 @@ struct ipa_interrupt; ...@@ -29,11 +29,11 @@ struct ipa_interrupt;
/** /**
* enum ipa_flag - IPA state flags * enum ipa_flag - IPA state flags
* @IPA_FLAG_CLOCK_HELD: Whether IPA clock is held to prevent suspend * @IPA_FLAG_RESUMED: Whether resume from suspend has been signaled
* @IPA_FLAG_COUNT: Number of defined IPA flags * @IPA_FLAG_COUNT: Number of defined IPA flags
*/ */
enum ipa_flag { enum ipa_flag {
IPA_FLAG_CLOCK_HELD, IPA_FLAG_RESUMED,
IPA_FLAG_COUNT, /* Last; not a flag */ IPA_FLAG_COUNT, /* Last; not a flag */
}; };
......
...@@ -86,7 +86,7 @@ static void ipa_suspend_handler(struct ipa *ipa, enum ipa_irq_id irq_id) ...@@ -86,7 +86,7 @@ static void ipa_suspend_handler(struct ipa *ipa, enum ipa_irq_id irq_id)
* More than one endpoint could signal this; if so, ignore * More than one endpoint could signal this; if so, ignore
* all but the first. * all but the first.
*/ */
if (!test_and_set_bit(IPA_FLAG_CLOCK_HELD, ipa->flags)) if (!test_and_set_bit(IPA_FLAG_RESUMED, ipa->flags))
pm_wakeup_dev_event(&ipa->pdev->dev, 0, true); pm_wakeup_dev_event(&ipa->pdev->dev, 0, true);
/* Acknowledge/clear the suspend interrupt on all endpoints */ /* Acknowledge/clear the suspend interrupt on all endpoints */
...@@ -518,7 +518,6 @@ static int ipa_config(struct ipa *ipa, const struct ipa_data *data) ...@@ -518,7 +518,6 @@ static int ipa_config(struct ipa *ipa, const struct ipa_data *data)
* is held after initialization completes, and won't get dropped * is held after initialization completes, and won't get dropped
* unless/until a system suspend request arrives. * unless/until a system suspend request arrives.
*/ */
__set_bit(IPA_FLAG_CLOCK_HELD, ipa->flags);
ipa_clock_get(ipa); ipa_clock_get(ipa);
ipa_hardware_config(ipa); ipa_hardware_config(ipa);
...@@ -554,7 +553,6 @@ static int ipa_config(struct ipa *ipa, const struct ipa_data *data) ...@@ -554,7 +553,6 @@ static int ipa_config(struct ipa *ipa, const struct ipa_data *data)
err_hardware_deconfig: err_hardware_deconfig:
ipa_hardware_deconfig(ipa); ipa_hardware_deconfig(ipa);
ipa_clock_put(ipa); ipa_clock_put(ipa);
__clear_bit(IPA_FLAG_CLOCK_HELD, ipa->flags);
return ret; return ret;
} }
...@@ -572,7 +570,6 @@ static void ipa_deconfig(struct ipa *ipa) ...@@ -572,7 +570,6 @@ static void ipa_deconfig(struct ipa *ipa)
ipa_endpoint_deconfig(ipa); ipa_endpoint_deconfig(ipa);
ipa_hardware_deconfig(ipa); ipa_hardware_deconfig(ipa);
ipa_clock_put(ipa); ipa_clock_put(ipa);
__clear_bit(IPA_FLAG_CLOCK_HELD, ipa->flags);
} }
static int ipa_firmware_load(struct device *dev) static int ipa_firmware_load(struct device *dev)
...@@ -778,7 +775,6 @@ static int ipa_probe(struct platform_device *pdev) ...@@ -778,7 +775,6 @@ static int ipa_probe(struct platform_device *pdev)
dev_set_drvdata(dev, ipa); dev_set_drvdata(dev, ipa);
ipa->modem_rproc = rproc; ipa->modem_rproc = rproc;
ipa->clock = clock; ipa->clock = clock;
__clear_bit(IPA_FLAG_CLOCK_HELD, ipa->flags);
ipa->version = data->version; ipa->version = data->version;
ret = ipa_reg_init(ipa); ret = ipa_reg_init(ipa);
...@@ -908,10 +904,15 @@ static int ipa_suspend(struct device *dev) ...@@ -908,10 +904,15 @@ static int ipa_suspend(struct device *dev)
{ {
struct ipa *ipa = dev_get_drvdata(dev); struct ipa *ipa = dev_get_drvdata(dev);
/* When a suspended RX endpoint has a packet ready to receive, we
* get an IPA SUSPEND interrupt. We trigger a system resume in
* that case, but only on the first such interrupt since suspend.
*/
__clear_bit(IPA_FLAG_RESUMED, ipa->flags);
ipa_endpoint_suspend(ipa); ipa_endpoint_suspend(ipa);
ipa_clock_put(ipa); ipa_clock_put(ipa);
__clear_bit(IPA_FLAG_CLOCK_HELD, ipa->flags);
return 0; return 0;
} }
...@@ -933,7 +934,6 @@ static int ipa_resume(struct device *dev) ...@@ -933,7 +934,6 @@ static int ipa_resume(struct device *dev)
/* This clock reference will keep the IPA out of suspend /* This clock reference will keep the IPA out of suspend
* until we get a power management suspend request. * until we get a power management suspend request.
*/ */
__set_bit(IPA_FLAG_CLOCK_HELD, ipa->flags);
ipa_clock_get(ipa); ipa_clock_get(ipa);
ipa_endpoint_resume(ipa); ipa_endpoint_resume(ipa);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment