Commit e4f5073d authored by M Chetan Kumar's avatar M Chetan Kumar Committed by David S. Miller
Browse files

net: wwan: iosm: enable runtime pm support for 7560



Adds runtime pm support for 7560.

As part of probe procedure auto suspend is enabled and auto suspend
delay is set to 5000 ms for runtime pm use. Later auto flag is set
to power manage the device at run time.

On successful communication establishment between host and device the
device usage counter is dropped and request to put the device into
sleep state (suspend).

In TX path, the device usage counter is raised and device is moved out
of sleep(resume) for data transmission. In RX path, if the device has
some data to be sent it request host platform to change the power state
by giving PCI PME message.

Signed-off-by: default avatarM Chetan Kumar <m.chetan.kumar@linux.intel.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent cbb1ca6d
Loading
Loading
Loading
Loading
+17 −0
Original line number Diff line number Diff line
@@ -4,6 +4,7 @@
 */

#include <linux/delay.h>
#include <linux/pm_runtime.h>

#include "iosm_ipc_chnl_cfg.h"
#include "iosm_ipc_devlink.h"
@@ -631,6 +632,11 @@ static void ipc_imem_run_state_worker(struct work_struct *instance)
	/* Complete all memory stores after setting bit */
	smp_mb__after_atomic();

	if (ipc_imem->pcie->pci->device == INTEL_CP_DEVICE_7560_ID) {
		pm_runtime_mark_last_busy(ipc_imem->dev);
		pm_runtime_put_autosuspend(ipc_imem->dev);
	}

	return;

err_ipc_mux_deinit:
@@ -1234,6 +1240,7 @@ void ipc_imem_cleanup(struct iosm_imem *ipc_imem)

	/* forward MDM_NOT_READY to listeners */
	ipc_uevent_send(ipc_imem->dev, UEVENT_MDM_NOT_READY);
	pm_runtime_get_sync(ipc_imem->dev);

	hrtimer_cancel(&ipc_imem->td_alloc_timer);
	hrtimer_cancel(&ipc_imem->tdupdate_timer);
@@ -1419,6 +1426,16 @@ struct iosm_imem *ipc_imem_init(struct iosm_pcie *pcie, unsigned int device_id,

		set_bit(IOSM_DEVLINK_INIT, &ipc_imem->flag);
	}

	if (!pm_runtime_enabled(ipc_imem->dev))
		pm_runtime_enable(ipc_imem->dev);

	pm_runtime_set_autosuspend_delay(ipc_imem->dev,
					 IPC_MEM_AUTO_SUSPEND_DELAY_MS);
	pm_runtime_use_autosuspend(ipc_imem->dev);
	pm_runtime_allow(ipc_imem->dev);
	pm_runtime_mark_last_busy(ipc_imem->dev);

	return ipc_imem;
devlink_channel_fail:
	ipc_devlink_deinit(ipc_imem->ipc_devlink);
+2 −0
Original line number Diff line number Diff line
@@ -103,6 +103,8 @@ struct ipc_chnl_cfg;
#define FULLY_FUNCTIONAL 0
#define IOSM_DEVLINK_INIT 1

#define IPC_MEM_AUTO_SUSPEND_DELAY_MS 5000

/* List of the supported UL/DL pipes. */
enum ipc_mem_pipes {
	IPC_MEM_PIPE_0 = 0,
+3 −1
Original line number Diff line number Diff line
@@ -6,6 +6,7 @@
#include <linux/acpi.h>
#include <linux/bitfield.h>
#include <linux/module.h>
#include <linux/pm_runtime.h>
#include <net/rtnetlink.h>

#include "iosm_ipc_imem.h"
@@ -437,7 +438,8 @@ static int __maybe_unused ipc_pcie_resume_cb(struct device *dev)
	return 0;
}

static SIMPLE_DEV_PM_OPS(iosm_ipc_pm, ipc_pcie_suspend_cb, ipc_pcie_resume_cb);
static DEFINE_RUNTIME_DEV_PM_OPS(iosm_ipc_pm, ipc_pcie_suspend_cb,
				 ipc_pcie_resume_cb, NULL);

static struct pci_driver iosm_ipc_driver = {
	.name = KBUILD_MODNAME,
+16 −1
Original line number Diff line number Diff line
@@ -3,6 +3,8 @@
 * Copyright (C) 2020-21 Intel Corporation.
 */

#include <linux/pm_runtime.h>

#include "iosm_ipc_chnl_cfg.h"
#include "iosm_ipc_imem_ops.h"
#include "iosm_ipc_port.h"
@@ -13,12 +15,16 @@ static int ipc_port_ctrl_start(struct wwan_port *port)
	struct iosm_cdev *ipc_port = wwan_port_get_drvdata(port);
	int ret = 0;

	pm_runtime_get_sync(ipc_port->ipc_imem->dev);
	ipc_port->channel = ipc_imem_sys_port_open(ipc_port->ipc_imem,
						   ipc_port->chl_id,
						   IPC_HP_CDEV_OPEN);
	if (!ipc_port->channel)
		ret = -EIO;

	pm_runtime_mark_last_busy(ipc_port->ipc_imem->dev);
	pm_runtime_put_autosuspend(ipc_port->ipc_imem->dev);

	return ret;
}

@@ -27,15 +33,24 @@ static void ipc_port_ctrl_stop(struct wwan_port *port)
{
	struct iosm_cdev *ipc_port = wwan_port_get_drvdata(port);

	pm_runtime_get_sync(ipc_port->ipc_imem->dev);
	ipc_imem_sys_port_close(ipc_port->ipc_imem, ipc_port->channel);
	pm_runtime_mark_last_busy(ipc_port->ipc_imem->dev);
	pm_runtime_put_autosuspend(ipc_port->ipc_imem->dev);
}

/* transfer control data to modem */
static int ipc_port_ctrl_tx(struct wwan_port *port, struct sk_buff *skb)
{
	struct iosm_cdev *ipc_port = wwan_port_get_drvdata(port);
	int ret;

	return ipc_imem_sys_cdev_write(ipc_port, skb);
	pm_runtime_get_sync(ipc_port->ipc_imem->dev);
	ret = ipc_imem_sys_cdev_write(ipc_port, skb);
	pm_runtime_mark_last_busy(ipc_port->ipc_imem->dev);
	pm_runtime_put_autosuspend(ipc_port->ipc_imem->dev);

	return ret;
}

static const struct wwan_port_ops ipc_wwan_ctrl_ops = {
+8 −0
Original line number Diff line number Diff line
@@ -3,7 +3,9 @@
 * Copyright (C) 2020-2021 Intel Corporation.
 */

#include <linux/pm_runtime.h>
#include <linux/wwan.h>

#include "iosm_ipc_trace.h"

/* sub buffer size and number of sub buffer */
@@ -97,6 +99,8 @@ static ssize_t ipc_trace_ctrl_file_write(struct file *filp,
	if (ret)
		return ret;

	pm_runtime_get_sync(ipc_trace->ipc_imem->dev);

	mutex_lock(&ipc_trace->trc_mutex);
	if (val == TRACE_ENABLE && ipc_trace->mode != TRACE_ENABLE) {
		ipc_trace->channel = ipc_imem_sys_port_open(ipc_trace->ipc_imem,
@@ -117,6 +121,10 @@ static ssize_t ipc_trace_ctrl_file_write(struct file *filp,
	ret = count;
unlock:
	mutex_unlock(&ipc_trace->trc_mutex);

	pm_runtime_mark_last_busy(ipc_trace->ipc_imem->dev);
	pm_runtime_put_autosuspend(ipc_trace->ipc_imem->dev);

	return ret;
}

Loading