]> Git Repo - linux.git/blob - drivers/net/wwan/iosm/iosm_ipc_port.c
net: bgmac: Fix return value check for fixed_phy_register()
[linux.git] / drivers / net / wwan / iosm / iosm_ipc_port.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (C) 2020-21 Intel Corporation.
4  */
5
6 #include <linux/pm_runtime.h>
7
8 #include "iosm_ipc_chnl_cfg.h"
9 #include "iosm_ipc_imem_ops.h"
10 #include "iosm_ipc_port.h"
11
12 /* open logical channel for control communication */
13 static int ipc_port_ctrl_start(struct wwan_port *port)
14 {
15         struct iosm_cdev *ipc_port = wwan_port_get_drvdata(port);
16         int ret = 0;
17
18         pm_runtime_get_sync(ipc_port->ipc_imem->dev);
19         ipc_port->channel = ipc_imem_sys_port_open(ipc_port->ipc_imem,
20                                                    ipc_port->chl_id,
21                                                    IPC_HP_CDEV_OPEN);
22         if (!ipc_port->channel)
23                 ret = -EIO;
24
25         pm_runtime_mark_last_busy(ipc_port->ipc_imem->dev);
26         pm_runtime_put_autosuspend(ipc_port->ipc_imem->dev);
27
28         return ret;
29 }
30
31 /* close logical channel */
32 static void ipc_port_ctrl_stop(struct wwan_port *port)
33 {
34         struct iosm_cdev *ipc_port = wwan_port_get_drvdata(port);
35
36         pm_runtime_get_sync(ipc_port->ipc_imem->dev);
37         ipc_imem_sys_port_close(ipc_port->ipc_imem, ipc_port->channel);
38         pm_runtime_mark_last_busy(ipc_port->ipc_imem->dev);
39         pm_runtime_put_autosuspend(ipc_port->ipc_imem->dev);
40 }
41
42 /* transfer control data to modem */
43 static int ipc_port_ctrl_tx(struct wwan_port *port, struct sk_buff *skb)
44 {
45         struct iosm_cdev *ipc_port = wwan_port_get_drvdata(port);
46         int ret;
47
48         pm_runtime_get_sync(ipc_port->ipc_imem->dev);
49         ret = ipc_imem_sys_cdev_write(ipc_port, skb);
50         pm_runtime_mark_last_busy(ipc_port->ipc_imem->dev);
51         pm_runtime_put_autosuspend(ipc_port->ipc_imem->dev);
52
53         return ret;
54 }
55
56 static const struct wwan_port_ops ipc_wwan_ctrl_ops = {
57         .start = ipc_port_ctrl_start,
58         .stop = ipc_port_ctrl_stop,
59         .tx = ipc_port_ctrl_tx,
60 };
61
62 /* Port init func */
63 struct iosm_cdev *ipc_port_init(struct iosm_imem *ipc_imem,
64                                 struct ipc_chnl_cfg ipc_port_cfg)
65 {
66         struct iosm_cdev *ipc_port = kzalloc(sizeof(*ipc_port), GFP_KERNEL);
67         enum wwan_port_type port_type = ipc_port_cfg.wwan_port_type;
68         enum ipc_channel_id chl_id = ipc_port_cfg.id;
69
70         if (!ipc_port)
71                 return NULL;
72
73         ipc_port->dev = ipc_imem->dev;
74         ipc_port->pcie = ipc_imem->pcie;
75
76         ipc_port->port_type = port_type;
77         ipc_port->chl_id = chl_id;
78         ipc_port->ipc_imem = ipc_imem;
79
80         ipc_port->iosm_port = wwan_create_port(ipc_port->dev, port_type,
81                                                &ipc_wwan_ctrl_ops, NULL,
82                                                ipc_port);
83
84         return ipc_port;
85 }
86
87 /* Port deinit func */
88 void ipc_port_deinit(struct iosm_cdev *port[])
89 {
90         struct iosm_cdev *ipc_port;
91         u8 ctrl_chl_nr;
92
93         for (ctrl_chl_nr = 0; ctrl_chl_nr < IPC_MEM_MAX_CHANNELS;
94              ctrl_chl_nr++) {
95                 if (port[ctrl_chl_nr]) {
96                         ipc_port = port[ctrl_chl_nr];
97                         wwan_remove_port(ipc_port->iosm_port);
98                         kfree(ipc_port);
99                 }
100         }
101 }
This page took 0.038686 seconds and 4 git commands to generate.