[PATCH net-next v2 1/3] net: wwan: core: propagate modem control signals to port drivers

Peter Hunt <[email protected]>
Newsgroups dev.linux.lists.mhi,org.kernel.vger.linux-arm-msm,org.kernel.vger.linux-kernel,org.kernel.vger.netdev
Message-ID <[email protected]>
The WWAN character device emulates the TTY modem-control ioctls
(TIOCMGET/TIOCMSET/TIOCMBIC/TIOCMBIS) for AT and QCDM ports, but the
result is only stored in port->at_data.mdmbits and never reaches the port
driver. A driver therefore cannot act on the host raising or dropping
DTR/RTS, even though some modems depend on it (e.g. they withhold
unsolicited AT result codes until the host asserts DTR).

Add optional ->tiocmget/->tiocmset operations to struct wwan_port_ops and
call them from the AT/QCDM ioctl path. ->tiocmset is passed the resolved
TIOCM_* bitmask after BIC/BIS/SET has been applied; ->tiocmget, when
provided, refreshes the cached bits from the device. Drivers that do not
implement them keep the previous store-only behaviour.

Signed-off-by: Peter Hunt <[email protected]>
---
 drivers/net/wwan/wwan_core.c | 12 +++++++++++-
 include/linux/wwan.h         |  4 ++++
 2 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wwan/wwan_core.c b/drivers/net/wwan/wwan_core.c
index ffbcf11e4e68..bf83eb5790fe 100644
--- a/drivers/net/wwan/wwan_core.c
+++ b/drivers/net/wwan/wwan_core.c
@@ -1018,7 +1018,15 @@ static long wwan_port_fops_at_ioctl(struct wwan_port *port, unsigned int cmd,
 #endif
 
 	case TIOCMGET:
-		ret = put_user(port->at_data.mdmbits, (int __user *)arg);
+		if (port->ops->tiocmget) {
+			ret = port->ops->tiocmget(port);
+			if (ret >= 0) {
+				port->at_data.mdmbits = ret;
+				ret = 0;
+			}
+		}
+		if (!ret)
+			ret = put_user(port->at_data.mdmbits, (int __user *)arg);
 		break;
 
 	case TIOCMSET:
@@ -1036,6 +1044,8 @@ static long wwan_port_fops_at_ioctl(struct wwan_port *port, unsigned int cmd,
 			port->at_data.mdmbits |= mdmbits;
 		else
 			port->at_data.mdmbits = mdmbits;
+		if (port->ops->tiocmset)
+			ret = port->ops->tiocmset(port, port->at_data.mdmbits);
 		break;
 	}
 
diff --git a/include/linux/wwan.h b/include/linux/wwan.h
index 1e0e2cb53579..bac02521e274 100644
--- a/include/linux/wwan.h
+++ b/include/linux/wwan.h
@@ -57,6 +57,8 @@ struct wwan_port;
  * @tx_blocking: Optional blocking routine that sends WWAN port protocol data
  *               to the device.
  * @tx_poll: Optional routine that sets additional TX poll flags.
+ * @tiocmget: Optional routine that reads the modem control lines.
+ * @tiocmset: Optional routine that sets the modem control lines.
  *
  * The wwan_port_ops structure contains a list of low-level operations
  * that control a WWAN port device. All functions are mandatory unless specified.
@@ -70,6 +72,8 @@ struct wwan_port_ops {
 	int (*tx_blocking)(struct wwan_port *port, struct sk_buff *skb);
 	__poll_t (*tx_poll)(struct wwan_port *port, struct file *filp,
 			    poll_table *wait);
+	int (*tiocmget)(struct wwan_port *port);
+	int (*tiocmset)(struct wwan_port *port, unsigned int mdmbits);
 };
 
 /** struct wwan_port_caps - The WWAN port capbilities
-- 
2.43.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.