diff options
author | David S. Miller <davem@davemloft.net> | 2021-06-18 23:13:40 +0300 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2021-06-18 23:13:40 +0300 |
commit | 4bea7207a80c8bba3b3eb5b84c407b162968475f (patch) | |
tree | 149cbe7b468334c730c302617fc331876e11e726 /drivers/net/wwan/wwan_core.c | |
parent | 01bf086b7c836bf5ccb6a92bb98b42ebfc841fc7 (diff) | |
parent | 31c143f712750143abaca396236bbe8707700111 (diff) | |
download | linux-4bea7207a80c8bba3b3eb5b84c407b162968475f.tar.xz |
Merge branch 'RPMSG-WWAN-CTRL-driver'
Stephan Gerhold says:
====================
net: wwan: Add RPMSG WWAN CTRL driver
This patch series adds a WWAN "control" driver for the remote processor
messaging (rpmsg) subsystem. This subsystem allows communicating with
an integrated modem DSP on many Qualcomm SoCs, e.g. MSM8916 or MSM8974.
The driver is a fairly simple glue layer between WWAN and RPMSG
and is mostly based on the existing mhi_wwan_ctrl.c and rpmsg_char.c.
For more information, see commit message in PATCH 2/3.
I already posted a RFC for this a while ago:
https://lore.kernel.org/linux-arm-msm/YLfL9Q+4860uqS8f@gerhold.net/
and now I'm looking for some feedback for the actual changes. :)
Changes in v3:
- PATCH 2/3: Clarify commit message
- PATCH 3/3: Fix build error for cdc-wdm.c, use extra tx_blocking() op instead
v2: https://lore.kernel.org/netdev/20210618075243.42046-1-stephan@gerhold.net/
Changes in v2: Only in PATCH 3/3
- Fix EPOLLOUT being always set even if poll op is defined
- Rename poll() op -> tx_poll() since it should be only used for TX
v1: https://lore.kernel.org/netdev/20210615133229.213064-1-stephan@gerhold.net/
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/wwan/wwan_core.c')
-rw-r--r-- | drivers/net/wwan/wwan_core.c | 16 |
1 files changed, 12 insertions, 4 deletions
diff --git a/drivers/net/wwan/wwan_core.c b/drivers/net/wwan/wwan_core.c index 7e728042fc41..165afec1dbd1 100644 --- a/drivers/net/wwan/wwan_core.c +++ b/drivers/net/wwan/wwan_core.c @@ -500,7 +500,8 @@ static void wwan_port_op_stop(struct wwan_port *port) mutex_unlock(&port->ops_lock); } -static int wwan_port_op_tx(struct wwan_port *port, struct sk_buff *skb) +static int wwan_port_op_tx(struct wwan_port *port, struct sk_buff *skb, + bool nonblock) { int ret; @@ -510,7 +511,10 @@ static int wwan_port_op_tx(struct wwan_port *port, struct sk_buff *skb) goto out_unlock; } - ret = port->ops->tx(port, skb); + if (nonblock || !port->ops->tx_blocking) + ret = port->ops->tx(port, skb); + else + ret = port->ops->tx_blocking(port, skb); out_unlock: mutex_unlock(&port->ops_lock); @@ -637,7 +641,7 @@ static ssize_t wwan_port_fops_write(struct file *filp, const char __user *buf, return -EFAULT; } - ret = wwan_port_op_tx(port, skb); + ret = wwan_port_op_tx(port, skb, !!(filp->f_flags & O_NONBLOCK)); if (ret) { kfree_skb(skb); return ret; @@ -653,12 +657,16 @@ static __poll_t wwan_port_fops_poll(struct file *filp, poll_table *wait) poll_wait(filp, &port->waitqueue, wait); - if (!is_write_blocked(port)) + mutex_lock(&port->ops_lock); + if (port->ops && port->ops->tx_poll) + mask |= port->ops->tx_poll(port, filp, wait); + else if (!is_write_blocked(port)) mask |= EPOLLOUT | EPOLLWRNORM; if (!is_read_blocked(port)) mask |= EPOLLIN | EPOLLRDNORM; if (!port->ops) mask |= EPOLLHUP | EPOLLERR; + mutex_unlock(&port->ops_lock); return mask; } |