linux/drivers/net/wwan/iosm/iosm_ipc_port.c
Bagas Sanjaya 1db34aa58d Revert "net: wwan: iosm: enable runtime pm support for 7560"
Runtime power management support breaks Intel LTE modem where dmesg dump
showes timeout errors:

```
[   72.027442] iosm 0000:01:00.0: msg timeout
[   72.531638] iosm 0000:01:00.0: msg timeout
[   73.035414] iosm 0000:01:00.0: msg timeout
[   73.540359] iosm 0000:01:00.0: msg timeout
```

Furthermore, when shutting down with `poweroff` and modem attached, the
system rebooted instead of powering down as expected. The modem works
again only after power cycling.

Revert runtime power management support for IOSM driver as introduced by
commit e4f5073d53be6c ("net: wwan: iosm: enable runtime pm support for
7560").

Fixes: e4f5073d53be ("net: wwan: iosm: enable runtime pm support for 7560")
Reported-by: Martin <mwolf@adiumentum.com>
Closes: https://bugzilla.kernel.org/show_bug.cgi?id=217996
Link: https://lore.kernel.org/r/267abf02-4b60-4a2e-92cd-709e3da6f7d3@gmail.com/
Signed-off-by: Bagas Sanjaya <bagasdotme@gmail.com>
Reviewed-by: Loic Poulain <loic.poulain@linaro.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2023-10-18 11:08:52 +01:00

87 lines
2.0 KiB
C

// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (C) 2020-21 Intel Corporation.
*/
#include "iosm_ipc_chnl_cfg.h"
#include "iosm_ipc_imem_ops.h"
#include "iosm_ipc_port.h"
/* open logical channel for control communication */
static int ipc_port_ctrl_start(struct wwan_port *port)
{
struct iosm_cdev *ipc_port = wwan_port_get_drvdata(port);
int ret = 0;
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;
return ret;
}
/* close logical channel */
static void ipc_port_ctrl_stop(struct wwan_port *port)
{
struct iosm_cdev *ipc_port = wwan_port_get_drvdata(port);
ipc_imem_sys_port_close(ipc_port->ipc_imem, ipc_port->channel);
}
/* 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);
return ipc_imem_sys_cdev_write(ipc_port, skb);
}
static const struct wwan_port_ops ipc_wwan_ctrl_ops = {
.start = ipc_port_ctrl_start,
.stop = ipc_port_ctrl_stop,
.tx = ipc_port_ctrl_tx,
};
/* Port init func */
struct iosm_cdev *ipc_port_init(struct iosm_imem *ipc_imem,
struct ipc_chnl_cfg ipc_port_cfg)
{
struct iosm_cdev *ipc_port = kzalloc(sizeof(*ipc_port), GFP_KERNEL);
enum wwan_port_type port_type = ipc_port_cfg.wwan_port_type;
enum ipc_channel_id chl_id = ipc_port_cfg.id;
if (!ipc_port)
return NULL;
ipc_port->dev = ipc_imem->dev;
ipc_port->pcie = ipc_imem->pcie;
ipc_port->port_type = port_type;
ipc_port->chl_id = chl_id;
ipc_port->ipc_imem = ipc_imem;
ipc_port->iosm_port = wwan_create_port(ipc_port->dev, port_type,
&ipc_wwan_ctrl_ops, NULL,
ipc_port);
return ipc_port;
}
/* Port deinit func */
void ipc_port_deinit(struct iosm_cdev *port[])
{
struct iosm_cdev *ipc_port;
u8 ctrl_chl_nr;
for (ctrl_chl_nr = 0; ctrl_chl_nr < IPC_MEM_MAX_CHANNELS;
ctrl_chl_nr++) {
if (port[ctrl_chl_nr]) {
ipc_port = port[ctrl_chl_nr];
wwan_remove_port(ipc_port->iosm_port);
kfree(ipc_port);
}
}
}