aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/net/ipa/ipa_clock.c17
-rw-r--r--drivers/net/ipa/ipa_clock.h24
-rw-r--r--drivers/net/ipa/ipa_interrupt.c14
-rw-r--r--drivers/net/ipa/ipa_main.c21
-rw-r--r--drivers/net/ipa/ipa_modem.c40
-rw-r--r--drivers/net/ipa/ipa_smp2p.c19
-rw-r--r--drivers/net/ipa/ipa_uc.c22
7 files changed, 65 insertions, 92 deletions
diff --git a/drivers/net/ipa/ipa_clock.c b/drivers/net/ipa/ipa_clock.c
index 74eb9ecdd19b..149b24da0bcc 100644
--- a/drivers/net/ipa/ipa_clock.c
+++ b/drivers/net/ipa/ipa_clock.c
@@ -272,23 +272,6 @@ static int ipa_runtime_idle(struct device *dev)
return -EAGAIN;
}
-/* Get an IPA clock reference. If the reference count is non-zero, it is
- * incremented and return is immediate. Otherwise the IPA clock is
- * enabled.
- */
-int ipa_clock_get(struct ipa *ipa)
-{
- return pm_runtime_get_sync(&ipa->pdev->dev);
-}
-
-/* Attempt to remove an IPA clock reference. If this represents the
- * last reference, disable the IPA clock.
- */
-int ipa_clock_put(struct ipa *ipa)
-{
- return pm_runtime_put(&ipa->pdev->dev);
-}
-
static int ipa_suspend(struct device *dev)
{
struct ipa *ipa = dev_get_drvdata(dev);
diff --git a/drivers/net/ipa/ipa_clock.h b/drivers/net/ipa/ipa_clock.h
index 64cd15981b1d..7b7864f3029b 100644
--- a/drivers/net/ipa/ipa_clock.h
+++ b/drivers/net/ipa/ipa_clock.h
@@ -70,28 +70,4 @@ struct ipa_clock *ipa_clock_init(struct device *dev,
*/
void ipa_clock_exit(struct ipa_clock *clock);
-/**
- * ipa_clock_get() - Get an IPA clock reference
- * @ipa: IPA pointer
- *
- * Return: 0 if clock started, 1 if clock already running, or a negative
- * error code
- *
- * This call blocks if this is the first reference. A reference is
- * taken even if an error occurs starting the IPA clock.
- */
-int ipa_clock_get(struct ipa *ipa);
-
-/**
- * ipa_clock_put() - Drop an IPA clock reference
- * @ipa: IPA pointer
- *
- * Return: 0 if successful, or a negative error code
- *
- * This drops a clock reference. If the last reference is being dropped,
- * the clock is stopped and RX endpoints are suspended. This call will
- * not block unless the last reference is dropped.
- */
-int ipa_clock_put(struct ipa *ipa);
-
#endif /* _IPA_CLOCK_H_ */
diff --git a/drivers/net/ipa/ipa_interrupt.c b/drivers/net/ipa/ipa_interrupt.c
index 934c14e066a0..3fecaadb4a37 100644
--- a/drivers/net/ipa/ipa_interrupt.c
+++ b/drivers/net/ipa/ipa_interrupt.c
@@ -21,9 +21,9 @@
#include <linux/types.h>
#include <linux/interrupt.h>
+#include <linux/pm_runtime.h>
#include "ipa.h"
-#include "ipa_clock.h"
#include "ipa_reg.h"
#include "ipa_endpoint.h"
#include "ipa_interrupt.h"
@@ -80,14 +80,16 @@ static irqreturn_t ipa_isr_thread(int irq, void *dev_id)
struct ipa_interrupt *interrupt = dev_id;
struct ipa *ipa = interrupt->ipa;
u32 enabled = interrupt->enabled;
+ struct device *dev;
u32 pending;
u32 offset;
u32 mask;
int ret;
- ret = ipa_clock_get(ipa);
+ dev = &ipa->pdev->dev;
+ ret = pm_runtime_get_sync(dev);
if (WARN_ON(ret < 0))
- goto out_clock_put;
+ goto out_power_put;
/* The status register indicates which conditions are present,
* including conditions whose interrupt is not enabled. Handle
@@ -108,15 +110,13 @@ static irqreturn_t ipa_isr_thread(int irq, void *dev_id)
/* If any disabled interrupts are pending, clear them */
if (pending) {
- struct device *dev = &ipa->pdev->dev;
-
dev_dbg(dev, "clearing disabled IPA interrupts 0x%08x\n",
pending);
offset = ipa_reg_irq_clr_offset(ipa->version);
iowrite32(pending, ipa->reg_virt + offset);
}
-out_clock_put:
- (void)ipa_clock_put(ipa);
+out_power_put:
+ (void)pm_runtime_put(dev);
return IRQ_HANDLED;
}
diff --git a/drivers/net/ipa/ipa_main.c b/drivers/net/ipa/ipa_main.c
index 69fa4b3120fd..3969aef6c437 100644
--- a/drivers/net/ipa/ipa_main.c
+++ b/drivers/net/ipa/ipa_main.c
@@ -15,6 +15,7 @@
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/of_address.h>
+#include <linux/pm_runtime.h>
#include <linux/qcom_scm.h>
#include <linux/soc/qcom/mdt_loader.h>
@@ -737,13 +738,13 @@ static int ipa_probe(struct platform_device *pdev)
goto err_table_exit;
/* The clock needs to be active for config and setup */
- ret = ipa_clock_get(ipa);
+ ret = pm_runtime_get_sync(dev);
if (WARN_ON(ret < 0))
- goto err_clock_put;
+ goto err_power_put;
ret = ipa_config(ipa, data);
if (ret)
- goto err_clock_put;
+ goto err_power_put;
dev_info(dev, "IPA driver initialized");
@@ -765,14 +766,14 @@ static int ipa_probe(struct platform_device *pdev)
if (ret)
goto err_deconfig;
done:
- (void)ipa_clock_put(ipa);
+ (void)pm_runtime_put(dev);
return 0;
err_deconfig:
ipa_deconfig(ipa);
-err_clock_put:
- (void)ipa_clock_put(ipa);
+err_power_put:
+ (void)pm_runtime_put(dev);
ipa_modem_exit(ipa);
err_table_exit:
ipa_table_exit(ipa);
@@ -798,9 +799,9 @@ static int ipa_remove(struct platform_device *pdev)
struct ipa_clock *clock = ipa->clock;
int ret;
- ret = ipa_clock_get(ipa);
+ ret = pm_runtime_get_sync(&pdev->dev);
if (WARN_ON(ret < 0))
- goto out_clock_put;
+ goto out_power_put;
if (ipa->setup_complete) {
ret = ipa_modem_stop(ipa);
@@ -816,8 +817,8 @@ static int ipa_remove(struct platform_device *pdev)
}
ipa_deconfig(ipa);
-out_clock_put:
- (void)ipa_clock_put(ipa);
+out_power_put:
+ (void)pm_runtime_put(&pdev->dev);
ipa_modem_exit(ipa);
ipa_table_exit(ipa);
diff --git a/drivers/net/ipa/ipa_modem.c b/drivers/net/ipa/ipa_modem.c
index 16d87910305e..11f0204a9695 100644
--- a/drivers/net/ipa/ipa_modem.c
+++ b/drivers/net/ipa/ipa_modem.c
@@ -49,15 +49,17 @@ static int ipa_open(struct net_device *netdev)
{
struct ipa_priv *priv = netdev_priv(netdev);
struct ipa *ipa = priv->ipa;
+ struct device *dev;
int ret;
- ret = ipa_clock_get(ipa);
- if (WARN_ON(ret < 0))
- goto err_clock_put;
+ dev = &ipa->pdev->dev;
+ ret = pm_runtime_get_sync(dev);
+ if (ret < 0)
+ goto err_power_put;
ret = ipa_endpoint_enable_one(ipa->name_map[IPA_ENDPOINT_AP_MODEM_TX]);
if (ret)
- goto err_clock_put;
+ goto err_power_put;
ret = ipa_endpoint_enable_one(ipa->name_map[IPA_ENDPOINT_AP_MODEM_RX]);
if (ret)
@@ -65,14 +67,14 @@ static int ipa_open(struct net_device *netdev)
netif_start_queue(netdev);
- (void)ipa_clock_put(ipa);
+ (void)pm_runtime_put(dev);
return 0;
err_disable_tx:
ipa_endpoint_disable_one(ipa->name_map[IPA_ENDPOINT_AP_MODEM_TX]);
-err_clock_put:
- (void)ipa_clock_put(ipa);
+err_power_put:
+ (void)pm_runtime_put(dev);
return ret;
}
@@ -82,18 +84,20 @@ static int ipa_stop(struct net_device *netdev)
{
struct ipa_priv *priv = netdev_priv(netdev);
struct ipa *ipa = priv->ipa;
+ struct device *dev;
int ret;
- ret = ipa_clock_get(ipa);
- if (WARN_ON(ret < 0))
- goto out_clock_put;
+ dev = &ipa->pdev->dev;
+ ret = pm_runtime_get_sync(dev);
+ if (ret < 0)
+ goto out_power_put;
netif_stop_queue(netdev);
ipa_endpoint_disable_one(ipa->name_map[IPA_ENDPOINT_AP_MODEM_RX]);
ipa_endpoint_disable_one(ipa->name_map[IPA_ENDPOINT_AP_MODEM_TX]);
-out_clock_put:
- (void)ipa_clock_put(ipa);
+out_power_put:
+ (void)pm_runtime_put(dev);
return 0;
}
@@ -362,9 +366,11 @@ static void ipa_modem_crashed(struct ipa *ipa)
struct device *dev = &ipa->pdev->dev;
int ret;
- ret = ipa_clock_get(ipa);
- if (WARN_ON(ret < 0))
- goto out_clock_put;
+ ret = pm_runtime_get_sync(dev);
+ if (ret < 0) {
+ dev_err(dev, "error %d getting power to handle crash\n", ret);
+ goto out_power_put;
+ }
ipa_endpoint_modem_pause_all(ipa, true);
@@ -391,8 +397,8 @@ static void ipa_modem_crashed(struct ipa *ipa)
if (ret)
dev_err(dev, "error %d zeroing modem memory regions\n", ret);
-out_clock_put:
- (void)ipa_clock_put(ipa);
+out_power_put:
+ (void)pm_runtime_put(dev);
}
static int ipa_modem_notify(struct notifier_block *nb, unsigned long action,
diff --git a/drivers/net/ipa/ipa_smp2p.c b/drivers/net/ipa/ipa_smp2p.c
index 04b977cf9159..f6e2061cd391 100644
--- a/drivers/net/ipa/ipa_smp2p.c
+++ b/drivers/net/ipa/ipa_smp2p.c
@@ -16,7 +16,6 @@
#include "ipa_smp2p.h"
#include "ipa.h"
#include "ipa_uc.h"
-#include "ipa_clock.h"
/**
* DOC: IPA SMP2P communication with the modem
@@ -153,6 +152,7 @@ static void ipa_smp2p_panic_notifier_unregister(struct ipa_smp2p *smp2p)
static irqreturn_t ipa_smp2p_modem_setup_ready_isr(int irq, void *dev_id)
{
struct ipa_smp2p *smp2p = dev_id;
+ struct device *dev;
int ret;
mutex_lock(&smp2p->mutex);
@@ -161,17 +161,20 @@ static irqreturn_t ipa_smp2p_modem_setup_ready_isr(int irq, void *dev_id)
goto out_mutex_unlock;
smp2p->disabled = true; /* If any others arrive, ignore them */
- /* The clock needs to be active for setup */
- ret = ipa_clock_get(smp2p->ipa);
- if (WARN_ON(ret < 0))
- goto out_clock_put;
+ /* Power needs to be active for setup */
+ dev = &smp2p->ipa->pdev->dev;
+ ret = pm_runtime_get_sync(dev);
+ if (ret < 0) {
+ dev_err(dev, "error %d getting power for setup\n", ret);
+ goto out_power_put;
+ }
/* An error here won't cause driver shutdown, so warn if one occurs */
ret = ipa_setup(smp2p->ipa);
WARN(ret != 0, "error %d from ipa_setup()\n", ret);
-out_clock_put:
- (void)ipa_clock_put(smp2p->ipa);
+out_power_put:
+ (void)pm_runtime_put(dev);
out_mutex_unlock:
mutex_unlock(&smp2p->mutex);
@@ -211,7 +214,7 @@ static void ipa_smp2p_clock_release(struct ipa *ipa)
if (!ipa->smp2p->clock_on)
return;
- (void)ipa_clock_put(ipa);
+ (void)pm_runtime_put(&ipa->pdev->dev);
ipa->smp2p->clock_on = false;
}
diff --git a/drivers/net/ipa/ipa_uc.c b/drivers/net/ipa/ipa_uc.c
index 9c8818c39073..a0bdd25b65b4 100644
--- a/drivers/net/ipa/ipa_uc.c
+++ b/drivers/net/ipa/ipa_uc.c
@@ -7,9 +7,9 @@
#include <linux/types.h>
#include <linux/io.h>
#include <linux/delay.h>
+#include <linux/pm_runtime.h>
#include "ipa.h"
-#include "ipa_clock.h"
#include "ipa_uc.h"
/**
@@ -154,7 +154,7 @@ static void ipa_uc_response_hdlr(struct ipa *ipa, enum ipa_irq_id irq_id)
case IPA_UC_RESPONSE_INIT_COMPLETED:
if (ipa->uc_clocked) {
ipa->uc_loaded = true;
- (void)ipa_clock_put(ipa);
+ (void)pm_runtime_put(dev);
ipa->uc_clocked = false;
} else {
dev_warn(dev, "unexpected init_completed response\n");
@@ -182,25 +182,29 @@ void ipa_uc_deconfig(struct ipa *ipa)
ipa_interrupt_remove(ipa->interrupt, IPA_IRQ_UC_1);
ipa_interrupt_remove(ipa->interrupt, IPA_IRQ_UC_0);
if (ipa->uc_clocked)
- (void)ipa_clock_put(ipa);
+ (void)pm_runtime_put(&ipa->pdev->dev);
}
/* Take a proxy clock reference for the microcontroller */
void ipa_uc_clock(struct ipa *ipa)
{
static bool already;
+ struct device *dev;
int ret;
if (already)
return;
already = true; /* Only do this on first boot */
- /* This clock reference dropped in ipa_uc_response_hdlr() above */
- ret = ipa_clock_get(ipa);
- if (WARN(ret < 0, "error %d getting proxy clock\n", ret))
- (void)ipa_clock_put(ipa);
-
- ipa->uc_clocked = ret >= 0;
+ /* This power reference dropped in ipa_uc_response_hdlr() above */
+ dev = &ipa->pdev->dev;
+ ret = pm_runtime_get_sync(dev);
+ if (ret < 0) {
+ pm_runtime_put_noidle(dev);
+ dev_err(dev, "error %d getting proxy power\n", ret);
+ } else {
+ ipa->uc_clocked = true;
+ }
}
/* Send a command to the microcontroller */