mbox series

[PATCHv6,0/4] n_gsm serdev support and protocol driver for droid4 modem

Message ID 20200421232752.3070-1-tony@atomide.com
Headers show
Series n_gsm serdev support and protocol driver for droid4 modem | expand

Message

Tony Lindgren April 21, 2020, 11:27 p.m. UTC
Hi all,

Here's v4 set of n_gsm serdev support patches, and the related protocol
driver for the modem found on Motorola Mapphone phones and tablets
like droid4.

This series only adds basic character device support for the serdev
driver. Other serdev consumer drivers for specific devices will be
posted separately.

The patches are against v5.6-rc series.

Regards,

Tony


Changes since v5:
- Cosmetic fixes for issues noted by Pavel

Changes since v4:
- Use drivers/tty/serdev/protocol directory for the driver instead of
  drivers/mfd as discussed on the lists for v3 set of patches
- Fix remove to call kfree only after removing device from the list

Changes since v3:
- Update list of folks in Cc, looks like I sent v3 only to Lee and lkml
- Init privdata before motmdm_register_dlci calls gsm_serdev_register_dlci
- Update binding based on Rob's comments for license and "allOf"

Changes since v2:
- Drop useless send_command indirection, use static motmdm_send_command

Changes since v1:

- Simplified usage and got rid of few pointless inline functions
- Added consumer MFD driver, devicetree binding, and dts changes


Tony Lindgren (4):
  tty: n_gsm: Add support for serdev drivers
  serdev: ngsm-motmdm: Add Motorola TS 27.010 serdev modem driver for
    droid4
  dt-bindings: serdev: motmdm: Add binding for motorola-mdm
  ARM: dts: omap4-droid4: Enable basic modem support

 .../serdev/motorola,mapphone-mdm6600.yaml     |   34 +
 .../boot/dts/motorola-mapphone-common.dtsi    |    6 +
 drivers/tty/n_gsm.c                           |  372 +++++
 drivers/tty/serdev/Kconfig                    |    2 +
 drivers/tty/serdev/Makefile                   |    2 +
 drivers/tty/serdev/protocol/Kconfig           |   14 +
 drivers/tty/serdev/protocol/Makefile          |    3 +
 .../tty/serdev/protocol/serdev-ngsm-motmdm.c  | 1191 +++++++++++++++++
 include/linux/serdev-gsm.h                    |  168 +++
 9 files changed, 1792 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/serdev/motorola,mapphone-mdm6600.yaml
 create mode 100644 drivers/tty/serdev/protocol/Kconfig
 create mode 100644 drivers/tty/serdev/protocol/Makefile
 create mode 100644 drivers/tty/serdev/protocol/serdev-ngsm-motmdm.c
 create mode 100644 include/linux/serdev-gsm.h

Comments

Pavel Machek Dec. 20, 2020, 10:48 p.m. UTC | #1
Hi!

> Sorry about the late reply on this.


I'm afraid I'll need some more answers in near future, but for now:

Tony, do you remember / can you figure out what gsmtty GPS is on? I
never used it on that interface, and I can't seem to figure it out.

My notes say:

/dev/motmdm1 -- basic support, calls, on/off                                    
/dev/motmdm3 -- send sms interface                                              
/dev/motmdm9 -- receive sms interface                                           

(and gsmtty numbering is same)

For now I converted gnss driver to use serdev interface, and n_gsm to
provide it... Not yet finished but I believe I'm walking in the right
direction.

Best regards,
								Pavel

diff --git a/arch/arm/boot/dts/motorola-mapphone-common.dtsi b/arch/arm/boot/dts/motorola-mapphone-common.dtsi
index f5e7ec8e1028..ce907aa40a28 100644
--- a/arch/arm/boot/dts/motorola-mapphone-common.dtsi
+++ b/arch/arm/boot/dts/motorola-mapphone-common.dtsi
@@ -761,9 +761,22 @@
 		};
 
 		gnss@4 {
-			compatible = "motorola,mapphone-mdm6600-gnss";
+			compatible = "disabled-old,motorola,mapphone-mdm6600-gnss";
 			reg = <4>;
 		};
+
+		port@1 {
+			compatible = "gsmmux,port";
+			reg = <1>;
+			subdev@1 {
+				 compatible = "motorola,mapphone-mdm6600-gnss";
+			};
+		};
+
+		port@3 {
+			compatible = "disabled,gsmmux,port";
+			reg = <3>;
+		};
 	};
 };
 
diff --git a/drivers/gnss/motmdm.c b/drivers/gnss/motmdm.c
index da1d44bed899..5a74bbcbc5de 100644
--- a/drivers/gnss/motmdm.c
+++ b/drivers/gnss/motmdm.c
@@ -3,11 +3,14 @@
  * Motorola Modem TS 27.010 serdev GNSS driver
  *
  * Copyright (C) 2018 - 2020 Tony Lindgren <tony@atomide.com>
+ * Copyright (C) 2020 Pavel Machek <pavel@ucw.cz>
  *
  * Based on drivers/gnss/sirf.c driver example:
  * Copyright (C) 2018 Johan Hovold <johan@kernel.org>
  */
 
+/* FIXME: see serial.c for good example..? */
+
 #include <linux/errno.h>
 #include <linux/gnss.h>
 #include <linux/init.h>
@@ -45,7 +48,7 @@ enum motmdm_gnss_status {
 struct motmdm_gnss_data {
 	struct gnss_device *gdev;
 	struct device *modem;
-	struct gsm_serdev_dlci dlci;
+	struct serdev_device *serdev;
 	struct delayed_work restart_work;
 	struct mutex mutex;	/* For modem commands */
 	ktime_t last_update;
@@ -76,6 +79,7 @@ int motmdm_gnss_send_command(struct motmdm_gnss_data *ddata,
 	unsigned char cmd[128];
 	int ret, cmdlen;
 
+	printk("send_command\n");
 	cmdlen = len + 5 + 1;
 	if (cmdlen > 128)
 		return -EINVAL;
@@ -84,23 +88,31 @@ int motmdm_gnss_send_command(struct motmdm_gnss_data *ddata,
 	memset(ddata->buf, 0, ddata->len);
 	ddata->parsed = false;
 	snprintf(cmd, cmdlen, "U%04li%s", jiffies % 10000, buf);
-	ret = serdev_ngsm_write(ddata->modem, &ddata->dlci, cmd, cmdlen);
+	printk("serdev_write\n");
+	
+	ret = serdev_device_write(ddata->serdev, cmd, cmdlen, MAX_SCHEDULE_TIMEOUT);
 	if (ret < 0)
 		goto out_unlock;
 
+	printk("wait event\n");
 	ret = wait_event_timeout(ddata->read_queue, ddata->parsed,
 				 msecs_to_jiffies(timeout_ms));
 	if (ret == 0) {
 		ret = -ETIMEDOUT;
+		printk("...timeout FIXME\n");
+		ret = 0;
 		goto out_unlock;
 	} else if (ret < 0) {
+		printk("...error FIXME\n");
+		ret = 0;
 		goto out_unlock;
 	}
 
 	if (!strstr(ddata->buf, ":OK")) {
 		dev_err(&gdev->dev, "command %s error %s\n",
 			cmd, ddata->buf);
-		ret = -EPIPE;
+		printk("did not get ok\n");
+		//ret = -EPIPE;
 	}
 
 	ret = len;
@@ -198,7 +210,7 @@ static int motmdm_gnss_finish(struct gnss_device *gdev)
 	return motmdm_gnss_send_command(ddata, cmd, strlen(cmd));
 }
 
-static int motmdm_gnss_receive_data(struct gsm_serdev_dlci *dlci,
+static int motmdm_gnss_receive_data(struct gsm_serdev_dlci_operations *dlci,
 				    const unsigned char *buf,
 				    size_t len)
 {
@@ -208,6 +220,8 @@ static int motmdm_gnss_receive_data(struct gsm_serdev_dlci *dlci,
 	size_t msglen;
 	int error = 0;
 
+	printk("motmdm_gnss_receive_data\n");
+
 	if (len <= MOTMDM_GNSS_RESP_LEN)
 		return 0;
 
@@ -283,19 +297,21 @@ static int motmdm_gnss_receive_data(struct gsm_serdev_dlci *dlci,
 static int motmdm_gnss_open(struct gnss_device *gdev)
 {
 	struct motmdm_gnss_data *ddata = gnss_get_drvdata(gdev);
-	struct gsm_serdev_dlci *dlci = &ddata->dlci;
+//	struct gsm_serdev_dlci_operations *dlci = &ddata->dlci;
 	int error;
 
+#if 0
 	dlci->drvdata = gdev;
 	dlci->receive_buf = motmdm_gnss_receive_data;
 
 	error = serdev_ngsm_register_dlci(ddata->modem, dlci);
 	if (error)
 		return error;
+#endif
 
 	error = motmdm_gnss_init(gdev);
 	if (error) {
-		serdev_ngsm_unregister_dlci(ddata->modem, dlci);
+//		serdev_ngsm_unregister_dlci(ddata->modem, dlci);
 
 		return error;
 	}
@@ -306,9 +322,10 @@ static int motmdm_gnss_open(struct gnss_device *gdev)
 static void motmdm_gnss_close(struct gnss_device *gdev)
 {
 	struct motmdm_gnss_data *ddata = gnss_get_drvdata(gdev);
-	struct gsm_serdev_dlci *dlci = &ddata->dlci;
+//	struct gsm_serdev_dlci_operations *dlci = &ddata->dlci;
 	int error;
 
+#if 0
 	dlci->receive_buf = NULL;
 	error = motmdm_gnss_finish(gdev);
 	if (error < 0)
@@ -316,15 +333,18 @@ static void motmdm_gnss_close(struct gnss_device *gdev)
 			 __func__, error);
 
 	serdev_ngsm_unregister_dlci(ddata->modem, dlci);
+#endif
 }
 
 static int motmdm_gnss_write_raw(struct gnss_device *gdev,
 				 const unsigned char *buf,
 				 size_t count)
 {
+#if 0
 	struct motmdm_gnss_data *ddata = gnss_get_drvdata(gdev);
 
 	return serdev_ngsm_write(ddata->modem, &ddata->dlci, buf, count);
+#endif
 }
 
 static const struct gnss_operations motmdm_gnss_ops = {
@@ -333,26 +353,78 @@ static const struct gnss_operations motmdm_gnss_ops = {
 	.write_raw	= motmdm_gnss_write_raw,
 };
 
-static int motmdm_gnss_probe(struct platform_device *pdev)
+static int gnss_serial_receive_buf(struct serdev_device *serdev,
+                                        const unsigned char *buf, size_t count)
+{
+	struct motmdm_gnss_data *ddata = serdev_device_get_drvdata(serdev);
+	struct gnss_device *gdev = ddata->gdev;
+	
+	printk("gnss_serial_recieve: %d bytes\n", count);
+	printk("gnss_serial_recieve: have data: %s bytes\n", buf);
+
+	return gnss_insert_raw(gdev, buf, count);
+}
+
+static const struct serdev_device_ops gnss_serial_serdev_ops = {
+        .receive_buf    = gnss_serial_receive_buf,
+        .write_wakeup   = serdev_device_write_wakeup,
+};
+
+
+int motmdm_gnss_test(struct serdev_device *serdev)
 {
-	struct device *dev = &pdev->dev;
+	int ret;
+	if (!serdev)
+		return -EIO;
+	printk("have serdev_device: %p, nr %d\n", serdev, serdev->nr);
+
+	dev_info(&serdev->dev, "interesting line, testing\n");
+	
+	/* HERE */
+        serdev_device_set_client_ops(serdev, &gnss_serial_serdev_ops);
+
+	dev_info(&serdev->dev, "opening serdev\n");
+	ret = serdev_device_open(serdev);
+        if (ret) {
+                return ret;
+	}
+
+//        serdev_device_set_baudrate(serdev, gserial->speed);
+//        serdev_device_set_flow_control(serdev, false);
+	dev_info(&serdev->dev, "writing\n");
+	
+	{
+		int count = 5;
+		ret = serdev_device_write(serdev, "HELLO", count, MAX_SCHEDULE_TIMEOUT);
+		if (ret < 0 || ret < count)
+			return ret;
+	}
+	dev_info(&serdev->dev, "waiting\n");
+	
+        serdev_device_wait_until_sent(serdev, 0);
+	dev_info(&serdev->dev, "all ok\n");
+	
+	return 0;
+}
+
+static int motmdm_gnss_probe(struct serdev_device *serdev)
+{
+	struct device *dev = &serdev->dev;
 	struct motmdm_gnss_data *ddata;
 	struct gnss_device *gdev;
 	u32 line;
 	int ret;
 
+	printk("gnss_probe\n");
+
 	ddata = devm_kzalloc(dev, sizeof(*ddata), GFP_KERNEL);
 	if (!ddata)
 		return -ENOMEM;
 
-	ret = of_property_read_u32(dev->of_node, "reg", &line);
-	if (ret)
-		return ret;
-
-	if (!line)
-		return -EINVAL;
+	printk("gnss_probe: searching for reg\n");
+	motmdm_gnss_test(serdev);
 
-	ddata->dlci.line = line;
+	ddata->serdev = serdev;
 	ddata->modem = dev->parent;
 	ddata->len = PAGE_SIZE;
 	mutex_init(&ddata->mutex);
@@ -363,7 +435,7 @@ static int motmdm_gnss_probe(struct platform_device *pdev)
 	if (!ddata->buf)
 		return -ENOMEM;
 
-	platform_set_drvdata(pdev, ddata);
+	serdev_device_set_drvdata(serdev, ddata);
 
 	gdev = gnss_allocate_device(dev);
 	if (!gdev)
@@ -386,14 +458,12 @@ static int motmdm_gnss_probe(struct platform_device *pdev)
 	return ret;
 }
 
-static int motmdm_gnss_remove(struct platform_device *pdev)
+static void motmdm_gnss_remove(struct serdev_device *serdev)
 {
-	struct motmdm_gnss_data *data = platform_get_drvdata(pdev);
+	struct motmdm_gnss_data *data = serdev_device_get_drvdata(serdev);
 
 	gnss_deregister_device(data->gdev);
 	gnss_put_device(data->gdev);
-
-	return 0;
 };
 
 #ifdef CONFIG_OF
@@ -404,7 +474,7 @@ static const struct of_device_id motmdm_gnss_of_match[] = {
 MODULE_DEVICE_TABLE(of, motmdm_gnss_of_match);
 #endif
 
-static struct platform_driver motmdm_gnss_driver = {
+static struct serdev_device_driver motmdm_gnss_driver = {
 	.driver	= {
 		.name		= "gnss-mot-mdm6600",
 		.of_match_table	= of_match_ptr(motmdm_gnss_of_match),
@@ -412,7 +482,7 @@ static struct platform_driver motmdm_gnss_driver = {
 	.probe	= motmdm_gnss_probe,
 	.remove	= motmdm_gnss_remove,
 };
-module_platform_driver(motmdm_gnss_driver);
+module_serdev_device_driver(motmdm_gnss_driver);
 
 MODULE_AUTHOR("Tony Lindgren <tony@atomide.com>");
 MODULE_DESCRIPTION("Motorola Mapphone MDM6600 GNSS receiver driver");
diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c
index 460123447fa1..00a5c8225973 100644
--- a/drivers/tty/n_gsm.c
+++ b/drivers/tty/n_gsm.c
@@ -52,14 +52,17 @@
 #include <linux/etherdevice.h>
 #include <linux/gsmmux.h>
 #include <linux/serdev-gsm.h>
+#include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
 
 static int debug;
 module_param(debug, int, 0600);
 
 /* Defaults: these are from the specification */
 
-#define T1	10		/* 100mS */
-#define T2	34		/* 333mS */
+#define T1	10		/* 100ms */
+#define T2	34		/* 333ms */
 #define N2	3		/* Retry 3 times */
 
 /* Use long timers for testing at low speed with debug on */
@@ -152,7 +155,7 @@ struct gsm_dlci {
 	/* Data handling callback */
 	void (*data)(struct gsm_dlci *dlci, const u8 *data, int len);
 	void (*prev_data)(struct gsm_dlci *dlci, const u8 *data, int len);
-	struct gsm_serdev_dlci *ops; /* serdev dlci ops, if used */
+	struct gsm_serdev_dlci_operations *ops; /* serdev dlci ops, if used */
 	struct net_device *net; /* network interface, if created */
 };
 
@@ -591,7 +594,8 @@ static void gsm_send(struct gsm_mux *gsm, int addr, int cr, int control)
 		WARN_ON(1);
 		return;
 	}
-	gsm->output(gsm, cbuf, len);
+	if (gsm->output)
+		gsm->output(gsm, cbuf, len);
 	gsm_print_packet("-->", addr, cr, control, NULL, 0);
 }
 
@@ -691,7 +695,7 @@ static void gsm_data_kick(struct gsm_mux *gsm, struct gsm_dlci *dlci)
 			print_hex_dump_bytes("gsm_data_kick: ",
 					     DUMP_PREFIX_OFFSET,
 					     gsm->txframe, len);
-		if (gsm->output(gsm, gsm->txframe, len) < 0)
+		if (gsm->output && gsm->output(gsm, gsm->txframe, len) < 0)
 			break;
 		/* FIXME: Can eliminate one SOF in many more cases */
 		gsm->tx_bytes -= msg->len;
@@ -1019,7 +1023,7 @@ static void gsm_control_reply(struct gsm_mux *gsm, int cmd, const u8 *data,
 static void gsm_process_modem(struct tty_struct *tty, struct gsm_dlci *dlci,
 							u32 modem, int clen)
 {
-	int  mlines = 0;
+	int mlines = 0;
 	u8 brk = 0;
 	int fc;
 
@@ -2344,38 +2348,11 @@ static int gsm_config(struct gsm_mux *gsm, struct gsm_config *c)
 }
 
 #ifdef CONFIG_SERIAL_DEV_BUS
-
-/**
- * gsm_serdev_get_config - read ts 27.010 config
- * @gsd:	serdev-gsm instance
- * @c:		ts 27.010 config data
- *
- * See gsm_copy_config_values() for more information.
- */
-int gsm_serdev_get_config(struct gsm_serdev *gsd, struct gsm_config *c)
-{
-	struct gsm_mux *gsm;
-
-	if (!gsd || !gsd->gsm)
-		return -ENODEV;
-
-	gsm = gsd->gsm;
-
-	if (!c)
-		return -EINVAL;
-
-	gsm_copy_config_values(gsm, c);
-
-	return 0;
-}
-EXPORT_SYMBOL_GPL(gsm_serdev_get_config);
-
+#if 1
 /**
  * gsm_serdev_set_config - set ts 27.010 config
  * @gsd:	serdev-gsm instance
  * @c:		ts 27.010 config data
- *
- * See gsm_config() for more information.
  */
 int gsm_serdev_set_config(struct gsm_serdev *gsd, struct gsm_config *c)
 {
@@ -2393,6 +2370,7 @@ int gsm_serdev_set_config(struct gsm_serdev *gsd, struct gsm_config *c)
 }
 EXPORT_SYMBOL_GPL(gsm_serdev_set_config);
 
+#endif
 static struct gsm_dlci *gsd_dlci_get(struct gsm_serdev *gsd, int line,
 				     bool allocate)
 {
@@ -2404,7 +2382,7 @@ static struct gsm_dlci *gsd_dlci_get(struct gsm_serdev *gsd, int line,
 
 	gsm = gsd->gsm;
 
-	if (line < 1 || line >= 63)
+	if (line < 1 || line >= 62)
 		return ERR_PTR(-EINVAL);
 
 	mutex_lock(&gsm->mutex);
@@ -2431,7 +2409,8 @@ static struct gsm_dlci *gsd_dlci_get(struct gsm_serdev *gsd, int line,
 	return dlci;
 }
 
-static int gsd_dlci_receive_buf(struct gsm_serdev_dlci *ops,
+#if 1
+static int gsd_dlci_receive_buf(struct gsm_serdev_dlci_operations *ops,
 				const unsigned char *buf,
 				size_t len)
 {
@@ -2449,6 +2428,7 @@ static int gsd_dlci_receive_buf(struct gsm_serdev_dlci *ops,
 
 	return len;
 }
+#endif
 
 static void gsd_dlci_data(struct gsm_dlci *dlci, const u8 *buf, int len)
 {
@@ -2471,58 +2451,6 @@ static void gsd_dlci_data(struct gsm_dlci *dlci, const u8 *buf, int len)
 	}
 }
 
-/**
- * gsm_serdev_write - write data to a ts 27.010 channel
- * @gsd:	serdev-gsm instance
- * @ops:	channel ops
- * @buf:	write buffer
- * @len:	buffer length
- */
-int gsm_serdev_write(struct gsm_serdev *gsd, struct gsm_serdev_dlci *ops,
-		     const u8 *buf, int len)
-{
-	struct gsm_mux *gsm;
-	struct gsm_dlci *dlci;
-	struct gsm_msg *msg;
-	int h, size, total_size = 0;
-	u8 *dp;
-
-	if (!gsd || !gsd->gsm)
-		return -ENODEV;
-
-	gsm = gsd->gsm;
-
-	dlci = gsd_dlci_get(gsd, ops->line, false);
-	if (IS_ERR(dlci))
-		return PTR_ERR(dlci);
-
-	h = dlci->adaption - 1;
-
-	if (len > gsm->mtu)
-		len = gsm->mtu;
-
-	size = len + h;
-
-	msg = gsm_data_alloc(gsm, dlci->addr, size, gsm->ftype);
-	if (!msg)
-		return -ENOMEM;
-
-	dp = msg->data;
-	switch (dlci->adaption) {
-	case 1:
-		break;
-	case 2:
-		*dp++ = gsm_encode_modem(dlci);
-		break;
-	}
-	memcpy(dp, buf, len);
-	gsm_data_queue(dlci, msg);
-	total_size += size;
-
-	return total_size;
-}
-EXPORT_SYMBOL_GPL(gsm_serdev_write);
-
 /**
  * gsm_serdev_data_kick - indicate more data can be transmitted
  * @gsd:	serdev-gsm instance
@@ -2545,13 +2473,14 @@ void gsm_serdev_data_kick(struct gsm_serdev *gsd)
 }
 EXPORT_SYMBOL_GPL(gsm_serdev_data_kick);
 
+#if 1
 /**
  * gsm_serdev_register_dlci - register a ts 27.010 channel
  * @gsd:	serdev-gsm instance
  * @ops:	channel ops
  */
 int gsm_serdev_register_dlci(struct gsm_serdev *gsd,
-			     struct gsm_serdev_dlci *ops)
+			     struct gsm_serdev_dlci_operations *ops)
 {
 	struct gsm_dlci *dlci;
 	struct gsm_mux *gsm;
@@ -2578,7 +2507,7 @@ int gsm_serdev_register_dlci(struct gsm_serdev *gsd,
 	dlci->ops = ops;
 	dlci->modem_rx = 0;
 	dlci->prev_data = dlci->data;
-	dlci->data = gsd_dlci_data;
+	dlci->data = gsd_dlci_data; /* FIXME: do we want this? */
 	mutex_unlock(&dlci->mutex);
 
 	gsm_dlci_begin_open(dlci);
@@ -2609,7 +2538,7 @@ EXPORT_SYMBOL_GPL(gsm_serdev_register_dlci);
  * @ops:	channel ops
  */
 void gsm_serdev_unregister_dlci(struct gsm_serdev *gsd,
-				struct gsm_serdev_dlci *ops)
+				struct gsm_serdev_dlci_operations *ops)
 {
 	struct gsm_mux *gsm;
 	struct gsm_dlci *dlci;
@@ -2636,6 +2565,7 @@ void gsm_serdev_unregister_dlci(struct gsm_serdev *gsd,
 	gsm_dlci_begin_close(dlci);
 }
 EXPORT_SYMBOL_GPL(gsm_serdev_unregister_dlci);
+#endif
 
 static int gsm_serdev_output(struct gsm_mux *gsm, u8 *data, int len)
 {
@@ -2647,6 +2577,7 @@ static int gsm_serdev_output(struct gsm_mux *gsm, u8 *data, int len)
 		return serdev_device_write_buf(serdev, data, len);
 }
 
+#if 1
 static int gsd_receive_buf(struct serdev_device *serdev, const u8 *data,
 			   size_t count)
 {
@@ -2680,13 +2611,18 @@ static struct serdev_device_ops gsd_client_ops = {
 	.receive_buf = gsd_receive_buf,
 	.write_wakeup = gsd_write_wakeup,
 };
+#endif
+
+extern int motmdm_gnss_attach(struct device *dev, int line);
 
 int gsm_serdev_register_tty_port(struct gsm_serdev *gsd, int line)
 {
-	struct gsm_serdev_dlci *ops;
+	struct gsm_serdev_dlci_operations *ops;
 	unsigned int base;
 	int error;
-
+	struct device *dev;
+	struct device_node *node;
+		
 	if (line < 1)
 		return -EINVAL;
 
@@ -2704,8 +2640,83 @@ int gsm_serdev_register_tty_port(struct gsm_serdev *gsd, int line)
 		return error;
 	}
 
+
 	base = mux_num_to_base(gsd->gsm);
-	tty_register_device(gsm_tty_driver, base + ops->line, NULL);
+	printk("register_tty_port: have port: %p, %d+%d\n", &gsd->gsm->dlci[line]->port, base, ops->line);
+	dev = &gsd->serdev->dev;
+	if (line != 1)
+		return 0;
+
+	for_each_available_child_of_node(dev->of_node, node) {
+		struct platform_device_info devinfo = {};
+		static int idx;
+		struct platform_device *pdev;
+		const char *c = of_get_property(node, "compatible", NULL);
+		
+		dev_info(dev, "register_tty: child -- %pOF\n", node);
+
+		if (!c)
+			continue;
+		dev_info(dev, "register_tty: child -- %pOF -- compatible %s\n", node, c);
+		if (strcmp(c, "gsmmux,port"))
+			continue;
+
+		printk("n_gsm: Have subnode with right compatible!\n");
+		
+		devinfo.name = kasprintf(GFP_KERNEL, "gsm-mux-%d", idx++);
+		devinfo.parent = dev;
+
+		/* Thanks to core.c: serdev_device_add */
+		pdev = platform_device_register_full(&devinfo);
+		pdev->dev.of_node = node;
+
+#if 0
+		tty_register_device(gsm_tty_driver, base + ops->line, NULL);
+#else
+		{
+			struct device *dev;
+
+			dev = tty_port_register_device_serdev(&gsd->gsm->dlci[line]->port, gsm_tty_driver, base + ops->line, &pdev->dev /* FIXME: needs non-null to attempt serdev registration */ );
+			printk("register_tty_port: got %p\n", dev);
+			{
+#if 0
+				struct serdev_controller *ctrl = to_serdev_controller(dev);
+				struct serdev_device *serdev = serdev_device_alloc(ctrl);
+				int err;
+				if (!serdev)
+					dev_err(dev, "could not alloc serdev, that is bad\n");
+
+				//serdev->dev.of_node = node;
+
+				err = serdev_device_add(serdev);
+				if (err) {
+					dev_err(&serdev->dev,
+						"failure adding device. status %pe\n",
+						ERR_PTR(err));
+					//serdev_device_put(serdev);
+				}
+#endif
+#if 0
+				printk("register_tty_port: Forcing attach\n");
+				/* FIXME: Need to do of_serdev_register_devices() ? */
+				motmdm_gnss_attach(dev, ops->line);
+#endif
+			}
+
+		}
+	}
+#endif
+	/* FIXME:
+
+extern struct device *tty_register_device(struct tty_driver *driver,
+                                          unsigned index, struct device *dev);
+
+Would like tty_port_register_device_attr or better
+	   	       tty_port_register_device_attr_serdev 
+
+ale chce navic struct tty_port *.
+
+		       _attr() -- last 2 arguments can be NULL. */
 
 	return 0;
 }
@@ -2730,29 +2741,14 @@ void gsm_serdev_unregister_tty_port(struct gsm_serdev *gsd, int line)
 }
 EXPORT_SYMBOL_GPL(gsm_serdev_unregister_tty_port);
 
-struct gsm_serdev_dlci *
-gsm_serdev_tty_port_get_dlci(struct gsm_serdev *gsd, int line)
-{
-	struct gsm_dlci *dlci;
-
-	if (line < 1)
-		return NULL;
-
-	dlci = gsd_dlci_get(gsd, line, false);
-	if (IS_ERR(dlci))
-		return NULL;
-
-	return dlci->ops;
-}
-EXPORT_SYMBOL_GPL(gsm_serdev_tty_port_get_dlci);
-
+#if 1
 int gsm_serdev_register_device(struct gsm_serdev *gsd)
 {
 	struct gsm_mux *gsm;
 	int error;
 
-	if (WARN(!gsd || !gsd->serdev || !gsd->output,
-		 "serdev and output must be initialized\n"))
+	if (WARN(!gsd || !gsd->serdev,
+		 "serdev must be initialized\n"))
 		return -EINVAL;
 
 	serdev_device_set_client_ops(gsd->serdev, &gsd_client_ops);
@@ -2787,7 +2783,7 @@ void gsm_serdev_unregister_device(struct gsm_serdev *gsd)
 	gsd->gsm = NULL;
 }
 EXPORT_SYMBOL_GPL(gsm_serdev_unregister_device);
-
+#endif
 #endif	/* CONFIG_SERIAL_DEV_BUS */
 
 /**
@@ -3644,7 +3640,7 @@ static int gsmtty_break_ctl(struct tty_struct *tty, int state)
 				    properly */
 		encode = 0x0F;
 	else if (state > 0) {
-		encode = state / 200;	/* mS to encoding */
+		encode = state / 200;	/* ms to encoding */
 		if (encode > 0x0F)
 			encode = 0x0F;	/* Best effort */
 	}
diff --git a/drivers/tty/serdev/core.c b/drivers/tty/serdev/core.c
index c5f0d936b003..081702d5479d 100644
--- a/drivers/tty/serdev/core.c
+++ b/drivers/tty/serdev/core.c
@@ -121,7 +121,7 @@ int serdev_device_add(struct serdev_device *serdev)
 		goto err_clear_serdev;
 	}
 
-	dev_dbg(&serdev->dev, "device %s registered\n", dev_name(&serdev->dev));
+	dev_info(&serdev->dev, "device %s registered, %p controller %p\n", dev_name(&serdev->dev), serdev, ctrl);
 
 	return 0;
 
@@ -509,7 +509,15 @@ struct serdev_controller *serdev_controller_alloc(struct device *parent,
 	pm_runtime_no_callbacks(&ctrl->dev);
 	pm_suspend_ignore_children(&ctrl->dev, true);
 
-	dev_dbg(&ctrl->dev, "allocated controller 0x%p id %d\n", ctrl, id);
+	/* /sys/bus/serial/drivers/serdev_ngsm/serial0-0 ?
+
+4806a000.serial:modem:audio-codec@2  modalias  subsystem
+4806a000.serial:modem:gnss@4	     of_node   supplier:phy-usb-phy@1.1
+driver				     power     uevent
+
+	*/
+	dev_info(&ctrl->dev, "allocated controller 0x%p 0x%p id %d [%d]\n",
+		 ctrl, &ctrl->dev, id, ctrl->nr);
 	return ctrl;
 
 err_free:
@@ -527,10 +535,12 @@ static int of_serdev_register_devices(struct serdev_controller *ctrl)
 	bool found = false;
 
 	for_each_available_child_of_node(ctrl->dev.of_node, node) {
+		dev_info(&ctrl->dev, "of_serdev_register_device: considering %pOF\n", node);
+		
 		if (!of_get_property(node, "compatible", NULL))
 			continue;
 
-		dev_dbg(&ctrl->dev, "adding child %pOF\n", node);
+		dev_info(&ctrl->dev, "adding child %pOF\n", node);
 
 		serdev = serdev_device_alloc(ctrl);
 		if (!serdev)
@@ -740,26 +750,34 @@ int serdev_controller_add(struct serdev_controller *ctrl)
 {
 	int ret_of, ret_acpi, ret;
 
+	printk("serdev_controller_add...\n");
+
 	/* Can't register until after driver model init */
 	if (WARN_ON(!is_registered))
 		return -EAGAIN;
 
+	printk("serdev_controller_add 1... %pOF\n", ctrl->dev.of_node);
+	
 	ret = device_add(&ctrl->dev);
 	if (ret)
 		return ret;
 
+	printk("serdev_controller_add 2...\n");	
 	pm_runtime_enable(&ctrl->dev);
 
 	ret_of = of_serdev_register_devices(ctrl);
 	ret_acpi = acpi_serdev_register_devices(ctrl);
 	if (ret_of && ret_acpi) {
-		dev_dbg(&ctrl->dev, "no devices registered: of:%pe acpi:%pe\n",
+		dev_info(&ctrl->dev, "no devices registered: of:%pe acpi:%pe\n",
 			ERR_PTR(ret_of), ERR_PTR(ret_acpi));
+#if 0
 		ret = -ENODEV;
 		goto err_rpm_disable;
+#endif		
 	}
 
-	dev_dbg(&ctrl->dev, "serdev%d registered: dev:%p\n",
+	printk("serdev_controller_add all ok?...\n");		
+	dev_info(&ctrl->dev, "serdev%d registered: dev:%p\n",
 		ctrl->nr, &ctrl->dev);
 	return 0;
 
diff --git a/drivers/tty/serdev/serdev-ngsm.c b/drivers/tty/serdev/serdev-ngsm.c
index a247cf36df4f..e8db5cc5b19d 100644
--- a/drivers/tty/serdev/serdev-ngsm.c
+++ b/drivers/tty/serdev/serdev-ngsm.c
@@ -40,7 +40,7 @@ struct serdev_ngsm {
 	const struct serdev_ngsm_cfg *cfg;
 };
 
-static int serdev_ngsm_tty_init(struct serdev_ngsm *ddata)
+static int serdev_ngsm_tty_init(struct serdev_ngsm *ddata, void *node /* will need of node here ? */)
 {
 	struct gsm_serdev *gsd = &ddata->gsd;
 	struct device *dev = ddata->dev;
@@ -50,7 +50,7 @@ static int serdev_ngsm_tty_init(struct serdev_ngsm *ddata)
 		if (BIT_ULL(bit) & TS27010_RESERVED_DLCI)
 			continue;
 
-		err = gsm_serdev_register_tty_port(gsd, bit);
+		err = gsm_serdev_register_tty_port(gsd, bit /*, node FIXME */);
 		if (err) {
 			dev_err(dev, "ngsm tty init failed for dlci%i: %i\n",
 				bit, err);
@@ -74,69 +74,6 @@ static void serdev_ngsm_tty_exit(struct serdev_ngsm *ddata)
 	}
 }
 
-/*
- * Note that we rely on gsm_serdev_register_dlci() locking for
- * reserved channels that serdev_ngsm_tty_init() and consumer
- * drivers may have already reserved.
- */
-int serdev_ngsm_register_dlci(struct device *dev,
-			      struct gsm_serdev_dlci *dlci)
-{
-	struct serdev_ngsm *ddata = gsm_serdev_get_drvdata(dev);
-	struct gsm_serdev *gsd = &ddata->gsd;
-	int err;
-
-	err = gsm_serdev_register_dlci(gsd, dlci);
-	if (err)
-		return err;
-
-	return 0;
-}
-EXPORT_SYMBOL_GPL(serdev_ngsm_register_dlci);
-
-void serdev_ngsm_unregister_dlci(struct device *dev,
-				 struct gsm_serdev_dlci *dlci)
-{
-	struct serdev_ngsm *ddata = gsm_serdev_get_drvdata(dev);
-	struct gsm_serdev *gsd = &ddata->gsd;
-
-	gsm_serdev_unregister_dlci(gsd, dlci);
-}
-EXPORT_SYMBOL_GPL(serdev_ngsm_unregister_dlci);
-
-int serdev_ngsm_write(struct device *dev, struct gsm_serdev_dlci *ops,
-		      const u8 *buf, int len)
-{
-	struct serdev_ngsm *ddata = gsm_serdev_get_drvdata(dev);
-	struct gsm_serdev *gsd = &ddata->gsd;
-	int ret;
-
-	ret = pm_runtime_get_sync(dev);
-	if ((ret != -EINPROGRESS) && ret < 0) {
-		pm_runtime_put_noidle(dev);
-
-		return ret;
-	}
-
-	ret = gsm_serdev_write(gsd, ops, buf, len);
-
-	pm_runtime_mark_last_busy(dev);
-	pm_runtime_put_autosuspend(dev);
-
-	return ret;
-}
-EXPORT_SYMBOL_GPL(serdev_ngsm_write);
-
-struct gsm_serdev_dlci *
-serdev_ngsm_get_dlci(struct device *dev, int line)
-{
-	struct serdev_ngsm *ddata = gsm_serdev_get_drvdata(dev);
-	struct gsm_serdev *gsd = &ddata->gsd;
-
-	return gsm_serdev_tty_port_get_dlci(gsd, line);
-}
-EXPORT_SYMBOL_GPL(serdev_ngsm_get_dlci);
-
 static int serdev_ngsm_set_config(struct device *dev)
 {
 	struct serdev_ngsm *ddata = gsm_serdev_get_drvdata(dev);
@@ -164,6 +101,7 @@ static int serdev_ngsm_set_config(struct device *dev)
 	return 0;
 }
 
+#if 1
 static int serdev_ngsm_output(struct gsm_serdev *gsd, u8 *data, int len)
 {
 	struct serdev_device *serdev = gsd->serdev;
@@ -183,6 +121,7 @@ static int serdev_ngsm_output(struct gsm_serdev *gsd, u8 *data, int len)
 
 	return len;
 }
+#endif
 
 static int serdev_ngsm_runtime_suspend(struct device *dev)
 {
@@ -227,7 +166,6 @@ static const struct dev_pm_ops serdev_ngsm_pm_ops = {
 			   serdev_ngsm_runtime_resume,
 			   NULL)
 };
-
 /*
  * At least Motorola MDM6600 devices have GPIO wake pins shared between the
  * USB PHY and the TS 27.010 interface. So for PM, we need to use the calls
@@ -327,7 +265,8 @@ static int serdev_ngsm_probe(struct serdev_device *serdev)
 
 	gsd = &ddata->gsd;
 	gsd->serdev = serdev;
-	gsd->output = serdev_ngsm_output;
+	gsd->output = serdev_ngsm_output; /* This is real-serial line to gsm direction; 
+					     we want to keep it */
 	serdev_device_set_drvdata(serdev, gsd);
 	gsm_serdev_set_drvdata(dev, ddata);
 
@@ -377,7 +316,7 @@ static int serdev_ngsm_probe(struct serdev_device *serdev)
 	if (err)
 		goto err_close;
 
-	err = serdev_ngsm_tty_init(ddata);
+	err = serdev_ngsm_tty_init(ddata, NULL /* FIXME! */);
 	if (err)
 		goto err_tty;
 
diff --git a/drivers/tty/serdev/serdev-ttyport.c b/drivers/tty/serdev/serdev-ttyport.c
index d367803e2044..6f02a1546560 100644
--- a/drivers/tty/serdev/serdev-ttyport.c
+++ b/drivers/tty/serdev/serdev-ttyport.c
@@ -272,6 +272,8 @@ struct device *serdev_tty_port_register(struct tty_port *port,
 	if (!port || !drv || !parent)
 		return ERR_PTR(-ENODEV);
 
+	printk("serdev_tty_port_register: %p, %d\n", port, idx);
+
 	ctrl = serdev_controller_alloc(parent, sizeof(struct serport));
 	if (!ctrl)
 		return ERR_PTR(-ENOMEM);
@@ -291,9 +293,12 @@ struct device *serdev_tty_port_register(struct tty_port *port,
 		goto err_reset_data;
 
 	dev_info(&ctrl->dev, "tty port %s%d registered\n", drv->name, idx);
+	printk("serdev_tty_port_register: controller is  %p, serdev %p\n", ctrl, ctrl->serdev);
+	
 	return &ctrl->dev;
 
 err_reset_data:
+	printk("serdev_tty_port_register: error?\n");
 	port->client_data = NULL;
 	port->client_ops = &tty_port_default_client_ops;
 	serdev_controller_put(ctrl);
diff --git a/include/linux/serdev-gsm.h b/include/linux/serdev-gsm.h
index 4fa819a6e366..5bdc8143b7df 100644
--- a/include/linux/serdev-gsm.h
+++ b/include/linux/serdev-gsm.h
@@ -7,7 +7,7 @@
 #include <linux/serdev.h>
 #include <linux/types.h>
 
-struct gsm_serdev_dlci;
+struct gsm_serdev_dlci_operations;
 struct gsm_config;
 
 /**
@@ -28,16 +28,16 @@ struct gsm_serdev {
 };
 
 /**
- * struct gsm_serdev_dlci - serdev-gsm ts 27.010 channel data
+ * struct gsm_serdev_dlci_operations - serdev-gsm ts 27.010 channel data
  * @gsd:		serdev-gsm instance
  * @line:		ts 27.010 channel, control channel 0 is not available
  * @receive_buf:	function to handle data received for the channel
  * @drvdata:		dlci specific consumer driver data
  */
-struct gsm_serdev_dlci {
+struct gsm_serdev_dlci_operations {
 	struct gsm_serdev *gsd;
 	int line;
-	int (*receive_buf)(struct gsm_serdev_dlci *ops,
+	int (*receive_buf)(struct gsm_serdev_dlci_operations *ops,
 			   const unsigned char *buf,
 			   size_t len);
 	void *drvdata;
@@ -48,12 +48,12 @@ struct gsm_serdev_dlci {
 /* TS 27.010 channel specific functions for consumer drivers */
 #if IS_ENABLED(CONFIG_SERIAL_DEV_N_GSM)
 extern int
-serdev_ngsm_register_dlci(struct device *dev, struct gsm_serdev_dlci *dlci);
+serdev_ngsm_register_dlci(struct device *dev, struct gsm_serdev_dlci_operations *dlci);
 extern void serdev_ngsm_unregister_dlci(struct device *dev,
-					struct gsm_serdev_dlci *dlci);
-extern int serdev_ngsm_write(struct device *dev, struct gsm_serdev_dlci *ops,
+					struct gsm_serdev_dlci_operations *dlci);
+extern int serdev_ngsm_write(struct device *dev, struct gsm_serdev_dlci_operations *ops,
 			     const u8 *buf, int len);
-extern struct gsm_serdev_dlci *
+extern struct gsm_serdev_dlci_operations *
 serdev_ngsm_get_dlci(struct device *dev, int line);
 #endif
 
@@ -62,7 +62,7 @@ extern int gsm_serdev_register_device(struct gsm_serdev *gsd);
 extern void gsm_serdev_unregister_device(struct gsm_serdev *gsd);
 extern int gsm_serdev_register_tty_port(struct gsm_serdev *gsd, int line);
 extern void gsm_serdev_unregister_tty_port(struct gsm_serdev *gsd, int line);
-extern struct gsm_serdev_dlci *
+extern struct gsm_serdev_dlci_operations *
 gsm_serdev_tty_port_get_dlci(struct gsm_serdev *gsd, int line);
 
 static inline void *gsm_serdev_get_drvdata(struct device *dev)
@@ -88,10 +88,10 @@ static inline void gsm_serdev_set_drvdata(struct device *dev, void *drvdata)
 extern int gsm_serdev_get_config(struct gsm_serdev *gsd, struct gsm_config *c);
 extern int gsm_serdev_set_config(struct gsm_serdev *gsd, struct gsm_config *c);
 extern int
-gsm_serdev_register_dlci(struct gsm_serdev *gsd, struct gsm_serdev_dlci *ops);
+gsm_serdev_register_dlci(struct gsm_serdev *gsd, struct gsm_serdev_dlci_operations *ops);
 extern void
-gsm_serdev_unregister_dlci(struct gsm_serdev *gsd, struct gsm_serdev_dlci *ops);
-extern int gsm_serdev_write(struct gsm_serdev *gsd, struct gsm_serdev_dlci *ops,
+gsm_serdev_unregister_dlci(struct gsm_serdev *gsd, struct gsm_serdev_dlci_operations *ops);
+extern int gsm_serdev_write(struct gsm_serdev *gsd, struct gsm_serdev_dlci_operations *ops,
 			    const u8 *buf, int len);
 extern void gsm_serdev_data_kick(struct gsm_serdev *gsd);
 
@@ -118,7 +118,7 @@ void gsm_serdev_unregister_tty_port(struct gsm_serdev *gsd, int line)
 {
 }
 
-static inline struct gsm_serdev_dlci *
+static inline struct gsm_serdev_dlci_operations *
 gsm_serdev_tty_port_get_dlci(struct gsm_serdev *gsd, int line)
 {
 	return NULL;
@@ -148,19 +148,19 @@ int gsm_serdev_set_config(struct gsm_serdev *gsd, struct gsm_config *c)
 
 static inline
 int gsm_serdev_register_dlci(struct gsm_serdev *gsd,
-			     struct gsm_serdev_dlci *ops)
+			     struct gsm_serdev_dlci_operations *ops)
 {
 	return -ENODEV;
 }
 
 static inline
 void gsm_serdev_unregister_dlci(struct gsm_serdev *gsd,
-				struct gsm_serdev_dlci *ops)
+				struct gsm_serdev_dlci_operations *ops)
 {
 }
 
 static inline
-int gsm_serdev_write(struct gsm_serdev *gsd, struct gsm_serdev_dlci *ops,
+int gsm_serdev_write(struct gsm_serdev *gsd, struct gsm_serdev_dlci_operations *ops,
 		     const u8 *buf, int len)
 {
 	return -ENODEV;
diff --git a/include/linux/serdev.h b/include/linux/serdev.h
index 9f14f9c12ec4..efdffe34a9b5 100644
--- a/include/linux/serdev.h
+++ b/include/linux/serdev.h
@@ -128,6 +128,7 @@ static inline void serdev_device_set_drvdata(struct serdev_device *serdev, void
  */
 static inline void serdev_device_put(struct serdev_device *serdev)
 {
+	printk("serdev_device_put... %p\n", serdev);
 	if (serdev)
 		put_device(&serdev->dev);
 }
@@ -156,6 +157,8 @@ static inline void serdev_controller_set_drvdata(struct serdev_controller *ctrl,
  */
 static inline void serdev_controller_put(struct serdev_controller *ctrl)
 {
+	printk("serdev_controller_put... %p\n", ctrl);
+	WARN_ON(1);
 	if (ctrl)
 		put_device(&ctrl->dev);
 }
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index afb9521ddf91..530a0146893c 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -802,7 +802,7 @@ static char *ptr_to_id(char *buf, char *end, const void *ptr,
 	 * Print the real pointer value for NULL and error pointers,
 	 * as they are not actual addresses.
 	 */
-	if (IS_ERR_OR_NULL(ptr))
+//	if (IS_ERR_OR_NULL(ptr))
 		return pointer_string(buf, end, ptr, spec);
 
 	/* When debugging early boot use non-cryptographically secure hash. */
diff --git a/sound/soc/codecs/motmdm.c b/sound/soc/codecs/motmdm.c
index 325a860ef665..1528c89d9d57 100644
--- a/sound/soc/codecs/motmdm.c
+++ b/sound/soc/codecs/motmdm.c
@@ -28,7 +28,7 @@ struct motmdm_driver_data {
 	struct snd_soc_component *component;
 	struct snd_soc_dai *master_dai;
 	struct device *modem;
-	struct gsm_serdev_dlci dlci;
+	struct gsm_serdev_dlci_operations dlci;
 	struct regmap *regmap;
 	unsigned char *buf;
 	size_t len;
@@ -38,7 +38,7 @@ struct motmdm_driver_data {
 	struct mutex mutex;	/* for sending commands */
 	wait_queue_head_t read_queue;
 
-	int (*receive_buf_orig)(struct gsm_serdev_dlci *ops,
+	int (*receive_buf_orig)(struct gsm_serdev_dlci_operations *ops,
 				const unsigned char *buf,
 				size_t len);
 	unsigned int dtmf_val;
@@ -121,7 +121,7 @@ static int motmdm_send_command(struct motmdm_driver_data *ddata,
 }
 
 /* Handle U1234+XXXX= style command response */
-static int motmdm_receive_data(struct gsm_serdev_dlci *dlci,
+static int motmdm_receive_data(struct gsm_serdev_dlci_operations *dlci,
 			       const unsigned char *buf,
 			       size_t len)
 {
@@ -569,7 +569,7 @@ static void motmdm_voice_get_state(struct motmdm_driver_data *ddata,
 		motmdm_disable_primary_dai(ddata->component);
 }
 
-static int receive_buf_voice(struct gsm_serdev_dlci *ops,
+static int receive_buf_voice(struct gsm_serdev_dlci_operations *ops,
 			     const unsigned char *buf,
 			     size_t len)
 {
@@ -585,7 +585,7 @@ static int receive_buf_voice(struct gsm_serdev_dlci *ops,
 /* Read the voice status from dlci1 and let user space handle rest */
 static int motmdm_init_voice_dlci(struct motmdm_driver_data *ddata)
 {
-	struct gsm_serdev_dlci *dlci;
+	struct gsm_serdev_dlci_operations *dlci;
 
 	dlci = serdev_ngsm_get_dlci(ddata->modem, MOTMDM_VOICE_DLCI);
 	if (!dlci)
@@ -600,7 +600,7 @@ static int motmdm_init_voice_dlci(struct motmdm_driver_data *ddata)
 
 static void motmdm_free_voice_dlci(struct motmdm_driver_data *ddata)
 {
-	struct gsm_serdev_dlci *dlci;
+	struct gsm_serdev_dlci_operations *dlci;
 
 	dlci = serdev_ngsm_get_dlci(ddata->modem, MOTMDM_VOICE_DLCI);
 	if (!dlci)
@@ -613,7 +613,7 @@ static void motmdm_free_voice_dlci(struct motmdm_driver_data *ddata)
 static int motmdm_soc_probe(struct snd_soc_component *component)
 {
 	struct motmdm_driver_data *ddata;
-	struct gsm_serdev_dlci *dlci;
+	struct gsm_serdev_dlci_operations *dlci;
 	const unsigned char *cmd = "AT+CMUT=0";
 	int error;
 	u32 line;
@@ -690,7 +690,7 @@ static int motmdm_soc_probe(struct snd_soc_component *component)
 static void motmdm_soc_remove(struct snd_soc_component *component)
 {
 	struct motmdm_driver_data *ddata;
-	struct gsm_serdev_dlci *dlci;
+	struct gsm_serdev_dlci_operations *dlci;
 
 	ddata = snd_soc_component_get_drvdata(component);
 	dlci = &ddata->dlci;
diff --git a/sound/soc/generic/audio-graph-card.c b/sound/soc/generic/audio-graph-card.c
index 97b4f5480a31..31ff426226ef 100644
--- a/sound/soc/generic/audio-graph-card.c
+++ b/sound/soc/generic/audio-graph-card.c
@@ -631,6 +631,8 @@ static int graph_probe(struct platform_device *pdev)
 	struct link_info li;
 	int ret;
 
+	printk("audio-graph: probe starts\n");
+
 	/* Allocate the private data and the DAI link array */
 	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
 	if (!priv)
@@ -648,19 +650,24 @@ static int graph_probe(struct platform_device *pdev)
 	if (!li.link || !li.dais)
 		return -EINVAL;
 
+	printk("audio-graph: 2\n");
+
 	ret = asoc_simple_init_priv(priv, &li);
 	if (ret < 0)
 		return ret;
 
 	priv->pa_gpio = devm_gpiod_get_optional(dev, "pa", GPIOD_OUT_LOW);
 	if (IS_ERR(priv->pa_gpio)) {
+		printk("audio-graph: optional pa failed\n");
 		ret = PTR_ERR(priv->pa_gpio);
 		dev_err(dev, "failed to get amplifier gpio: %d\n", ret);
 		return ret;
 	}
 
+	printk("audio-graph: parsing of\n");	
 	ret = graph_parse_of(priv);
 	if (ret < 0) {
+		printk("audio-graph: parsing of failed: %d\n", ret);	
 		if (ret != -EPROBE_DEFER)
 			dev_err(dev, "parse error %d\n", ret);
 		goto err;
@@ -670,9 +677,13 @@ static int graph_probe(struct platform_device *pdev)
 
 	asoc_simple_debug_info(priv);
 
+		printk("audio-graph: registering card\n");	
+	
+
 	ret = devm_snd_soc_register_card(dev, card);
 	if (ret < 0)
 		goto err;
+		printk("audio-graph: all ok\n");	
 
 	return 0;
 err:


-- 
http://www.livejournal.com/~pavelmachek
Pavel Machek Dec. 24, 2020, 2:59 p.m. UTC | #2
Hi!

> > My notes say:
> > 
> > /dev/motmdm1 -- basic support, calls, on/off                                    
> > /dev/motmdm3 -- send sms interface                                              
> > /dev/motmdm9 -- receive sms interface                                           
> >
> > (and gsmtty numbering is same)
> 
> Yes I have not had a chance to look at these for several months now,
> but have the latest set in droid4-pending-v5.10 branch in my github
> tree.
> 
> The gnss device is at /dev/gsmtty6, see the current droid4-agps tool
> to upload the almanac also on github. That's has turned out to be a
> pretty good gsm serdev test too :)

Thanks a lot for the info! Is it this one?
https://github.com/tmlind/droid4-agps . GPS worked for me even w/o
AGPS support, but I broke even that, so I need to fix that first.

> > For now I converted gnss driver to use serdev interface, and n_gsm to
> > provide it... Not yet finished but I believe I'm walking in the right
> > direction.
> 
> Great, sounds good to me if you got things working with just serdev
> calls :) I'll try to take a look at this stuff again after I have
> the other pending droid4 issues out of the way like v5.12 charger
> and keyboard stuff.

Just ask for latest code :-). I still believe I'm going right
direction, but now I understand why you did it the way you did. Sound
code needs to listen on gsmtty1, with the data still being provided
for userspace.

Best regards,
								Pavel
Pavel Machek Jan. 2, 2021, 4:23 p.m. UTC | #3
Hi!

> > I'm afraid I'll need some more answers in near future, but for now:

> > 

> > Tony, do you remember / can you figure out what gsmtty GPS is on? I

> > never used it on that interface, and I can't seem to figure it out.

> > 

> > My notes say:

> > 

> > /dev/motmdm1 -- basic support, calls, on/off                                    

> > /dev/motmdm3 -- send sms interface                                              

> > /dev/motmdm9 -- receive sms interface                                           

> >

> > (and gsmtty numbering is same)

> 

> Yes I have not had a chance to look at these for several months now,

> but have the latest set in droid4-pending-v5.10 branch in my github

> tree.

> 

> The gnss device is at /dev/gsmtty6, see the current droid4-agps tool

> to upload the almanac also on github. That's has turned out to be a

> pretty good gsm serdev test too :)


Treason uncloaked!

While A-GPS is at gsmtty6 I guess, NMEA data are on gsmtty4. And I
could not access that one, due to bitmask reserving it for gnss.

But now I have figured it out, and should have something reviewable
soon.

Thanks for support,

								Pavel
-- 
http://www.livejournal.com/~pavelmachek