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