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

From: Pavel Machek
Date: Sun Dec 20 2020 - 17:50:07 EST


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@xxxxxxxxxxx>
+ * Copyright (C) 2020 Pavel Machek <pavel@xxxxxx>
*
* Based on drivers/gnss/sirf.c driver example:
* Copyright (C) 2018 Johan Hovold <johan@xxxxxxxxxx>
*/

+/* 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@xxxxxxxxxxx>");
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

Attachment: signature.asc
Description: PGP signature