Commit c1125062 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'ipa-kill-off-ipa_clock_get'



Alex Elder says:

====================
net: ipa: kill off ipa_clock_get()

This series replaces the remaining uses of ipa_clock_get() with
calls to pm_runtime_get_sync() instead.  It replaces all calls to
ipa_clock_put() with calls to pm_runtime_put().

This completes the preparation for enabling automated suspend under
the control of the power management core code.  The next patch (in
an upcoming series) enables that.  Then the "ipa_clock" files and
symbols will switch to using an "ipa_power" naming convention instead.

Additional info

It is possible for pm_runtime_get_sync() to return an error.  There
are really three cases, identified by return value:
  - 1, meaning power was already active
  - 0, meaning power was not previously active, but is now
  - EACCES, meaning runtime PM is disabled
One additional case is EINVAL, meaning a previous suspend or resume
(or idle) call returned an error.  But we have always assumed this
won't happen (we previously didn't even check for an error).

But because we use pm_runtime_force_suspend() to implement system
suspend, there's a chance we'd get an EACCES error (the first thing
that function does is disable runtime suspend).  Individual patches
explain what happens in that case, but generally we just accept that
it could be an unlikely problem (occurring only at startup time).

Similarly, pm_runtime_put() could return an error.  There too, we
ignore EINVAL, assuming the IPA suspend and resume operations won't
produce an error.  EBUSY and EPERM are not applicable, EAGAIN is not
expected (and harmless).  We should never get EACCES (runtime
suspend disabled), because pm_runtime_put() calls match prior
pm_runtime_get_sync() calls, and a system suspend will not be
started while a runtime suspend or resume is underway.  In summary,
the value returned from pm_runtime_put() is not meaningful, so we
explicitly ignore it.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents b8e36e13 c3f115aa
Loading
Loading
Loading
Loading
+0 −17
Original line number Diff line number Diff line
@@ -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);
+0 −24
Original line number Diff line number Diff line
@@ -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_ */
+7 −7
Original line number Diff line number Diff line
@@ -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;
}
+11 −10
Original line number Diff line number Diff line
@@ -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);
+23 −17
Original line number Diff line number Diff line
@@ -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,
Loading