summaryrefslogtreecommitdiffstats
path: root/drivers/net/ipa/ipa_main.c
diff options
context:
space:
mode:
authorAlex Elder <elder@linaro.org>2021-08-10 14:26:58 -0500
committerDavid S. Miller <davem@davemloft.net>2021-08-11 13:31:55 +0100
commit7ebd168c3bfc3ebf113545170c2bb28d02f0ba15 (patch)
treed3e3d328ea10b9e964b5bd72ff2a965f029d6937 /drivers/net/ipa/ipa_main.c
parent6f45933dfed0c1d90c2d9acfe6b782c5560ee038 (diff)
downloadlinux-7ebd168c3bfc3ebf113545170c2bb28d02f0ba15.tar.bz2
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>
Diffstat (limited to 'drivers/net/ipa/ipa_main.c')
-rw-r--r--drivers/net/ipa/ipa_main.c36
1 files changed, 21 insertions, 15 deletions
diff --git a/drivers/net/ipa/ipa_main.c b/drivers/net/ipa/ipa_main.c
index 25bbb456e007..64112a676774 100644
--- a/drivers/net/ipa/ipa_main.c
+++ b/drivers/net/ipa/ipa_main.c
@@ -431,7 +431,9 @@ static int ipa_config(struct ipa *ipa, const struct ipa_data *data)
* is held after initialization completes, and won't get dropped
* unless/until a system suspend request arrives.
*/
- ipa_clock_get(ipa);
+ ret = ipa_clock_get(ipa);
+ if (WARN_ON(ret < 0))
+ goto err_clock_put;
ipa_hardware_config(ipa, data);
@@ -475,7 +477,8 @@ err_mem_deconfig:
ipa_mem_deconfig(ipa);
err_hardware_deconfig:
ipa_hardware_deconfig(ipa);
- ipa_clock_put(ipa);
+err_clock_put:
+ (void)ipa_clock_put(ipa);
return ret;
}
@@ -493,7 +496,7 @@ static void ipa_deconfig(struct ipa *ipa)
ipa->interrupt = NULL;
ipa_mem_deconfig(ipa);
ipa_hardware_deconfig(ipa);
- ipa_clock_put(ipa);
+ (void)ipa_clock_put(ipa);
}
static int ipa_firmware_load(struct device *dev)
@@ -750,20 +753,22 @@ static int ipa_probe(struct platform_device *pdev)
goto err_table_exit;
/* The clock needs to be active for config and setup */
- ipa_clock_get(ipa);
+ ret = ipa_clock_get(ipa);
+ if (WARN_ON(ret < 0))
+ goto err_clock_put;
ret = ipa_config(ipa, data);
if (ret)
- goto err_clock_put; /* Error */
+ goto err_clock_put;
dev_info(dev, "IPA driver initialized");
/* If the modem is doing early initialization, it will trigger a
- * call to ipa_setup() call when it has finished. In that case
- * we're done here.
+ * call to ipa_setup() when it has finished. In that case we're
+ * done here.
*/
if (modem_init)
- goto out_clock_put; /* Done; no error */
+ goto done;
/* Otherwise we need to load the firmware and have Trust Zone validate
* and install it. If that succeeds we can proceed with setup.
@@ -775,16 +780,15 @@ static int ipa_probe(struct platform_device *pdev)
ret = ipa_setup(ipa);
if (ret)
goto err_deconfig;
-
-out_clock_put:
- ipa_clock_put(ipa);
+done:
+ (void)ipa_clock_put(ipa);
return 0;
err_deconfig:
ipa_deconfig(ipa);
err_clock_put:
- ipa_clock_put(ipa);
+ (void)ipa_clock_put(ipa);
ipa_modem_exit(ipa);
err_table_exit:
ipa_table_exit(ipa);
@@ -810,7 +814,9 @@ static int ipa_remove(struct platform_device *pdev)
struct ipa_clock *clock = ipa->clock;
int ret;
- ipa_clock_get(ipa);
+ ret = ipa_clock_get(ipa);
+ if (WARN_ON(ret < 0))
+ goto out_clock_put;
if (ipa->setup_complete) {
ret = ipa_modem_stop(ipa);
@@ -826,8 +832,8 @@ static int ipa_remove(struct platform_device *pdev)
}
ipa_deconfig(ipa);
-
- ipa_clock_put(ipa);
+out_clock_put:
+ (void)ipa_clock_put(ipa);
ipa_modem_exit(ipa);
ipa_table_exit(ipa);