* [PATCH 0/3] Add support for 'tty-slaves' described by devicetree. @ 2014-12-11 21:59 NeilBrown 2014-12-11 21:59 ` [PATCH 2/3] TTY: add slave driver to power-on device via a regulator NeilBrown ` (2 more replies) 0 siblings, 3 replies; 34+ messages in thread From: NeilBrown @ 2014-12-11 21:59 UTC (permalink / raw) To: Grant Likely, Greg Kroah-Hartman, Mark Rutland, Jiri Slaby Cc: devicetree, linux-kernel Greetings TTY and Devicetree folks. On my phone (GTA04) there are two devices which are each accessed via a UART: the bluetooth module and the GPS. I would like these to be powered on when the relevant /dev/ttyXX is opened, and to be powered off when the tty is closed. This patch series adds support for "tty slaves" and creates two appropriate drivers of this type. A "tty slave" is a platform device which is primarily attached by a TTY (i.e. a uart). Like other platform devices it might have other interconnections like gpios and regulators etc. In devicetree, any child node of a uart with a 'compatible' attribute is treated as a 'tty slave'. This means that it is probed like any other platform device. Also, when the tty is opened the device is powered on by taking a pm_runtime reference.. Similarly when the tty is closed the pm_runtime reference is dropped. One of the drivers is a generic "tty-regulator" drive which simply enables a regulator when powered on, and disables it when no longer in use. This suffices for my bluetooth device. The other handles the slightly awkward details of powering on my particular GPS as well as a regulator which powers the antenna. It also registers an 'rfkill' which can power-off the antenna independently of the TTY. Comments and review most welcome. Thanks, NeilBrown --- NeilBrown (3): TTY: add support for "tty slave" devices. TTY: add slave driver to power-on device via a regulator. TTY/slave: add driver for w2sg0004 GPS .../devicetree/bindings/serial/of-serial.txt | 4 .../devicetree/bindings/serial/slave-reg.txt | 18 + .../devicetree/bindings/serial/slave-w2sg0004.txt | 35 ++ drivers/tty/Kconfig | 2 drivers/tty/Makefile | 1 drivers/tty/slaves/Kconfig | 18 + drivers/tty/slaves/Makefile | 3 drivers/tty/slaves/tty-reg.c | 102 +++++ drivers/tty/slaves/tty-w2sg0004.c | 412 ++++++++++++++++++++ drivers/tty/tty_io.c | 22 + 10 files changed, 617 insertions(+) create mode 100644 Documentation/devicetree/bindings/serial/slave-reg.txt create mode 100644 Documentation/devicetree/bindings/serial/slave-w2sg0004.txt create mode 100644 drivers/tty/slaves/Kconfig create mode 100644 drivers/tty/slaves/Makefile create mode 100644 drivers/tty/slaves/tty-reg.c create mode 100644 drivers/tty/slaves/tty-w2sg0004.c -- Signature ^ permalink raw reply [flat|nested] 34+ messages in thread
* [PATCH 2/3] TTY: add slave driver to power-on device via a regulator. 2014-12-11 21:59 [PATCH 0/3] Add support for 'tty-slaves' described by devicetree NeilBrown @ 2014-12-11 21:59 ` NeilBrown [not found] ` <20141211215944.4127.4186.stgit-wvvUuzkyo1EYVZTmpyfIwg@public.gmane.org> 2014-12-12 12:05 ` Grant Likely 2014-12-11 21:59 ` [PATCH 1/3] TTY: add support for "tty slave" devices NeilBrown 2014-12-11 21:59 ` [PATCH 3/3] TTY/slave: add driver for w2sg0004 GPS NeilBrown 2 siblings, 2 replies; 34+ messages in thread From: NeilBrown @ 2014-12-11 21:59 UTC (permalink / raw) To: Grant Likely, Greg Kroah-Hartman, Mark Rutland, Jiri Slaby Cc: devicetree, linux-kernel The regulator is identified in devicetree as 'vdd-supply' Signed-off-by: NeilBrown <neilb@suse.de> --- .../devicetree/bindings/serial/slave-reg.txt | 18 ++++ drivers/tty/Kconfig | 2 drivers/tty/Makefile | 1 drivers/tty/slaves/Kconfig | 12 ++ drivers/tty/slaves/Makefile | 2 drivers/tty/slaves/tty-reg.c | 102 ++++++++++++++++++++ 6 files changed, 137 insertions(+) create mode 100644 Documentation/devicetree/bindings/serial/slave-reg.txt create mode 100644 drivers/tty/slaves/Kconfig create mode 100644 drivers/tty/slaves/Makefile create mode 100644 drivers/tty/slaves/tty-reg.c diff --git a/Documentation/devicetree/bindings/serial/slave-reg.txt b/Documentation/devicetree/bindings/serial/slave-reg.txt new file mode 100644 index 000000000000..7896bce8dfe4 --- /dev/null +++ b/Documentation/devicetree/bindings/serial/slave-reg.txt @@ -0,0 +1,18 @@ +Regulator powered UART-attached device + +Required properties: +- compatible: "tty,regulator" +- vdd-supply: regulator to power the device + + +This is listed as a child node of a UART. When the +UART is opened, the device is powered. + +Example: + +&uart1 { + bluetooth { + compatible = "tty,regulator"; + vdd-supply = <&vaux4>; + }; +}; diff --git a/drivers/tty/Kconfig b/drivers/tty/Kconfig index b24aa010f68c..ea3383c71701 100644 --- a/drivers/tty/Kconfig +++ b/drivers/tty/Kconfig @@ -419,4 +419,6 @@ config DA_CONSOLE help This enables a console on a Dash channel. +source drivers/tty/slaves/Kconfig + endif # TTY diff --git a/drivers/tty/Makefile b/drivers/tty/Makefile index 58ad1c05b7f8..45957d671e33 100644 --- a/drivers/tty/Makefile +++ b/drivers/tty/Makefile @@ -13,6 +13,7 @@ obj-$(CONFIG_R3964) += n_r3964.o obj-y += vt/ obj-$(CONFIG_HVC_DRIVER) += hvc/ obj-y += serial/ +obj-$(CONFIG_TTY_SLAVE) += slaves/ # tty drivers obj-$(CONFIG_AMIGA_BUILTIN_SERIAL) += amiserial.o diff --git a/drivers/tty/slaves/Kconfig b/drivers/tty/slaves/Kconfig new file mode 100644 index 000000000000..2dd1acf80f8c --- /dev/null +++ b/drivers/tty/slaves/Kconfig @@ -0,0 +1,12 @@ +menuconfig TTY_SLAVE + bool "TTY slave devices" + help + Devices which attach via a uart, but need extra + driver support for power management etc. + +if TTY_SLAVE + +config TTY_SLAVE_REGULATOR + tristate "TTY slave device powered by regulator" + +endif diff --git a/drivers/tty/slaves/Makefile b/drivers/tty/slaves/Makefile new file mode 100644 index 000000000000..e636bf49f1cc --- /dev/null +++ b/drivers/tty/slaves/Makefile @@ -0,0 +1,2 @@ + +obj-$(CONFIG_TTY_SLAVE_REGULATOR) += tty-reg.o diff --git a/drivers/tty/slaves/tty-reg.c b/drivers/tty/slaves/tty-reg.c new file mode 100644 index 000000000000..613f8b10967c --- /dev/null +++ b/drivers/tty/slaves/tty-reg.c @@ -0,0 +1,102 @@ +/* + * tty-reg: + * Support for any device which needs a regulator turned on + * when a tty is opened. + */ + +#include <linux/module.h> +#include <linux/slab.h> +#include <linux/err.h> +#include <linux/regulator/consumer.h> +#include <linux/platform_device.h> +#include <linux/pm_runtime.h> +#include <linux/tty.h> + +struct tty_reg_data { + struct regulator *reg; + bool reg_enabled; +}; + +static int tty_reg_runtime_resume(struct device *slave) +{ + struct tty_reg_data *data = dev_get_drvdata(slave); + if (!data->reg_enabled && + regulator_enable(data->reg) == 0) { + dev_dbg(slave, "power on\n"); + data->reg_enabled = true; + } + return 0; +} + +static int tty_reg_runtime_suspend(struct device *slave) +{ + struct tty_reg_data *data = dev_get_drvdata(slave); + + if (data->reg_enabled && + regulator_disable(data->reg) == 0) { + dev_dbg(slave, "power off\n"); + data->reg_enabled = false; + } + return 0; +} + +static int tty_reg_probe(struct platform_device *pdev) +{ + struct tty_reg_data *data; + struct regulator *reg; + int err; + + err = -ENODEV; + if (pdev->dev.parent == NULL) + goto out; + reg = devm_regulator_get(&pdev->dev, "vdd"); + err = PTR_ERR(reg); + if (IS_ERR(reg)) + goto out; + + data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); + err = -ENOMEM; + if (!data) + goto out; + data->reg = reg; + data->reg_enabled = false; + pm_runtime_enable(&pdev->dev); + platform_set_drvdata(pdev, data); + err = 0; +out: + return err; +} + +static struct of_device_id tty_reg_dt_ids[] = { + { .compatible = "tty,regulator", }, + {} +}; + +static const struct dev_pm_ops tty_reg_pm_ops = { + SET_RUNTIME_PM_OPS(tty_reg_runtime_suspend, + tty_reg_runtime_resume, NULL) +}; + +static struct platform_driver tty_reg_driver = { + .driver.name = "tty-regulator", + .driver.owner = THIS_MODULE, + .driver.of_match_table = tty_reg_dt_ids, + .driver.pm = &tty_reg_pm_ops, + .probe = tty_reg_probe, +}; + +static int __init tty_reg_init(void) +{ + return platform_driver_register(&tty_reg_driver); +} +module_init(tty_reg_init); + +static void __exit tty_reg_exit(void) +{ + platform_driver_unregister(&tty_reg_driver); +} +module_exit(tty_reg_exit); + +MODULE_AUTHOR("NeilBrown <neilb@suse.de>"); +MODULE_DESCRIPTION("Serial port device which requires a regulator when open."); +MODULE_LICENSE("GPL v2"); ^ permalink raw reply related [flat|nested] 34+ messages in thread
[parent not found: <20141211215944.4127.4186.stgit-wvvUuzkyo1EYVZTmpyfIwg@public.gmane.org>]
* Re: [PATCH 2/3] TTY: add slave driver to power-on device via a regulator. [not found] ` <20141211215944.4127.4186.stgit-wvvUuzkyo1EYVZTmpyfIwg@public.gmane.org> @ 2014-12-11 22:58 ` Sebastian Reichel 2014-12-12 0:46 ` Marcel Holtmann 2014-12-12 5:01 ` NeilBrown 2014-12-11 23:32 ` Peter Hurley 1 sibling, 2 replies; 34+ messages in thread From: Sebastian Reichel @ 2014-12-11 22:58 UTC (permalink / raw) To: NeilBrown Cc: Grant Likely, Greg Kroah-Hartman, Mark Rutland, Jiri Slaby, devicetree-u79uwXL29TY76Z2rM5mHXA, linux-kernel-u79uwXL29TY76Z2rM5mHXA [-- Attachment #1: Type: text/plain, Size: 7007 bytes --] Hi, On Fri, Dec 12, 2014 at 08:59:44AM +1100, NeilBrown wrote: > The regulator is identified in devicetree as 'vdd-supply' long description is kind of useless... > Signed-off-by: NeilBrown <neilb-l3A5Bk7waGM@public.gmane.org> > --- > .../devicetree/bindings/serial/slave-reg.txt | 18 ++++ > drivers/tty/Kconfig | 2 > drivers/tty/Makefile | 1 > drivers/tty/slaves/Kconfig | 12 ++ > drivers/tty/slaves/Makefile | 2 > drivers/tty/slaves/tty-reg.c | 102 ++++++++++++++++++++ > 6 files changed, 137 insertions(+) > create mode 100644 Documentation/devicetree/bindings/serial/slave-reg.txt > create mode 100644 drivers/tty/slaves/Kconfig > create mode 100644 drivers/tty/slaves/Makefile > create mode 100644 drivers/tty/slaves/tty-reg.c > > diff --git a/Documentation/devicetree/bindings/serial/slave-reg.txt b/Documentation/devicetree/bindings/serial/slave-reg.txt > new file mode 100644 > index 000000000000..7896bce8dfe4 > --- /dev/null > +++ b/Documentation/devicetree/bindings/serial/slave-reg.txt > @@ -0,0 +1,18 @@ > +Regulator powered UART-attached device > + > +Required properties: > +- compatible: "tty,regulator" > +- vdd-supply: regulator to power the device > + > + > +This is listed as a child node of a UART. When the > +UART is opened, the device is powered. > + > +Example: > + > +&uart1 { > + bluetooth { > + compatible = "tty,regulator"; > + vdd-supply = <&vaux4>; > + }; > +}; NACK. The compatible value should describe the connected device. You did not connect a regulator, but a bluetooth chip! DT should look like this: &uart1 { bluetooth { compatible = "vendor,bluetooth-chip"; vdd-supply = <&vaux4>; }; }; I think it would be ok to use your generic driver to handle the specific compatible value, though. Having the proper compatible value means, that there can be a more specific driver later, that other operating systems can expose the device as some kind of /dev/bluetooth instead of /dev/ttyXY, that userspace is able to know there is a bluetooth device connected to /dev/ttyXY by parsing the DT and results in easier-to-understand DTS. > diff --git a/drivers/tty/Kconfig b/drivers/tty/Kconfig > index b24aa010f68c..ea3383c71701 100644 > --- a/drivers/tty/Kconfig > +++ b/drivers/tty/Kconfig > @@ -419,4 +419,6 @@ config DA_CONSOLE > help > This enables a console on a Dash channel. > > +source drivers/tty/slaves/Kconfig > + > endif # TTY > diff --git a/drivers/tty/Makefile b/drivers/tty/Makefile > index 58ad1c05b7f8..45957d671e33 100644 > --- a/drivers/tty/Makefile > +++ b/drivers/tty/Makefile > @@ -13,6 +13,7 @@ obj-$(CONFIG_R3964) += n_r3964.o > obj-y += vt/ > obj-$(CONFIG_HVC_DRIVER) += hvc/ > obj-y += serial/ > +obj-$(CONFIG_TTY_SLAVE) += slaves/ > > # tty drivers > obj-$(CONFIG_AMIGA_BUILTIN_SERIAL) += amiserial.o > diff --git a/drivers/tty/slaves/Kconfig b/drivers/tty/slaves/Kconfig > new file mode 100644 > index 000000000000..2dd1acf80f8c > --- /dev/null > +++ b/drivers/tty/slaves/Kconfig > @@ -0,0 +1,12 @@ > +menuconfig TTY_SLAVE > + bool "TTY slave devices" > + help > + Devices which attach via a uart, but need extra > + driver support for power management etc. > + > +if TTY_SLAVE > + > +config TTY_SLAVE_REGULATOR > + tristate "TTY slave device powered by regulator" > + > +endif > diff --git a/drivers/tty/slaves/Makefile b/drivers/tty/slaves/Makefile > new file mode 100644 > index 000000000000..e636bf49f1cc > --- /dev/null > +++ b/drivers/tty/slaves/Makefile > @@ -0,0 +1,2 @@ > + > +obj-$(CONFIG_TTY_SLAVE_REGULATOR) += tty-reg.o > diff --git a/drivers/tty/slaves/tty-reg.c b/drivers/tty/slaves/tty-reg.c > new file mode 100644 > index 000000000000..613f8b10967c > --- /dev/null > +++ b/drivers/tty/slaves/tty-reg.c > @@ -0,0 +1,102 @@ > +/* > + * tty-reg: > + * Support for any device which needs a regulator turned on > + * when a tty is opened. > + */ > + > +#include <linux/module.h> > +#include <linux/slab.h> > +#include <linux/err.h> > +#include <linux/regulator/consumer.h> > +#include <linux/platform_device.h> > +#include <linux/pm_runtime.h> > +#include <linux/tty.h> > + > +struct tty_reg_data { > + struct regulator *reg; > + bool reg_enabled; > +}; > + > +static int tty_reg_runtime_resume(struct device *slave) > +{ > + struct tty_reg_data *data = dev_get_drvdata(slave); > + if (!data->reg_enabled && > + regulator_enable(data->reg) == 0) { > + dev_dbg(slave, "power on\n"); > + data->reg_enabled = true; > + } > + return 0; > +} > + > +static int tty_reg_runtime_suspend(struct device *slave) > +{ > + struct tty_reg_data *data = dev_get_drvdata(slave); > + > + if (data->reg_enabled && > + regulator_disable(data->reg) == 0) { > + dev_dbg(slave, "power off\n"); > + data->reg_enabled = false; > + } > + return 0; > +} > + > +static int tty_reg_probe(struct platform_device *pdev) > +{ > + struct tty_reg_data *data; > + struct regulator *reg; > + int err; > + > + err = -ENODEV; > + if (pdev->dev.parent == NULL) > + goto out; > + reg = devm_regulator_get(&pdev->dev, "vdd"); > + err = PTR_ERR(reg); > + if (IS_ERR(reg)) > + goto out; > + > + data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); > + err = -ENOMEM; > + if (!data) > + goto out; > + data->reg = reg; > + data->reg_enabled = false; > + pm_runtime_enable(&pdev->dev); > + platform_set_drvdata(pdev, data); > + err = 0; > +out: > + return err; > +} > + > +static struct of_device_id tty_reg_dt_ids[] = { > + { .compatible = "tty,regulator", }, > + {} > +}; > + > +static const struct dev_pm_ops tty_reg_pm_ops = { > + SET_RUNTIME_PM_OPS(tty_reg_runtime_suspend, > + tty_reg_runtime_resume, NULL) > +}; > + > +static struct platform_driver tty_reg_driver = { > + .driver.name = "tty-regulator", > + .driver.owner = THIS_MODULE, > + .driver.of_match_table = tty_reg_dt_ids, > + .driver.pm = &tty_reg_pm_ops, > + .probe = tty_reg_probe, > +}; > + > +static int __init tty_reg_init(void) > +{ > + return platform_driver_register(&tty_reg_driver); > +} > +module_init(tty_reg_init); > + > +static void __exit tty_reg_exit(void) > +{ > + platform_driver_unregister(&tty_reg_driver); > +} > +module_exit(tty_reg_exit); > + > +MODULE_AUTHOR("NeilBrown <neilb-l3A5Bk7waGM@public.gmane.org>"); > +MODULE_DESCRIPTION("Serial port device which requires a regulator when open."); > +MODULE_LICENSE("GPL v2"); > > > -- > To unsubscribe from this list: send the line "unsubscribe linux-kernel" in > the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org > More majordomo info at http://vger.kernel.org/majordomo-info.html > Please read the FAQ at http://www.tux.org/lkml/ [-- Attachment #2: Digital signature --] [-- Type: application/pgp-signature, Size: 819 bytes --] ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH 2/3] TTY: add slave driver to power-on device via a regulator. 2014-12-11 22:58 ` Sebastian Reichel @ 2014-12-12 0:46 ` Marcel Holtmann 2014-12-12 1:31 ` Sebastian Reichel 2014-12-12 5:01 ` NeilBrown 1 sibling, 1 reply; 34+ messages in thread From: Marcel Holtmann @ 2014-12-12 0:46 UTC (permalink / raw) To: Sebastian Reichel Cc: NeilBrown, Grant Likely, Greg Kroah-Hartman, Mark Rutland, Jiri Slaby, devicetree, linux-kernel Hi Sebastian, >> diff --git a/Documentation/devicetree/bindings/serial/slave-reg.txt b/Documentation/devicetree/bindings/serial/slave-reg.txt >> new file mode 100644 >> index 000000000000..7896bce8dfe4 >> --- /dev/null >> +++ b/Documentation/devicetree/bindings/serial/slave-reg.txt >> @@ -0,0 +1,18 @@ >> +Regulator powered UART-attached device >> + >> +Required properties: >> +- compatible: "tty,regulator" >> +- vdd-supply: regulator to power the device >> + >> + >> +This is listed as a child node of a UART. When the >> +UART is opened, the device is powered. >> + >> +Example: >> + >> +&uart1 { >> + bluetooth { >> + compatible = "tty,regulator"; >> + vdd-supply = <&vaux4>; >> + }; >> +}; > > NACK. The compatible value should describe the connected device. You > did not connect a regulator, but a bluetooth chip! DT should look > like this: > > &uart1 { > bluetooth { > compatible = "vendor,bluetooth-chip"; > vdd-supply = <&vaux4>; > }; > }; > > I think it would be ok to use your generic driver to handle the > specific compatible value, though. > > Having the proper compatible value means, that there can be a more > specific driver later, that other operating systems can expose the > device as some kind of /dev/bluetooth instead of /dev/ttyXY, that > userspace is able to know there is a bluetooth device connected to > /dev/ttyXY by parsing the DT and results in easier-to-understand > DTS. I think that is up to udev to be able to make this a nice device node. However the device node name is pretty much irrelevant. What you want is enough meta data to tell that there is Bluetooth chip behind this TTY. From a Bluetooth stack perspective only hciattach needs to be run to get the N_HCI line discipline up and running for that chip. However what would be interesting for hciattach would be a possibility to expose the Bluetooth manufacturer. Since the init routine is different for each manufacturer. So if that could be encoded in the DT, then that would be certainly helpful. Regards Marcel ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH 2/3] TTY: add slave driver to power-on device via a regulator. 2014-12-12 0:46 ` Marcel Holtmann @ 2014-12-12 1:31 ` Sebastian Reichel 0 siblings, 0 replies; 34+ messages in thread From: Sebastian Reichel @ 2014-12-12 1:31 UTC (permalink / raw) To: Marcel Holtmann Cc: NeilBrown, Grant Likely, Greg Kroah-Hartman, Mark Rutland, Jiri Slaby, devicetree, linux-kernel [-- Attachment #1: Type: text/plain, Size: 2362 bytes --] Hi Marcel, On Fri, Dec 12, 2014 at 01:46:33AM +0100, Marcel Holtmann wrote: > > NACK. The compatible value should describe the connected device. You > > did not connect a regulator, but a bluetooth chip! DT should look > > like this: > > > > &uart1 { > > bluetooth { > > compatible = "vendor,bluetooth-chip"; > > vdd-supply = <&vaux4>; > > }; > > }; > > > > I think it would be ok to use your generic driver to handle the > > specific compatible value, though. > > > > Having the proper compatible value means, that there can be a more > > specific driver later, that other operating systems can expose the > > device as some kind of /dev/bluetooth instead of /dev/ttyXY, that > > userspace is able to know there is a bluetooth device connected to > > /dev/ttyXY by parsing the DT and results in easier-to-understand > > DTS. > > I think that is up to udev to be able to make this a nice device > node. However the device node name is pretty much irrelevant. Ah that was not about Linux, but about $random-os using DT. Just ignore the device name its not important for the argument. > What you want is enough meta data to tell that there is Bluetooth > chip behind this TTY. Yes, that is what I tried to say :) > From a Bluetooth stack perspective only hciattach needs to be run > to get the N_HCI line discipline up and running for that chip. Yes, but with the metadata from Neil's proposed binding you do not know, that there is a bluetooth chip connected, so you need to do this manually. Not very nice, when it could be done automatically. > However what would be interesting for hciattach would be a > possibility to expose the Bluetooth manufacturer. Since the init > routine is different for each manufacturer. Yes and it may be, that a manufacturer breaks its init routine at some point. The problem is not much different from other devices and normally solved through the compatible string. > So if that could be encoded in the DT, then that would be > certainly helpful. All needed data should be encoded when specified as in the following example: &uart1 { bluetooth { compatible = "wi2wi,w2cbw003"; vdd-supply = <&vaux4>; }; }; Note: wi2wi is not yet in Documentation/devicetree/bindings/vendor-prefixes.txt -- Sebastian [-- Attachment #2: Digital signature --] [-- Type: application/pgp-signature, Size: 819 bytes --] ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH 2/3] TTY: add slave driver to power-on device via a regulator. 2014-12-11 22:58 ` Sebastian Reichel 2014-12-12 0:46 ` Marcel Holtmann @ 2014-12-12 5:01 ` NeilBrown 1 sibling, 0 replies; 34+ messages in thread From: NeilBrown @ 2014-12-12 5:01 UTC (permalink / raw) To: Sebastian Reichel Cc: Grant Likely, Greg Kroah-Hartman, Mark Rutland, Jiri Slaby, devicetree, linux-kernel [-- Attachment #1: Type: text/plain, Size: 2681 bytes --] On Thu, 11 Dec 2014 23:58:48 +0100 Sebastian Reichel <sre@kernel.org> wrote: > Hi, > > On Fri, Dec 12, 2014 at 08:59:44AM +1100, NeilBrown wrote: > > The regulator is identified in devicetree as 'vdd-supply' > > long description is kind of useless... > > > Signed-off-by: NeilBrown <neilb@suse.de> > > --- > > .../devicetree/bindings/serial/slave-reg.txt | 18 ++++ > > drivers/tty/Kconfig | 2 > > drivers/tty/Makefile | 1 > > drivers/tty/slaves/Kconfig | 12 ++ > > drivers/tty/slaves/Makefile | 2 > > drivers/tty/slaves/tty-reg.c | 102 ++++++++++++++++++++ > > 6 files changed, 137 insertions(+) > > create mode 100644 Documentation/devicetree/bindings/serial/slave-reg.txt > > create mode 100644 drivers/tty/slaves/Kconfig > > create mode 100644 drivers/tty/slaves/Makefile > > create mode 100644 drivers/tty/slaves/tty-reg.c > > > > diff --git a/Documentation/devicetree/bindings/serial/slave-reg.txt b/Documentation/devicetree/bindings/serial/slave-reg.txt > > new file mode 100644 > > index 000000000000..7896bce8dfe4 > > --- /dev/null > > +++ b/Documentation/devicetree/bindings/serial/slave-reg.txt > > @@ -0,0 +1,18 @@ > > +Regulator powered UART-attached device > > + > > +Required properties: > > +- compatible: "tty,regulator" > > +- vdd-supply: regulator to power the device > > + > > + > > +This is listed as a child node of a UART. When the > > +UART is opened, the device is powered. > > + > > +Example: > > + > > +&uart1 { > > + bluetooth { > > + compatible = "tty,regulator"; > > + vdd-supply = <&vaux4>; > > + }; > > +}; > > NACK. The compatible value should describe the connected device. You > did not connect a regulator, but a bluetooth chip! DT should look > like this: > > &uart1 { > bluetooth { > compatible = "vendor,bluetooth-chip"; > vdd-supply = <&vaux4>; > }; > }; > > I think it would be ok to use your generic driver to handle the > specific compatible value, though. > > Having the proper compatible value means, that there can be a more > specific driver later, that other operating systems can expose the > device as some kind of /dev/bluetooth instead of /dev/ttyXY, that > userspace is able to know there is a bluetooth device connected to > /dev/ttyXY by parsing the DT and results in easier-to-understand > DTS. So the tty_reg_dt_ids array could conceivably grow a long list of compatible devices, starting with this one. I guess that makes sense. Thanks, NeilBrown [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 811 bytes --] ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH 2/3] TTY: add slave driver to power-on device via a regulator. [not found] ` <20141211215944.4127.4186.stgit-wvvUuzkyo1EYVZTmpyfIwg@public.gmane.org> 2014-12-11 22:58 ` Sebastian Reichel @ 2014-12-11 23:32 ` Peter Hurley 2014-12-12 5:27 ` NeilBrown 1 sibling, 1 reply; 34+ messages in thread From: Peter Hurley @ 2014-12-11 23:32 UTC (permalink / raw) To: NeilBrown, Grant Likely, Greg Kroah-Hartman, Mark Rutland, Jiri Slaby Cc: devicetree-u79uwXL29TY76Z2rM5mHXA, linux-kernel-u79uwXL29TY76Z2rM5mHXA On 12/11/2014 04:59 PM, NeilBrown wrote: > The regulator is identified in devicetree as 'vdd-supply' > > Signed-off-by: NeilBrown <neilb-l3A5Bk7waGM@public.gmane.org> tty_* is only for tty core functions/data. Regards, Peter Hurley > --- > .../devicetree/bindings/serial/slave-reg.txt | 18 ++++ > drivers/tty/Kconfig | 2 > drivers/tty/Makefile | 1 > drivers/tty/slaves/Kconfig | 12 ++ > drivers/tty/slaves/Makefile | 2 > drivers/tty/slaves/tty-reg.c | 102 ++++++++++++++++++++ > 6 files changed, 137 insertions(+) > create mode 100644 Documentation/devicetree/bindings/serial/slave-reg.txt > create mode 100644 drivers/tty/slaves/Kconfig > create mode 100644 drivers/tty/slaves/Makefile > create mode 100644 drivers/tty/slaves/tty-reg.c > > diff --git a/Documentation/devicetree/bindings/serial/slave-reg.txt b/Documentation/devicetree/bindings/serial/slave-reg.txt > new file mode 100644 > index 000000000000..7896bce8dfe4 > --- /dev/null > +++ b/Documentation/devicetree/bindings/serial/slave-reg.txt > @@ -0,0 +1,18 @@ > +Regulator powered UART-attached device > + > +Required properties: > +- compatible: "tty,regulator" > +- vdd-supply: regulator to power the device > + > + > +This is listed as a child node of a UART. When the > +UART is opened, the device is powered. > + > +Example: > + > +&uart1 { > + bluetooth { > + compatible = "tty,regulator"; > + vdd-supply = <&vaux4>; > + }; > +}; > diff --git a/drivers/tty/Kconfig b/drivers/tty/Kconfig > index b24aa010f68c..ea3383c71701 100644 > --- a/drivers/tty/Kconfig > +++ b/drivers/tty/Kconfig > @@ -419,4 +419,6 @@ config DA_CONSOLE > help > This enables a console on a Dash channel. > > +source drivers/tty/slaves/Kconfig > + > endif # TTY > diff --git a/drivers/tty/Makefile b/drivers/tty/Makefile > index 58ad1c05b7f8..45957d671e33 100644 > --- a/drivers/tty/Makefile > +++ b/drivers/tty/Makefile > @@ -13,6 +13,7 @@ obj-$(CONFIG_R3964) += n_r3964.o > obj-y += vt/ > obj-$(CONFIG_HVC_DRIVER) += hvc/ > obj-y += serial/ > +obj-$(CONFIG_TTY_SLAVE) += slaves/ > > # tty drivers > obj-$(CONFIG_AMIGA_BUILTIN_SERIAL) += amiserial.o > diff --git a/drivers/tty/slaves/Kconfig b/drivers/tty/slaves/Kconfig > new file mode 100644 > index 000000000000..2dd1acf80f8c > --- /dev/null > +++ b/drivers/tty/slaves/Kconfig > @@ -0,0 +1,12 @@ > +menuconfig TTY_SLAVE > + bool "TTY slave devices" > + help > + Devices which attach via a uart, but need extra > + driver support for power management etc. > + > +if TTY_SLAVE > + > +config TTY_SLAVE_REGULATOR > + tristate "TTY slave device powered by regulator" > + > +endif > diff --git a/drivers/tty/slaves/Makefile b/drivers/tty/slaves/Makefile > new file mode 100644 > index 000000000000..e636bf49f1cc > --- /dev/null > +++ b/drivers/tty/slaves/Makefile > @@ -0,0 +1,2 @@ > + > +obj-$(CONFIG_TTY_SLAVE_REGULATOR) += tty-reg.o > diff --git a/drivers/tty/slaves/tty-reg.c b/drivers/tty/slaves/tty-reg.c > new file mode 100644 > index 000000000000..613f8b10967c > --- /dev/null > +++ b/drivers/tty/slaves/tty-reg.c > @@ -0,0 +1,102 @@ > +/* > + * tty-reg: > + * Support for any device which needs a regulator turned on > + * when a tty is opened. > + */ > + > +#include <linux/module.h> > +#include <linux/slab.h> > +#include <linux/err.h> > +#include <linux/regulator/consumer.h> > +#include <linux/platform_device.h> > +#include <linux/pm_runtime.h> > +#include <linux/tty.h> > + > +struct tty_reg_data { > + struct regulator *reg; > + bool reg_enabled; > +}; > + > +static int tty_reg_runtime_resume(struct device *slave) > +{ > + struct tty_reg_data *data = dev_get_drvdata(slave); > + if (!data->reg_enabled && > + regulator_enable(data->reg) == 0) { > + dev_dbg(slave, "power on\n"); > + data->reg_enabled = true; > + } > + return 0; > +} > + > +static int tty_reg_runtime_suspend(struct device *slave) > +{ > + struct tty_reg_data *data = dev_get_drvdata(slave); > + > + if (data->reg_enabled && > + regulator_disable(data->reg) == 0) { > + dev_dbg(slave, "power off\n"); > + data->reg_enabled = false; > + } > + return 0; > +} > + > +static int tty_reg_probe(struct platform_device *pdev) > +{ > + struct tty_reg_data *data; > + struct regulator *reg; > + int err; > + > + err = -ENODEV; > + if (pdev->dev.parent == NULL) > + goto out; > + reg = devm_regulator_get(&pdev->dev, "vdd"); > + err = PTR_ERR(reg); > + if (IS_ERR(reg)) > + goto out; > + > + data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); > + err = -ENOMEM; > + if (!data) > + goto out; > + data->reg = reg; > + data->reg_enabled = false; > + pm_runtime_enable(&pdev->dev); > + platform_set_drvdata(pdev, data); > + err = 0; > +out: > + return err; > +} > + > +static struct of_device_id tty_reg_dt_ids[] = { > + { .compatible = "tty,regulator", }, > + {} > +}; > + > +static const struct dev_pm_ops tty_reg_pm_ops = { > + SET_RUNTIME_PM_OPS(tty_reg_runtime_suspend, > + tty_reg_runtime_resume, NULL) > +}; > + > +static struct platform_driver tty_reg_driver = { > + .driver.name = "tty-regulator", > + .driver.owner = THIS_MODULE, > + .driver.of_match_table = tty_reg_dt_ids, > + .driver.pm = &tty_reg_pm_ops, > + .probe = tty_reg_probe, > +}; > + > +static int __init tty_reg_init(void) > +{ > + return platform_driver_register(&tty_reg_driver); > +} > +module_init(tty_reg_init); > + > +static void __exit tty_reg_exit(void) > +{ > + platform_driver_unregister(&tty_reg_driver); > +} > +module_exit(tty_reg_exit); > + > +MODULE_AUTHOR("NeilBrown <neilb-l3A5Bk7waGM@public.gmane.org>"); > +MODULE_DESCRIPTION("Serial port device which requires a regulator when open."); > +MODULE_LICENSE("GPL v2"); -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH 2/3] TTY: add slave driver to power-on device via a regulator. 2014-12-11 23:32 ` Peter Hurley @ 2014-12-12 5:27 ` NeilBrown [not found] ` <20141212162714.3a2378df-wvvUuzkyo1EYVZTmpyfIwg@public.gmane.org> 0 siblings, 1 reply; 34+ messages in thread From: NeilBrown @ 2014-12-12 5:27 UTC (permalink / raw) To: Peter Hurley Cc: Grant Likely, Greg Kroah-Hartman, Mark Rutland, Jiri Slaby, devicetree, linux-kernel [-- Attachment #1: Type: text/plain, Size: 455 bytes --] On Thu, 11 Dec 2014 18:32:52 -0500 Peter Hurley <peter@hurleysoftware.com> wrote: > On 12/11/2014 04:59 PM, NeilBrown wrote: > > The regulator is identified in devicetree as 'vdd-supply' > > > > Signed-off-by: NeilBrown <neilb@suse.de> > > tty_* is only for tty core functions/data. I think you are just objecting to the function and type names - is that correct? I suspect I can come up with something different. Thanks, NeilBrown [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 811 bytes --] ^ permalink raw reply [flat|nested] 34+ messages in thread
[parent not found: <20141212162714.3a2378df-wvvUuzkyo1EYVZTmpyfIwg@public.gmane.org>]
* Re: [PATCH 2/3] TTY: add slave driver to power-on device via a regulator. [not found] ` <20141212162714.3a2378df-wvvUuzkyo1EYVZTmpyfIwg@public.gmane.org> @ 2014-12-12 11:59 ` Peter Hurley 0 siblings, 0 replies; 34+ messages in thread From: Peter Hurley @ 2014-12-12 11:59 UTC (permalink / raw) To: NeilBrown Cc: Grant Likely, Greg Kroah-Hartman, Mark Rutland, Jiri Slaby, devicetree-u79uwXL29TY76Z2rM5mHXA, linux-kernel-u79uwXL29TY76Z2rM5mHXA On 12/12/2014 12:27 AM, NeilBrown wrote: > On Thu, 11 Dec 2014 18:32:52 -0500 Peter Hurley <peter-WaGBZJeGNqdsbIuE7sb01tBPR1lH4CV8@public.gmane.org> > wrote: > >> On 12/11/2014 04:59 PM, NeilBrown wrote: >>> The regulator is identified in devicetree as 'vdd-supply' >>> >>> Signed-off-by: NeilBrown <neilb-l3A5Bk7waGM@public.gmane.org> >> >> tty_* is only for tty core functions/data. > > I think you are just objecting to the function and type names - is that > correct? Yeah, exactly. > I suspect I can come up with something different. Thanks. -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH 2/3] TTY: add slave driver to power-on device via a regulator. 2014-12-11 21:59 ` [PATCH 2/3] TTY: add slave driver to power-on device via a regulator NeilBrown [not found] ` <20141211215944.4127.4186.stgit-wvvUuzkyo1EYVZTmpyfIwg@public.gmane.org> @ 2014-12-12 12:05 ` Grant Likely 1 sibling, 0 replies; 34+ messages in thread From: Grant Likely @ 2014-12-12 12:05 UTC (permalink / raw) To: NeilBrown, Greg Kroah-Hartman, Mark Rutland, Jiri Slaby Cc: devicetree, linux-kernel On Fri, 12 Dec 2014 08:59:44 +1100 , NeilBrown <neilb@suse.de> wrote: > The regulator is identified in devicetree as 'vdd-supply' > > Signed-off-by: NeilBrown <neilb@suse.de> > --- > .../devicetree/bindings/serial/slave-reg.txt | 18 ++++ > drivers/tty/Kconfig | 2 > drivers/tty/Makefile | 1 > drivers/tty/slaves/Kconfig | 12 ++ > drivers/tty/slaves/Makefile | 2 > drivers/tty/slaves/tty-reg.c | 102 ++++++++++++++++++++ > 6 files changed, 137 insertions(+) > create mode 100644 Documentation/devicetree/bindings/serial/slave-reg.txt > create mode 100644 drivers/tty/slaves/Kconfig > create mode 100644 drivers/tty/slaves/Makefile > create mode 100644 drivers/tty/slaves/tty-reg.c > > diff --git a/Documentation/devicetree/bindings/serial/slave-reg.txt b/Documentation/devicetree/bindings/serial/slave-reg.txt > new file mode 100644 > index 000000000000..7896bce8dfe4 > --- /dev/null > +++ b/Documentation/devicetree/bindings/serial/slave-reg.txt > @@ -0,0 +1,18 @@ > +Regulator powered UART-attached device > + > +Required properties: > +- compatible: "tty,regulator" > +- vdd-supply: regulator to power the device The binding should be specfic to the device. Trying to do a generic binding like this doesn't scale well. Do a specific binding for the bluetooth chipset and make that driver understand how to do PM operations on that device. That way each kind of tty slave device driver can have its own set of PM mechanism which may be completely different. > +This is listed as a child node of a UART. When the > +UART is opened, the device is powered. Another thought, what if I *don't* want the device to be powered merely because the uart is opened? > + > +Example: > + > +&uart1 { > + bluetooth { > + compatible = "tty,regulator"; > + vdd-supply = <&vaux4>; > + }; > +}; > diff --git a/drivers/tty/Kconfig b/drivers/tty/Kconfig > index b24aa010f68c..ea3383c71701 100644 > --- a/drivers/tty/Kconfig > +++ b/drivers/tty/Kconfig > @@ -419,4 +419,6 @@ config DA_CONSOLE > help > This enables a console on a Dash channel. > > +source drivers/tty/slaves/Kconfig > + > endif # TTY > diff --git a/drivers/tty/Makefile b/drivers/tty/Makefile > index 58ad1c05b7f8..45957d671e33 100644 > --- a/drivers/tty/Makefile > +++ b/drivers/tty/Makefile > @@ -13,6 +13,7 @@ obj-$(CONFIG_R3964) += n_r3964.o > obj-y += vt/ > obj-$(CONFIG_HVC_DRIVER) += hvc/ > obj-y += serial/ > +obj-$(CONFIG_TTY_SLAVE) += slaves/ > > # tty drivers > obj-$(CONFIG_AMIGA_BUILTIN_SERIAL) += amiserial.o > diff --git a/drivers/tty/slaves/Kconfig b/drivers/tty/slaves/Kconfig > new file mode 100644 > index 000000000000..2dd1acf80f8c > --- /dev/null > +++ b/drivers/tty/slaves/Kconfig > @@ -0,0 +1,12 @@ > +menuconfig TTY_SLAVE > + bool "TTY slave devices" > + help > + Devices which attach via a uart, but need extra > + driver support for power management etc. > + > +if TTY_SLAVE > + > +config TTY_SLAVE_REGULATOR > + tristate "TTY slave device powered by regulator" > + > +endif > diff --git a/drivers/tty/slaves/Makefile b/drivers/tty/slaves/Makefile > new file mode 100644 > index 000000000000..e636bf49f1cc > --- /dev/null > +++ b/drivers/tty/slaves/Makefile > @@ -0,0 +1,2 @@ > + > +obj-$(CONFIG_TTY_SLAVE_REGULATOR) += tty-reg.o > diff --git a/drivers/tty/slaves/tty-reg.c b/drivers/tty/slaves/tty-reg.c > new file mode 100644 > index 000000000000..613f8b10967c > --- /dev/null > +++ b/drivers/tty/slaves/tty-reg.c > @@ -0,0 +1,102 @@ > +/* > + * tty-reg: > + * Support for any device which needs a regulator turned on > + * when a tty is opened. > + */ > + > +#include <linux/module.h> > +#include <linux/slab.h> > +#include <linux/err.h> > +#include <linux/regulator/consumer.h> > +#include <linux/platform_device.h> > +#include <linux/pm_runtime.h> > +#include <linux/tty.h> > + > +struct tty_reg_data { > + struct regulator *reg; > + bool reg_enabled; > +}; > + > +static int tty_reg_runtime_resume(struct device *slave) > +{ > + struct tty_reg_data *data = dev_get_drvdata(slave); > + if (!data->reg_enabled && > + regulator_enable(data->reg) == 0) { > + dev_dbg(slave, "power on\n"); > + data->reg_enabled = true; > + } > + return 0; > +} > + > +static int tty_reg_runtime_suspend(struct device *slave) > +{ > + struct tty_reg_data *data = dev_get_drvdata(slave); > + > + if (data->reg_enabled && > + regulator_disable(data->reg) == 0) { > + dev_dbg(slave, "power off\n"); > + data->reg_enabled = false; > + } > + return 0; > +} > + > +static int tty_reg_probe(struct platform_device *pdev) > +{ > + struct tty_reg_data *data; > + struct regulator *reg; > + int err; > + > + err = -ENODEV; > + if (pdev->dev.parent == NULL) > + goto out; > + reg = devm_regulator_get(&pdev->dev, "vdd"); > + err = PTR_ERR(reg); > + if (IS_ERR(reg)) > + goto out; > + > + data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); > + err = -ENOMEM; > + if (!data) > + goto out; > + data->reg = reg; > + data->reg_enabled = false; > + pm_runtime_enable(&pdev->dev); > + platform_set_drvdata(pdev, data); > + err = 0; > +out: > + return err; > +} > + > +static struct of_device_id tty_reg_dt_ids[] = { > + { .compatible = "tty,regulator", }, > + {} > +}; > + > +static const struct dev_pm_ops tty_reg_pm_ops = { > + SET_RUNTIME_PM_OPS(tty_reg_runtime_suspend, > + tty_reg_runtime_resume, NULL) > +}; > + > +static struct platform_driver tty_reg_driver = { > + .driver.name = "tty-regulator", > + .driver.owner = THIS_MODULE, > + .driver.of_match_table = tty_reg_dt_ids, > + .driver.pm = &tty_reg_pm_ops, > + .probe = tty_reg_probe, > +}; Instead of creating a full driver that binds against the device, would it not be better to provide a library of stock PM operations that other device drivers (like the bluetooth driver) can use as-is instead of defining its own? > + > +static int __init tty_reg_init(void) > +{ > + return platform_driver_register(&tty_reg_driver); > +} > +module_init(tty_reg_init); > + > +static void __exit tty_reg_exit(void) > +{ > + platform_driver_unregister(&tty_reg_driver); > +} > +module_exit(tty_reg_exit); > + > +MODULE_AUTHOR("NeilBrown <neilb@suse.de>"); > +MODULE_DESCRIPTION("Serial port device which requires a regulator when open."); > +MODULE_LICENSE("GPL v2"); > > ^ permalink raw reply [flat|nested] 34+ messages in thread
* [PATCH 1/3] TTY: add support for "tty slave" devices. 2014-12-11 21:59 [PATCH 0/3] Add support for 'tty-slaves' described by devicetree NeilBrown 2014-12-11 21:59 ` [PATCH 2/3] TTY: add slave driver to power-on device via a regulator NeilBrown @ 2014-12-11 21:59 ` NeilBrown [not found] ` <20141211215943.4127.24792.stgit-wvvUuzkyo1EYVZTmpyfIwg@public.gmane.org> ` (2 more replies) 2014-12-11 21:59 ` [PATCH 3/3] TTY/slave: add driver for w2sg0004 GPS NeilBrown 2 siblings, 3 replies; 34+ messages in thread From: NeilBrown @ 2014-12-11 21:59 UTC (permalink / raw) To: Grant Likely, Greg Kroah-Hartman, Mark Rutland, Jiri Slaby Cc: devicetree, linux-kernel A "tty slave" is a device connected via UART. It may need a driver to, for example, power the device on when the tty is opened, and power it off when the tty is released. A "tty slave" is a platform device which is declared as a child of the uart in device-tree: &uart1 { bluetooth { compatible = "tty,regulator"; vdd-supply = <&vaux4>; }; }; runtime power management is used to power-up the device on tty_open() and power-down on tty_release(). Signed-off-by: NeilBrown <neilb@suse.de> --- .../devicetree/bindings/serial/of-serial.txt | 4 ++++ drivers/tty/tty_io.c | 22 ++++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/Documentation/devicetree/bindings/serial/of-serial.txt b/Documentation/devicetree/bindings/serial/of-serial.txt index 8c4fd0332028..b59501ee2f21 100644 --- a/Documentation/devicetree/bindings/serial/of-serial.txt +++ b/Documentation/devicetree/bindings/serial/of-serial.txt @@ -39,6 +39,10 @@ Optional properties: driver is allowed to detect support for the capability even without this property. +Optional child node: +- a platform device listed as a child node will be probed and + powered-on whenever the tty is in use (open). + Example: uart@80230000 { diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 0508a1d8e4cd..7acdc6f093f4 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -95,6 +95,8 @@ #include <linux/seq_file.h> #include <linux/serial.h> #include <linux/ratelimit.h> +#include <linux/pm_runtime.h> +#include <linux/of_platform.h> #include <linux/uaccess.h> @@ -1683,6 +1685,17 @@ static int tty_release_checks(struct tty_struct *tty, struct tty_struct *o_tty, return 0; } +static int open_child(struct device *dev, void *data) +{ + pm_runtime_get_sync(dev); + return 0; +} +static int release_child(struct device *dev, void *data) +{ + pm_runtime_put_autosuspend(dev); + return 0; +} + /** * tty_release - vfs callback for close * @inode: inode of tty @@ -1712,6 +1725,8 @@ int tty_release(struct inode *inode, struct file *filp) long timeout = 0; int once = 1; + if (tty->dev) + device_for_each_child(tty->dev, NULL, release_child); if (tty_paranoia_check(tty, inode, __func__)) return 0; @@ -2118,6 +2133,8 @@ retry_open: __proc_set_tty(current, tty); spin_unlock_irq(¤t->sighand->siglock); tty_unlock(tty); + if (tty->dev) + device_for_each_child(tty->dev, NULL, open_child); mutex_unlock(&tty_mutex); return 0; err_unlock: @@ -3207,6 +3224,11 @@ struct device *tty_register_device_attr(struct tty_driver *driver, retval = device_register(dev); if (retval) goto error; + if (device && device->of_node) + /* Children are platform devices and will be + * runtime_pm managed by this tty. + */ + of_platform_populate(device->of_node, NULL, NULL, dev); return dev; ^ permalink raw reply related [flat|nested] 34+ messages in thread
[parent not found: <20141211215943.4127.24792.stgit-wvvUuzkyo1EYVZTmpyfIwg@public.gmane.org>]
* Re: [PATCH 1/3] TTY: add support for "tty slave" devices. [not found] ` <20141211215943.4127.24792.stgit-wvvUuzkyo1EYVZTmpyfIwg@public.gmane.org> @ 2014-12-11 22:41 ` Sebastian Reichel 2014-12-11 23:18 ` Peter Hurley 1 sibling, 0 replies; 34+ messages in thread From: Sebastian Reichel @ 2014-12-11 22:41 UTC (permalink / raw) To: NeilBrown Cc: Grant Likely, Greg Kroah-Hartman, Mark Rutland, Jiri Slaby, devicetree-u79uwXL29TY76Z2rM5mHXA, linux-kernel-u79uwXL29TY76Z2rM5mHXA [-- Attachment #1: Type: text/plain, Size: 745 bytes --] Hi, On Fri, Dec 12, 2014 at 08:59:44AM +1100, NeilBrown wrote: > A "tty slave" is a device connected via UART. > It may need a driver to, for example, power the device on > when the tty is opened, and power it off when the tty > is released. > > A "tty slave" is a platform device which is declared as a > child of the uart in device-tree: > > &uart1 { > bluetooth { > compatible = "tty,regulator"; > vdd-supply = <&vaux4>; > }; > }; > > runtime power management is used to power-up the device > on tty_open() and power-down on tty_release(). > > Signed-off-by: NeilBrown <neilb-l3A5Bk7waGM@public.gmane.org> FWIW: Acked-By: Sebastian Reichel <sre-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> -- Sebastian [-- Attachment #2: Digital signature --] [-- Type: application/pgp-signature, Size: 819 bytes --] ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH 1/3] TTY: add support for "tty slave" devices. [not found] ` <20141211215943.4127.24792.stgit-wvvUuzkyo1EYVZTmpyfIwg@public.gmane.org> 2014-12-11 22:41 ` Sebastian Reichel @ 2014-12-11 23:18 ` Peter Hurley [not found] ` <548A264D.8070103-WaGBZJeGNqdsbIuE7sb01tBPR1lH4CV8@public.gmane.org> 1 sibling, 1 reply; 34+ messages in thread From: Peter Hurley @ 2014-12-11 23:18 UTC (permalink / raw) To: NeilBrown, Grant Likely, Greg Kroah-Hartman, Mark Rutland, Jiri Slaby Cc: devicetree-u79uwXL29TY76Z2rM5mHXA, linux-kernel-u79uwXL29TY76Z2rM5mHXA On 12/11/2014 04:59 PM, NeilBrown wrote: > A "tty slave" is a device connected via UART. > It may need a driver to, for example, power the device on > when the tty is opened, and power it off when the tty > is released. > > A "tty slave" is a platform device which is declared as a > child of the uart in device-tree: > > &uart1 { > bluetooth { > compatible = "tty,regulator"; > vdd-supply = <&vaux4>; > }; > }; > > runtime power management is used to power-up the device > on tty_open() and power-down on tty_release(). I have a couple of issues with this: 1) why does a child device imply power management and a platform device? iow, what happens when someone else wants to have a child device that does something different? 2) why is this tied to the tty core and not the serial core if this is only for UART? Regards, Peter Hurley > Signed-off-by: NeilBrown <neilb-l3A5Bk7waGM@public.gmane.org> > --- > .../devicetree/bindings/serial/of-serial.txt | 4 ++++ > drivers/tty/tty_io.c | 22 ++++++++++++++++++++ > 2 files changed, 26 insertions(+) > > diff --git a/Documentation/devicetree/bindings/serial/of-serial.txt b/Documentation/devicetree/bindings/serial/of-serial.txt > index 8c4fd0332028..b59501ee2f21 100644 > --- a/Documentation/devicetree/bindings/serial/of-serial.txt > +++ b/Documentation/devicetree/bindings/serial/of-serial.txt > @@ -39,6 +39,10 @@ Optional properties: > driver is allowed to detect support for the capability even without this > property. > > +Optional child node: > +- a platform device listed as a child node will be probed and > + powered-on whenever the tty is in use (open). > + > Example: > > uart@80230000 { > diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c > index 0508a1d8e4cd..7acdc6f093f4 100644 > --- a/drivers/tty/tty_io.c > +++ b/drivers/tty/tty_io.c > @@ -95,6 +95,8 @@ > #include <linux/seq_file.h> > #include <linux/serial.h> > #include <linux/ratelimit.h> > +#include <linux/pm_runtime.h> > +#include <linux/of_platform.h> > > #include <linux/uaccess.h> > > @@ -1683,6 +1685,17 @@ static int tty_release_checks(struct tty_struct *tty, struct tty_struct *o_tty, > return 0; > } > > +static int open_child(struct device *dev, void *data) > +{ > + pm_runtime_get_sync(dev); > + return 0; > +} > +static int release_child(struct device *dev, void *data) > +{ > + pm_runtime_put_autosuspend(dev); > + return 0; > +} > + > /** > * tty_release - vfs callback for close > * @inode: inode of tty > @@ -1712,6 +1725,8 @@ int tty_release(struct inode *inode, struct file *filp) > long timeout = 0; > int once = 1; > > + if (tty->dev) > + device_for_each_child(tty->dev, NULL, release_child); > if (tty_paranoia_check(tty, inode, __func__)) > return 0; > > @@ -2118,6 +2133,8 @@ retry_open: > __proc_set_tty(current, tty); > spin_unlock_irq(¤t->sighand->siglock); > tty_unlock(tty); > + if (tty->dev) > + device_for_each_child(tty->dev, NULL, open_child); > mutex_unlock(&tty_mutex); > return 0; > err_unlock: > @@ -3207,6 +3224,11 @@ struct device *tty_register_device_attr(struct tty_driver *driver, > retval = device_register(dev); > if (retval) > goto error; > + if (device && device->of_node) > + /* Children are platform devices and will be > + * runtime_pm managed by this tty. > + */ > + of_platform_populate(device->of_node, NULL, NULL, dev); > > return dev; -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 34+ messages in thread
[parent not found: <548A264D.8070103-WaGBZJeGNqdsbIuE7sb01tBPR1lH4CV8@public.gmane.org>]
* Re: [PATCH 1/3] TTY: add support for "tty slave" devices. [not found] ` <548A264D.8070103-WaGBZJeGNqdsbIuE7sb01tBPR1lH4CV8@public.gmane.org> @ 2014-12-12 5:23 ` NeilBrown [not found] ` <20141212162352.66be5b5e-wvvUuzkyo1EYVZTmpyfIwg@public.gmane.org> 2014-12-13 14:12 ` One Thousand Gnomes 1 sibling, 1 reply; 34+ messages in thread From: NeilBrown @ 2014-12-12 5:23 UTC (permalink / raw) To: Peter Hurley Cc: Grant Likely, Greg Kroah-Hartman, Mark Rutland, Jiri Slaby, devicetree-u79uwXL29TY76Z2rM5mHXA, linux-kernel-u79uwXL29TY76Z2rM5mHXA [-- Attachment #1: Type: text/plain, Size: 6197 bytes --] On Thu, 11 Dec 2014 18:18:37 -0500 Peter Hurley <peter-WaGBZJeGNqdsbIuE7sb01tBPR1lH4CV8@public.gmane.org> wrote: > On 12/11/2014 04:59 PM, NeilBrown wrote: > > A "tty slave" is a device connected via UART. > > It may need a driver to, for example, power the device on > > when the tty is opened, and power it off when the tty > > is released. > > > > A "tty slave" is a platform device which is declared as a > > child of the uart in device-tree: > > > > &uart1 { > > bluetooth { > > compatible = "tty,regulator"; > > vdd-supply = <&vaux4>; > > }; > > }; > > > > runtime power management is used to power-up the device > > on tty_open() and power-down on tty_release(). > > I have a couple of issues with this: > 1) why does a child device imply power management and a platform > device? iow, what happens when someone else wants to have a > child device that does something different? Why does it imply power management? Because it seems to make obvious sense to turn something on when the tty is open. If the device has other reason to remain on when the tty is closed, it can arrange for extra references to be taken of course. Is it conceivable that you would want the device to remain off when the tty device is open? In that case just make it a regular platform device. Why a platform device? Things on an i2c bus are i2c devices. Things on a usb bus are usb devices. Ideally a thing on a uart 'bus' would be a 'uart device', but no such thing exists. I did contemplate the possibility of creating an explicit "uart" or "tty" bus type, but I could find no value in that. The door is certainly still open to that possibility if a meaning for the idea becomes apparent. As far as device tree is concerned it is just a child device node. The fact that it is implemented as a "platform" device could easily be changed later if needed without device tree noticing. What could conceivably want to be different? The only (purely hypothetical) concept I can come up with which wouldn't fit is a device with both an UART port and a USB port, or similar. However device tree, and the device model in general, just isn't geared towards devices being on multiple buses so if that were real it would have much greater implications that just here. But maybe I misunderstand... > 2) why is this tied to the tty core and not the serial core > if this is only for UART? Because the knowledge of "the device is being opened" or "the device is being closed" seems to exist in the tty core but not in the serial core. The "of_platform_populate()" call could certainly go in serial_core.c, in uart_add_one_port() I think. I did have it there originally. I moved it for a reason that I think is no longer relevant. As the on/off code is (and I think has to be) in tty_io.c, I left all of it there. I'm happy to move it to serial_core.c if that is preferred. I'll also move the open/close handling if you can point to where it should go. Thanks, NeilBrown > > Regards, > Peter Hurley > > > Signed-off-by: NeilBrown <neilb-l3A5Bk7waGM@public.gmane.org> > > --- > > .../devicetree/bindings/serial/of-serial.txt | 4 ++++ > > drivers/tty/tty_io.c | 22 ++++++++++++++++++++ > > 2 files changed, 26 insertions(+) > > > > diff --git a/Documentation/devicetree/bindings/serial/of-serial.txt b/Documentation/devicetree/bindings/serial/of-serial.txt > > index 8c4fd0332028..b59501ee2f21 100644 > > --- a/Documentation/devicetree/bindings/serial/of-serial.txt > > +++ b/Documentation/devicetree/bindings/serial/of-serial.txt > > @@ -39,6 +39,10 @@ Optional properties: > > driver is allowed to detect support for the capability even without this > > property. > > > > +Optional child node: > > +- a platform device listed as a child node will be probed and > > + powered-on whenever the tty is in use (open). > > + > > Example: > > > > uart@80230000 { > > diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c > > index 0508a1d8e4cd..7acdc6f093f4 100644 > > --- a/drivers/tty/tty_io.c > > +++ b/drivers/tty/tty_io.c > > @@ -95,6 +95,8 @@ > > #include <linux/seq_file.h> > > #include <linux/serial.h> > > #include <linux/ratelimit.h> > > +#include <linux/pm_runtime.h> > > +#include <linux/of_platform.h> > > > > #include <linux/uaccess.h> > > > > @@ -1683,6 +1685,17 @@ static int tty_release_checks(struct tty_struct *tty, struct tty_struct *o_tty, > > return 0; > > } > > > > +static int open_child(struct device *dev, void *data) > > +{ > > + pm_runtime_get_sync(dev); > > + return 0; > > +} > > +static int release_child(struct device *dev, void *data) > > +{ > > + pm_runtime_put_autosuspend(dev); > > + return 0; > > +} > > + > > /** > > * tty_release - vfs callback for close > > * @inode: inode of tty > > @@ -1712,6 +1725,8 @@ int tty_release(struct inode *inode, struct file *filp) > > long timeout = 0; > > int once = 1; > > > > + if (tty->dev) > > + device_for_each_child(tty->dev, NULL, release_child); > > if (tty_paranoia_check(tty, inode, __func__)) > > return 0; > > > > @@ -2118,6 +2133,8 @@ retry_open: > > __proc_set_tty(current, tty); > > spin_unlock_irq(¤t->sighand->siglock); > > tty_unlock(tty); > > + if (tty->dev) > > + device_for_each_child(tty->dev, NULL, open_child); > > mutex_unlock(&tty_mutex); > > return 0; > > err_unlock: > > @@ -3207,6 +3224,11 @@ struct device *tty_register_device_attr(struct tty_driver *driver, > > retval = device_register(dev); > > if (retval) > > goto error; > > + if (device && device->of_node) > > + /* Children are platform devices and will be > > + * runtime_pm managed by this tty. > > + */ > > + of_platform_populate(device->of_node, NULL, NULL, dev); > > > > return dev; > > > -- > To unsubscribe from this list: send the line "unsubscribe devicetree" in > the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org > More majordomo info at http://vger.kernel.org/majordomo-info.html [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 811 bytes --] ^ permalink raw reply [flat|nested] 34+ messages in thread
[parent not found: <20141212162352.66be5b5e-wvvUuzkyo1EYVZTmpyfIwg@public.gmane.org>]
* Re: [PATCH 1/3] TTY: add support for "tty slave" devices. [not found] ` <20141212162352.66be5b5e-wvvUuzkyo1EYVZTmpyfIwg@public.gmane.org> @ 2014-12-12 13:02 ` Peter Hurley 2014-12-13 14:23 ` One Thousand Gnomes 0 siblings, 1 reply; 34+ messages in thread From: Peter Hurley @ 2014-12-12 13:02 UTC (permalink / raw) To: NeilBrown Cc: Grant Likely, Greg Kroah-Hartman, Mark Rutland, Jiri Slaby, devicetree-u79uwXL29TY76Z2rM5mHXA, linux-kernel-u79uwXL29TY76Z2rM5mHXA On 12/12/2014 12:23 AM, NeilBrown wrote: > On Thu, 11 Dec 2014 18:18:37 -0500 Peter Hurley <peter-WaGBZJeGNqdsbIuE7sb01tBPR1lH4CV8@public.gmane.org> > wrote: > >> On 12/11/2014 04:59 PM, NeilBrown wrote: >>> A "tty slave" is a device connected via UART. >>> It may need a driver to, for example, power the device on >>> when the tty is opened, and power it off when the tty >>> is released. >>> >>> A "tty slave" is a platform device which is declared as a >>> child of the uart in device-tree: >>> >>> &uart1 { >>> bluetooth { >>> compatible = "tty,regulator"; >>> vdd-supply = <&vaux4>; >>> }; >>> }; >>> >>> runtime power management is used to power-up the device >>> on tty_open() and power-down on tty_release(). >> >> I have a couple of issues with this: >> 1) why does a child device imply power management and a platform >> device? iow, what happens when someone else wants to have a >> child device that does something different? > > Why does it imply power management? > Because it seems to make obvious sense to turn something on when the tty is > open. If the device has other reason to remain on when the tty is closed, > it can arrange for extra references to be taken of course. > Is it conceivable that you would want the device to remain off when the > tty device is open? In that case just make it a regular platform device. > > Why a platform device? > Things on an i2c bus are i2c devices. Things on a usb bus are usb devices. > Ideally a thing on a uart 'bus' would be a 'uart device', but no such thing > exists. I did contemplate the possibility of creating an explicit "uart" or > "tty" bus type, but I could find no value in that. > The door is certainly still open to that possibility if a meaning for the > idea becomes apparent. As far as device tree is concerned it is just a > child device node. The fact that it is implemented as a "platform" device > could easily be changed later if needed without device tree noticing. > > What could conceivably want to be different? The only (purely hypothetical) > concept I can come up with which wouldn't fit is a device with both an UART > port and a USB port, or similar. However device tree, and the device model > in general, just isn't geared towards devices being on multiple buses so > if that were real it would have much greater implications that just here. > > But maybe I misunderstand... Yeah, misunderstanding. This patch is using a very generic abstraction (parent-child device association) for a really specific purpose (power management for platform devices). What about PCI, PNP, etc.? Also, what happens for existing child device associations like bluetooth & serio? Why not just provide a serial core interface for associating power-managed child devices? Which brings up another point: why not do this in the runtime power management; ie, turn on the slave device when the master device is turned on? Sebastian recently made the 8250 driver power-managed per access, which would enable significant power savings over just leaving the slave device on the whole time. >> 2) why is this tied to the tty core and not the serial core >> if this is only for UART? > > Because the knowledge of "the device is being opened" or "the device is being > closed" seems to exist in the tty core but not in the serial core. uart_open() = device file is being opened uart_close() = device file is being released > The "of_platform_populate()" call could certainly go in serial_core.c, in > uart_add_one_port() I think. I did have it there originally. I moved it for > a reason that I think is no longer relevant. As the on/off code is (and I > think has to be) in tty_io.c, I left all of it there. > > I'm happy to move it to serial_core.c if that is preferred. > I'll also move the open/close handling if you can point to where it should go. Yes, please. The reverse dependency (tty core => of) is undesirable. Regards, Peter Hurley >>> Signed-off-by: NeilBrown <neilb-l3A5Bk7waGM@public.gmane.org> >>> --- >>> .../devicetree/bindings/serial/of-serial.txt | 4 ++++ >>> drivers/tty/tty_io.c | 22 ++++++++++++++++++++ >>> 2 files changed, 26 insertions(+) >>> >>> diff --git a/Documentation/devicetree/bindings/serial/of-serial.txt b/Documentation/devicetree/bindings/serial/of-serial.txt >>> index 8c4fd0332028..b59501ee2f21 100644 >>> --- a/Documentation/devicetree/bindings/serial/of-serial.txt >>> +++ b/Documentation/devicetree/bindings/serial/of-serial.txt >>> @@ -39,6 +39,10 @@ Optional properties: >>> driver is allowed to detect support for the capability even without this >>> property. >>> >>> +Optional child node: >>> +- a platform device listed as a child node will be probed and >>> + powered-on whenever the tty is in use (open). >>> + >>> Example: >>> >>> uart@80230000 { >>> diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c >>> index 0508a1d8e4cd..7acdc6f093f4 100644 >>> --- a/drivers/tty/tty_io.c >>> +++ b/drivers/tty/tty_io.c >>> @@ -95,6 +95,8 @@ >>> #include <linux/seq_file.h> >>> #include <linux/serial.h> >>> #include <linux/ratelimit.h> >>> +#include <linux/pm_runtime.h> >>> +#include <linux/of_platform.h> >>> >>> #include <linux/uaccess.h> >>> >>> @@ -1683,6 +1685,17 @@ static int tty_release_checks(struct tty_struct *tty, struct tty_struct *o_tty, >>> return 0; >>> } >>> >>> +static int open_child(struct device *dev, void *data) >>> +{ >>> + pm_runtime_get_sync(dev); >>> + return 0; >>> +} >>> +static int release_child(struct device *dev, void *data) >>> +{ >>> + pm_runtime_put_autosuspend(dev); >>> + return 0; >>> +} >>> + >>> /** >>> * tty_release - vfs callback for close >>> * @inode: inode of tty >>> @@ -1712,6 +1725,8 @@ int tty_release(struct inode *inode, struct file *filp) >>> long timeout = 0; >>> int once = 1; >>> >>> + if (tty->dev) >>> + device_for_each_child(tty->dev, NULL, release_child); >>> if (tty_paranoia_check(tty, inode, __func__)) >>> return 0; >>> >>> @@ -2118,6 +2133,8 @@ retry_open: >>> __proc_set_tty(current, tty); >>> spin_unlock_irq(¤t->sighand->siglock); >>> tty_unlock(tty); >>> + if (tty->dev) >>> + device_for_each_child(tty->dev, NULL, open_child); >>> mutex_unlock(&tty_mutex); >>> return 0; >>> err_unlock: >>> @@ -3207,6 +3224,11 @@ struct device *tty_register_device_attr(struct tty_driver *driver, >>> retval = device_register(dev); >>> if (retval) >>> goto error; >>> + if (device && device->of_node) >>> + /* Children are platform devices and will be >>> + * runtime_pm managed by this tty. >>> + */ >>> + of_platform_populate(device->of_node, NULL, NULL, dev); >>> >>> return dev; -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH 1/3] TTY: add support for "tty slave" devices. 2014-12-12 13:02 ` Peter Hurley @ 2014-12-13 14:23 ` One Thousand Gnomes [not found] ` <20141213142344.61372b92-qBU/x9rampVanCEyBjwyrvXRex20P6io@public.gmane.org> 0 siblings, 1 reply; 34+ messages in thread From: One Thousand Gnomes @ 2014-12-13 14:23 UTC (permalink / raw) To: Peter Hurley Cc: NeilBrown, Grant Likely, Greg Kroah-Hartman, Mark Rutland, Jiri Slaby, devicetree, linux-kernel On Fri, 12 Dec 2014 08:02:48 -0500 > Which brings up another point: why not do this in the runtime power management; > ie, turn on the slave device when the master device is turned on? Sebastian > recently made the 8250 driver power-managed per access, which would enable > significant power savings over just leaving the slave device on the whole time. That per access model only works on 8250 (in fact only on some 8250). On most devices if the UART is in low power you lose bytes send to it rather than then queuing up anywhere. It doesn't handle cases where you need to keep power on to different rules (for example there are cases where you do things like power the uart down after no bits have been received for 'n' millseconds). Right now if you look into Androidspace you'll find people doing this in userspace by having the sysfs node open and playing crazy games with sysfs, Android glue hacks and gpio poking via the gpio sysfs/gpio lib routines. Good example is some of the GPS and serial based sensor chips. The latency of tty open/close is unacceptable and risks losing bits so they keep the tty open and whack the power management by hand right now. The kind of thing many of them want is stuff like "hold power on until we see receive data, then keep it on until it shuts up for a bit" "assert gpio, send, receive, wait idle, drop gpio" "on GPIO interrupt wake uart, wait for data, when idle, power uart down" > >> 2) why is this tied to the tty core and not the serial core > >> if this is only for UART? > > > > Because the knowledge of "the device is being opened" or "the device is being > > closed" seems to exist in the tty core but not in the serial core. > > uart_open() = device file is being opened > uart_close() = device file is being released Only for a subset of uart type devices that use the uart layer. Quite a few don't, including all the USB ones, and the sd ones. > > I'm happy to move it to serial_core.c if that is preferred. > > I'll also move the open/close handling if you can point to where it should go. > > Yes, please. NAK - I certainly object to it being moved to uart. That's the wrong abstraction layer for this. It's a generic behaviour, it's a tty level behaviour without any uart specific properties. It should work for uarts that don't use the legacy serial_core code, uarts that do, uarts that use USB, uarts that are directly connected to things like sdio etc. That means it has to be tty layer. Alan ^ permalink raw reply [flat|nested] 34+ messages in thread
[parent not found: <20141213142344.61372b92-qBU/x9rampVanCEyBjwyrvXRex20P6io@public.gmane.org>]
* Re: [PATCH 1/3] TTY: add support for "tty slave" devices. [not found] ` <20141213142344.61372b92-qBU/x9rampVanCEyBjwyrvXRex20P6io@public.gmane.org> @ 2014-12-16 16:14 ` Peter Hurley 0 siblings, 0 replies; 34+ messages in thread From: Peter Hurley @ 2014-12-16 16:14 UTC (permalink / raw) To: One Thousand Gnomes Cc: NeilBrown, Grant Likely, Greg Kroah-Hartman, Mark Rutland, Jiri Slaby, devicetree-u79uwXL29TY76Z2rM5mHXA, linux-kernel-u79uwXL29TY76Z2rM5mHXA On 12/13/2014 09:23 AM, One Thousand Gnomes wrote: > On Fri, 12 Dec 2014 08:02:48 -0500 >> Which brings up another point: why not do this in the runtime power management; >> ie, turn on the slave device when the master device is turned on? Sebastian >> recently made the 8250 driver power-managed per access, which would enable >> significant power savings over just leaving the slave device on the whole time. > > That per access model only works on 8250 (in fact only on some 8250). On > most devices if the UART is in low power you lose bytes send to it rather > than then queuing up anywhere. > > It doesn't handle cases where you need to keep power on to different rules > (for example there are cases where you do things like power the uart down > after no bits have been received for 'n' millseconds). Right now if you > look into Androidspace you'll find people doing this in userspace by > having the sysfs node open and playing crazy games with sysfs, Android > glue hacks and gpio poking via the gpio sysfs/gpio lib routines. > > Good example is some of the GPS and serial based sensor chips. The > latency of tty open/close is unacceptable and risks losing bits so they > keep the tty open and whack the power management by hand right now. > > The kind of thing many of them want is stuff like > > "hold power on until we see receive data, then keep it on until it shuts > up for a bit" > > "assert gpio, send, receive, wait idle, drop gpio" > > "on GPIO interrupt wake uart, wait for data, when idle, power uart down" > >>>> 2) why is this tied to the tty core and not the serial core >>>> if this is only for UART? >>> >>> Because the knowledge of "the device is being opened" or "the device is being >>> closed" seems to exist in the tty core but not in the serial core. >> >> uart_open() = device file is being opened >> uart_close() = device file is being released > > Only for a subset of uart type devices that use the uart layer. Quite a > few don't, including all the USB ones, and the sd ones. > >>> I'm happy to move it to serial_core.c if that is preferred. >>> I'll also move the open/close handling if you can point to where it should go. >> >> Yes, please. > > NAK - I certainly object to it being moved to uart. That's the wrong > abstraction layer for this. It's a generic behaviour, it's a tty level > behaviour without any uart specific properties. It should work for uarts > that don't use the legacy serial_core code, uarts that do, uarts that use > USB, uarts that are directly connected to things like sdio etc. > > That means it has to be tty layer. I was reviewing the patch submitted, which does none of the things you outlined and does not provide the necessary infrastructure to build upon it. I'm all for the functionality you describe but I think that design will end up subsystem-agnostic. Regards, Peter Hurley -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH 1/3] TTY: add support for "tty slave" devices. [not found] ` <548A264D.8070103-WaGBZJeGNqdsbIuE7sb01tBPR1lH4CV8@public.gmane.org> 2014-12-12 5:23 ` NeilBrown @ 2014-12-13 14:12 ` One Thousand Gnomes 1 sibling, 0 replies; 34+ messages in thread From: One Thousand Gnomes @ 2014-12-13 14:12 UTC (permalink / raw) To: Peter Hurley Cc: NeilBrown, Grant Likely, Greg Kroah-Hartman, Mark Rutland, Jiri Slaby, devicetree-u79uwXL29TY76Z2rM5mHXA, linux-kernel-u79uwXL29TY76Z2rM5mHXA > 2) why is this tied to the tty core and not the serial core > if this is only for UART? I'm a bit baffled why you would try and tie it to serial core given that serial core only covers a random subset of the uart drivers we have. If we have a USB connected device with USB gpio lines doing power management then it needs to be tied tty core. -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH 1/3] TTY: add support for "tty slave" devices. 2014-12-11 21:59 ` [PATCH 1/3] TTY: add support for "tty slave" devices NeilBrown [not found] ` <20141211215943.4127.24792.stgit-wvvUuzkyo1EYVZTmpyfIwg@public.gmane.org> @ 2014-12-12 11:59 ` Grant Likely 2014-12-13 17:46 ` Sebastian Reichel 2014-12-28 14:20 ` Pavel Machek 2 siblings, 1 reply; 34+ messages in thread From: Grant Likely @ 2014-12-12 11:59 UTC (permalink / raw) To: NeilBrown, Greg Kroah-Hartman, Mark Rutland, Jiri Slaby Cc: devicetree, linux-kernel On Fri, 12 Dec 2014 08:59:44 +1100 , NeilBrown <neilb@suse.de> wrote: > A "tty slave" is a device connected via UART. > It may need a driver to, for example, power the device on > when the tty is opened, and power it off when the tty > is released. Some nit picking below, mostly about avoiding nasty surprises on devices that may already have child nodes below the tty node. > > A "tty slave" is a platform device which is declared as a > child of the uart in device-tree: As far as the binding is concerned, talking about platform devices isn't relevant. That's an implementation detail. They are just devices. Using a platform device is somewhat problematic for the kernel because the DT could specify pretty much *any* platform device compatible value here and the kernel will happily bind a driver to it. I strongly recommend a separate bus type so that the pool of drivers remains separate. It would be a good time to look at platform_bus_type and see if more of it can be generalized so that subsystems can have custom bus types without very much code at all. > > &uart1 { > bluetooth { > compatible = "tty,regulator"; > vdd-supply = <&vaux4>; > }; The example here isn't great. The compatible value should specify the specific device, not a generic "tty,regulator" type binding. The expectation is the driver understands the attachment and understands how to do PM on the device. > }; > > runtime power management is used to power-up the device > on tty_open() and power-down on tty_release(). What about devices that need to stay powered up even if the tty is not opened? The runtime PM model needs to be better described for tty slaves. > > Signed-off-by: NeilBrown <neilb@suse.de> > --- > .../devicetree/bindings/serial/of-serial.txt | 4 ++++ > drivers/tty/tty_io.c | 22 ++++++++++++++++++++ > 2 files changed, 26 insertions(+) > > diff --git a/Documentation/devicetree/bindings/serial/of-serial.txt b/Documentation/devicetree/bindings/serial/of-serial.txt > index 8c4fd0332028..b59501ee2f21 100644 > --- a/Documentation/devicetree/bindings/serial/of-serial.txt > +++ b/Documentation/devicetree/bindings/serial/of-serial.txt > @@ -39,6 +39,10 @@ Optional properties: > driver is allowed to detect support for the capability even without this > property. > > +Optional child node: > +- a platform device listed as a child node will be probed and > + powered-on whenever the tty is in use (open). > + The biggest concern I have is what happens to nodes that already have child devices that /don't/ match this use case? It is possible that some UART nodes already have a child node used to store other data. There are two ways to handle this; 1) add a new bool property that indicates the child nodes are tty slave devices, or 2) Make each uart driver explicitly enable the feature so that driver authors can check if it is a problem for that device. I personally would suggest #1 because then it can be enabled in generic code. > Example: > > uart@80230000 { > diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c > index 0508a1d8e4cd..7acdc6f093f4 100644 > --- a/drivers/tty/tty_io.c > +++ b/drivers/tty/tty_io.c > @@ -95,6 +95,8 @@ > #include <linux/seq_file.h> > #include <linux/serial.h> > #include <linux/ratelimit.h> > +#include <linux/pm_runtime.h> > +#include <linux/of_platform.h> > > #include <linux/uaccess.h> > > @@ -1683,6 +1685,17 @@ static int tty_release_checks(struct tty_struct *tty, struct tty_struct *o_tty, > return 0; > } > > +static int open_child(struct device *dev, void *data) > +{ > + pm_runtime_get_sync(dev); > + return 0; > +} > +static int release_child(struct device *dev, void *data) > +{ > + pm_runtime_put_autosuspend(dev); > + return 0; > +} > + > /** > * tty_release - vfs callback for close > * @inode: inode of tty > @@ -1712,6 +1725,8 @@ int tty_release(struct inode *inode, struct file *filp) > long timeout = 0; > int once = 1; > > + if (tty->dev) > + device_for_each_child(tty->dev, NULL, release_child); > if (tty_paranoia_check(tty, inode, __func__)) > return 0; > > @@ -2118,6 +2133,8 @@ retry_open: > __proc_set_tty(current, tty); > spin_unlock_irq(¤t->sighand->siglock); > tty_unlock(tty); > + if (tty->dev) > + device_for_each_child(tty->dev, NULL, open_child); > mutex_unlock(&tty_mutex); > return 0; > err_unlock: > @@ -3207,6 +3224,11 @@ struct device *tty_register_device_attr(struct tty_driver *driver, > retval = device_register(dev); > if (retval) > goto error; > + if (device && device->of_node) > + /* Children are platform devices and will be > + * runtime_pm managed by this tty. > + */ > + of_platform_populate(device->of_node, NULL, NULL, dev); Also need to remove all the tty slaves on driver unbind. > > return dev; > > > ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH 1/3] TTY: add support for "tty slave" devices. 2014-12-12 11:59 ` Grant Likely @ 2014-12-13 17:46 ` Sebastian Reichel 2014-12-13 22:22 ` Grant Likely 0 siblings, 1 reply; 34+ messages in thread From: Sebastian Reichel @ 2014-12-13 17:46 UTC (permalink / raw) To: Grant Likely Cc: NeilBrown, Greg Kroah-Hartman, Mark Rutland, Jiri Slaby, devicetree, linux-kernel [-- Attachment #1: Type: text/plain, Size: 1238 bytes --] Hi, On Fri, Dec 12, 2014 at 11:59:20AM +0000, Grant Likely wrote: > [...] > > --- a/Documentation/devicetree/bindings/serial/of-serial.txt > > +++ b/Documentation/devicetree/bindings/serial/of-serial.txt > > @@ -39,6 +39,10 @@ Optional properties: > > driver is allowed to detect support for the capability even without this > > property. > > > > +Optional child node: > > +- a platform device listed as a child node will be probed and > > + powered-on whenever the tty is in use (open). > > + > > The biggest concern I have is what happens to nodes that already have > child devices that /don't/ match this use case? It is possible that some > UART nodes already have a child node used to store other data. There are > two ways to handle this; 1) add a new bool property that indicates the > child nodes are tty slave devices, or 2) Make each uart driver > explicitly enable the feature so that driver authors can check if it is > a problem for that device. I personally would suggest #1 because then it > can be enabled in generic code. maybe simple depend on the compatible value? If the UART node has child nodes to store other random data it should not have a compatible value? -- Sebastian [-- Attachment #2: Digital signature --] [-- Type: application/pgp-signature, Size: 819 bytes --] ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH 1/3] TTY: add support for "tty slave" devices. 2014-12-13 17:46 ` Sebastian Reichel @ 2014-12-13 22:22 ` Grant Likely 0 siblings, 0 replies; 34+ messages in thread From: Grant Likely @ 2014-12-13 22:22 UTC (permalink / raw) To: Sebastian Reichel Cc: NeilBrown, Greg Kroah-Hartman, Mark Rutland, Jiri Slaby, devicetree@vger.kernel.org, Linux Kernel Mailing List On Sat, Dec 13, 2014 at 5:46 PM, Sebastian Reichel <sre@kernel.org> wrote: > Hi, > > On Fri, Dec 12, 2014 at 11:59:20AM +0000, Grant Likely wrote: >> [...] >> > --- a/Documentation/devicetree/bindings/serial/of-serial.txt >> > +++ b/Documentation/devicetree/bindings/serial/of-serial.txt >> > @@ -39,6 +39,10 @@ Optional properties: >> > driver is allowed to detect support for the capability even without this >> > property. >> > >> > +Optional child node: >> > +- a platform device listed as a child node will be probed and >> > + powered-on whenever the tty is in use (open). >> > + >> >> The biggest concern I have is what happens to nodes that already have >> child devices that /don't/ match this use case? It is possible that some >> UART nodes already have a child node used to store other data. There are >> two ways to handle this; 1) add a new bool property that indicates the >> child nodes are tty slave devices, or 2) Make each uart driver >> explicitly enable the feature so that driver authors can check if it is >> a problem for that device. I personally would suggest #1 because then it >> can be enabled in generic code. > > maybe simple depend on the compatible value? If the UART node has > child nodes to store other random data it should not have a > compatible value? That's not a given. It is entirely possible that drivers have used compatible in the child nodes. However, I may be stirring up trouble for nothing. We could enable it for all child nodes that have a compatible value, and then blacklist any parent nodes that want to use a different behaviour. If someone complains then we will fix it. g. ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH 1/3] TTY: add support for "tty slave" devices. 2014-12-11 21:59 ` [PATCH 1/3] TTY: add support for "tty slave" devices NeilBrown [not found] ` <20141211215943.4127.24792.stgit-wvvUuzkyo1EYVZTmpyfIwg@public.gmane.org> 2014-12-12 11:59 ` Grant Likely @ 2014-12-28 14:20 ` Pavel Machek 2015-01-02 21:33 ` NeilBrown 2 siblings, 1 reply; 34+ messages in thread From: Pavel Machek @ 2014-12-28 14:20 UTC (permalink / raw) To: NeilBrown Cc: Grant Likely, Greg Kroah-Hartman, Mark Rutland, Jiri Slaby, devicetree, linux-kernel Hi! > index 8c4fd0332028..b59501ee2f21 100644 > --- a/Documentation/devicetree/bindings/serial/of-serial.txt > +++ b/Documentation/devicetree/bindings/serial/of-serial.txt > @@ -39,6 +39,10 @@ Optional properties: > driver is allowed to detect support for the capability even without this > property. > > +Optional child node: > +- a platform device listed as a child node will be probed and > + powered-on whenever the tty is in use (open). > + > Example: > > uart@80230000 { Hmm. Other devices may want it the other way around: probe the device behind the uart, make it control power and open/close of the uart, and hide the /dev/ttyXX from userspace... Pavel -- (english) http://www.livejournal.com/~pavelmachek (cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH 1/3] TTY: add support for "tty slave" devices. 2014-12-28 14:20 ` Pavel Machek @ 2015-01-02 21:33 ` NeilBrown 2015-01-04 10:18 ` Pavel Machek 2015-01-05 15:41 ` One Thousand Gnomes 0 siblings, 2 replies; 34+ messages in thread From: NeilBrown @ 2015-01-02 21:33 UTC (permalink / raw) To: Pavel Machek Cc: Grant Likely, Greg Kroah-Hartman, Mark Rutland, Jiri Slaby, devicetree, linux-kernel [-- Attachment #1: Type: text/plain, Size: 3197 bytes --] On Sun, 28 Dec 2014 15:20:10 +0100 Pavel Machek <pavel@ucw.cz> wrote: > Hi! > > > index 8c4fd0332028..b59501ee2f21 100644 > > --- a/Documentation/devicetree/bindings/serial/of-serial.txt > > +++ b/Documentation/devicetree/bindings/serial/of-serial.txt > > @@ -39,6 +39,10 @@ Optional properties: > > driver is allowed to detect support for the capability even without this > > property. > > > > +Optional child node: > > +- a platform device listed as a child node will be probed and > > + powered-on whenever the tty is in use (open). > > + > > Example: > > > > uart@80230000 { > > Hmm. Other devices may want it the other way around: probe the device > behind the uart, make it control power and open/close of the uart, and > hide the /dev/ttyXX from userspace... > Pavel > I've been thinking a bit about this. The current "tty" seems to be a combination of two things: - a line discipline - a char_dev But some line disciplines don't really want the char_dev. N_MOUSE wants a serio device. N_HCI wants an HCI device N_GSM07010 wants 63 different tty char_devs. N_IRDA and N_PPP ultimately want a net_dev. etc. It would be really nice if the uart would register the line disciple as a child device, then the line discipline would register whatever it wants. Then if a uart had no children, it would register the 'N_TTY' line discipline and get a tty char_dev. If it had a child, it would probe the child device and leave it to register and appropriate line discipline. The child device could interpose itself in the control flow somehow so my driver could add power control at open/close. But that isn't how it works. The line discipline doesn't talk to the uart. Rather the tty layer talks to the uart (through tty_operations) and to the line discipline (through tty_ldisc_ops) and also registers the char_dev. One of the several difficulties with allowing a child device to select a line discipline is the different line disciplines activate differently. N_HCI activates (registers the hci dev) on HCIUARTSETPROTO ioctl. A child device would need a way to specify the protocol I resume. N_MOUSE activates on a 'read' on the tty - and deactivates when the read completes. N_GSM0710 activates immediately that the ldisc is activated, as does N_IRDA N_PPP seems to want a PPPIOCNEWUNIT ioctl to fully register. Doing any of these in a driver for a uart slave device would certainly be possible. I wonder if it is something we really want to do in the kernel though. What is the gain over providing sufficient information in the KOBJ_ADD uevent so that udev can do the required work in user-space? I'm not against the idea, I am just finding it hard to justify. However I do like the idea of having the UART probe the child instead of registering a tty. It could pass the tty_operations structure to the child, and the child could then register a tty with a slightly different tty_operations structure, allowing it to capture any operations that it wants to capture (such as open/close). I might try coding that and see what it looks like... Thanks, NeilBrown [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 811 bytes --] ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH 1/3] TTY: add support for "tty slave" devices. 2015-01-02 21:33 ` NeilBrown @ 2015-01-04 10:18 ` Pavel Machek 2015-01-05 7:09 ` NeilBrown 2015-01-05 15:41 ` One Thousand Gnomes 1 sibling, 1 reply; 34+ messages in thread From: Pavel Machek @ 2015-01-04 10:18 UTC (permalink / raw) To: NeilBrown Cc: Grant Likely, Greg Kroah-Hartman, Mark Rutland, Jiri Slaby, devicetree, linux-kernel Hi! > > > +Optional child node: > > > +- a platform device listed as a child node will be probed and > > > + powered-on whenever the tty is in use (open). > > > + > > > Example: > > > > > > uart@80230000 { > > > But some line disciplines don't really want the char_dev. > N_MOUSE wants a serio device. > N_HCI wants an HCI device > N_GSM07010 wants 63 different tty char_devs. > N_IRDA and N_PPP ultimately want a net_dev. > etc. > > It would be really nice if the uart would register the line disciple as a > child device, then the line discipline would register whatever it wants. Yes. > N_HCI activates (registers the hci dev) on HCIUARTSETPROTO ioctl. A child > device would need a way to specify the protocol I resume. > N_MOUSE activates on a 'read' on the tty - and deactivates when the read > completes. > N_GSM0710 activates immediately that the ldisc is activated, as does N_IRDA > N_PPP seems to want a PPPIOCNEWUNIT ioctl to fully register. > > Doing any of these in a driver for a uart slave device would certainly be > possible. I wonder if it is something we really want to do in the kernel > though. What is the gain over providing sufficient information in the > KOBJ_ADD uevent so that udev can do the required work in user-space? Consistency. If you have bluetooth on USB, it automatically works, without userspace help. If we have mouse on USB, it automatically works, etc... > However I do like the idea of having the UART probe the child instead of > registering a tty. It could pass the tty_operations structure to the child, > and the child could then register a tty with a slightly different > tty_operations structure, allowing it to capture any operations that it wants > to capture (such as open/close). > I might try coding that and see what it looks like... Lets have a look... Pavel -- (english) http://www.livejournal.com/~pavelmachek (cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH 1/3] TTY: add support for "tty slave" devices. 2015-01-04 10:18 ` Pavel Machek @ 2015-01-05 7:09 ` NeilBrown [not found] ` <20150105200936.2ba8f596-wvvUuzkyo1EYVZTmpyfIwg@public.gmane.org> 0 siblings, 1 reply; 34+ messages in thread From: NeilBrown @ 2015-01-05 7:09 UTC (permalink / raw) To: Pavel Machek Cc: Grant Likely, Greg Kroah-Hartman, Mark Rutland, Jiri Slaby, devicetree-u79uwXL29TY76Z2rM5mHXA, linux-kernel-u79uwXL29TY76Z2rM5mHXA [-- Attachment #1: Type: text/plain, Size: 2431 bytes --] On Sun, 4 Jan 2015 11:18:47 +0100 Pavel Machek <pavel-+ZI9xUNit7I@public.gmane.org> wrote: > Hi! > > > > > +Optional child node: > > > > +- a platform device listed as a child node will be probed and > > > > + powered-on whenever the tty is in use (open). > > > > + > > > > Example: > > > > > > > > uart@80230000 { > > > > > > But some line disciplines don't really want the char_dev. > > N_MOUSE wants a serio device. > > N_HCI wants an HCI device > > N_GSM07010 wants 63 different tty char_devs. > > N_IRDA and N_PPP ultimately want a net_dev. > > etc. > > > > It would be really nice if the uart would register the line disciple as a > > child device, then the line discipline would register whatever it wants. > > Yes. > > > N_HCI activates (registers the hci dev) on HCIUARTSETPROTO ioctl. A child > > device would need a way to specify the protocol I resume. > > N_MOUSE activates on a 'read' on the tty - and deactivates when the read > > completes. > > N_GSM0710 activates immediately that the ldisc is activated, as does N_IRDA > > N_PPP seems to want a PPPIOCNEWUNIT ioctl to fully register. > > > > Doing any of these in a driver for a uart slave device would certainly be > > possible. I wonder if it is something we really want to do in the kernel > > though. What is the gain over providing sufficient information in the > > KOBJ_ADD uevent so that udev can do the required work in user-space? > > Consistency. If you have bluetooth on USB, it automatically works, > without userspace help. If we have mouse on USB, it automatically > works, etc... My point is: why is the kernel/userspace distinction important? As long as it "automatically works", does it really matter where the code is? We can put a little bit of code in the kernel (to report the details of the attached device) and a little bit of code in udev (to run hciattach) and it will still be automatic. NeilBrown > > > However I do like the idea of having the UART probe the child instead of > > registering a tty. It could pass the tty_operations structure to the child, > > and the child could then register a tty with a slightly different > > tty_operations structure, allowing it to capture any operations that it wants > > to capture (such as open/close). > > I might try coding that and see what it looks like... > > Lets have a look... > Pavel [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 811 bytes --] ^ permalink raw reply [flat|nested] 34+ messages in thread
[parent not found: <20150105200936.2ba8f596-wvvUuzkyo1EYVZTmpyfIwg@public.gmane.org>]
* Re: [PATCH 1/3] TTY: add support for "tty slave" devices. [not found] ` <20150105200936.2ba8f596-wvvUuzkyo1EYVZTmpyfIwg@public.gmane.org> @ 2015-01-05 13:43 ` Pavel Machek 0 siblings, 0 replies; 34+ messages in thread From: Pavel Machek @ 2015-01-05 13:43 UTC (permalink / raw) To: NeilBrown Cc: Grant Likely, Greg Kroah-Hartman, Mark Rutland, Jiri Slaby, devicetree-u79uwXL29TY76Z2rM5mHXA, linux-kernel-u79uwXL29TY76Z2rM5mHXA Hi! > > > N_HCI activates (registers the hci dev) on HCIUARTSETPROTO ioctl. A child > > > device would need a way to specify the protocol I resume. > > > N_MOUSE activates on a 'read' on the tty - and deactivates when the read > > > completes. > > > N_GSM0710 activates immediately that the ldisc is activated, as does N_IRDA > > > N_PPP seems to want a PPPIOCNEWUNIT ioctl to fully register. > > > > > > Doing any of these in a driver for a uart slave device would certainly be > > > possible. I wonder if it is something we really want to do in the kernel > > > though. What is the gain over providing sufficient information in the > > > KOBJ_ADD uevent so that udev can do the required work in user-space? > > > > Consistency. If you have bluetooth on USB, it automatically works, > > without userspace help. If we have mouse on USB, it automatically > > works, etc... > > My point is: why is the kernel/userspace distinction important? As long as > it "automatically works", does it really matter where the code is? For some cases, it does, as "devices needed during boot". Someone is going to attach keyboard or something powermanagement related, sooner or later. > We can put a little bit of code in the kernel (to report the details of the > attached device) and a little bit of code in udev (to run hciattach) and it > will still be automatic. Of course, that's also possible. There will be parameters such as speed / parity / flow control that will need to be passed, and userland will still see /dev/ttySX device that it perhaps does not need to see. And there will be problems with devices such as bcm2048 on Nokia, which is connected by a serial line and (interrupt capable) GPIO lines and clocks. Rather than extending hciattach to pass the neccessary GPIO/clock information and extending udev to pass GPIO/clock information to hciattach (and extending kernel to pass it to udev and accept from hciattach), it makes sense to just do it internally. Pavel -- (english) http://www.livejournal.com/~pavelmachek (cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH 1/3] TTY: add support for "tty slave" devices. 2015-01-02 21:33 ` NeilBrown 2015-01-04 10:18 ` Pavel Machek @ 2015-01-05 15:41 ` One Thousand Gnomes 2015-01-05 16:28 ` Pavel Machek 1 sibling, 1 reply; 34+ messages in thread From: One Thousand Gnomes @ 2015-01-05 15:41 UTC (permalink / raw) To: NeilBrown Cc: Pavel Machek, Grant Likely, Greg Kroah-Hartman, Mark Rutland, Jiri Slaby, devicetree, linux-kernel > It would be really nice if the uart would register the line disciple as a > child device, then the line discipline would register whatever it wants. For almost every case this doesn't work. You need a tty interface as well because thats how you manage it. > But that isn't how it works. The line discipline doesn't talk to the uart. > Rather the tty layer talks to the uart (through tty_operations) and to the > line discipline (through tty_ldisc_ops) and also registers the char_dev. This is intentional. An ldisc has no business knowing what it's connected to. Try running bluetooth over a tty/pty pair remotely to a dongle - and you can do it or faking a GSM mux over a tty/pty pair for testing. There are lots of cases where we know the correct ldisc from information in the ACPI, DT or even USB identifiers in order to plug in the right ldisc and daemon but I think that pretty much has to be in user space. The kernel might be able to set an ldisc but it can't go around starting bluetooth daemons, doing modem chats to go into mux mode or firing up JMRI and java when it sees a Sprog. That's a job for systemd/udev. Alan ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH 1/3] TTY: add support for "tty slave" devices. 2015-01-05 15:41 ` One Thousand Gnomes @ 2015-01-05 16:28 ` Pavel Machek 0 siblings, 0 replies; 34+ messages in thread From: Pavel Machek @ 2015-01-05 16:28 UTC (permalink / raw) To: One Thousand Gnomes Cc: NeilBrown, Grant Likely, Greg Kroah-Hartman, Mark Rutland, Jiri Slaby, devicetree, linux-kernel On Mon 2015-01-05 15:41:41, One Thousand Gnomes wrote: > > It would be really nice if the uart would register the line disciple as a > > child device, then the line discipline would register whatever it wants. > > For almost every case this doesn't work. You need a tty interface as well > because thats how you manage it. > > > But that isn't how it works. The line discipline doesn't talk to the uart. > > Rather the tty layer talks to the uart (through tty_operations) and to the > > line discipline (through tty_ldisc_ops) and also registers the char_dev. > > This is intentional. An ldisc has no business knowing what it's connected > to. Try running bluetooth over a tty/pty pair remotely to a dongle - and > you can do it or faking a GSM mux over a tty/pty pair for testing. Not all cases are like that. IIRC Neil's hardware uses CTS/RTS in an interesting way. bc2048 is connected to serial+clocks+gpios... > There are lots of cases where we know the correct ldisc from information > in the ACPI, DT or even USB identifiers in order to plug in the right > ldisc and daemon but I think that pretty much has to be in user space. > The kernel might be able to set an ldisc but it can't go around starting > bluetooth daemons, doing modem chats to go into mux mode or firing up > JMRI and java when it sees a Sprog. That's a job for systemd/udev. No need to start bluetooth daemons: userspace can start them itself. Just like in btusb case. Pavel -- (english) http://www.livejournal.com/~pavelmachek (cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html ^ permalink raw reply [flat|nested] 34+ messages in thread
* [PATCH 3/3] TTY/slave: add driver for w2sg0004 GPS 2014-12-11 21:59 [PATCH 0/3] Add support for 'tty-slaves' described by devicetree NeilBrown 2014-12-11 21:59 ` [PATCH 2/3] TTY: add slave driver to power-on device via a regulator NeilBrown 2014-12-11 21:59 ` [PATCH 1/3] TTY: add support for "tty slave" devices NeilBrown @ 2014-12-11 21:59 ` NeilBrown [not found] ` <20141211215944.4127.57146.stgit-wvvUuzkyo1EYVZTmpyfIwg@public.gmane.org> 2014-12-12 12:11 ` Grant Likely 2 siblings, 2 replies; 34+ messages in thread From: NeilBrown @ 2014-12-11 21:59 UTC (permalink / raw) To: Grant Likely, Greg Kroah-Hartman, Mark Rutland, Jiri Slaby Cc: NeilBrown, devicetree, linux-kernel This uart-attatched GPS device has a toggle which turns both on and off. For reliable use we need to know what start it is in. So it registers with the tty for recv events when the tty is open, and optionally configures the RX pin as a GPIO interrupt when the tty is closed. If it detects data when it should be off, or a lack of data when it should be on, it toggles the line. A regulator can also be configured to power the antenna. In this case an rfkill device is created. When the rfkill is 'blocked' or the device is otherwise powered down, the regulator is turned off. Signed-off-by: NeilBrown <neil@brown.name> --- .../devicetree/bindings/serial/slave-w2sg0004.txt | 35 ++ drivers/tty/slaves/Kconfig | 6 drivers/tty/slaves/Makefile | 3 drivers/tty/slaves/tty-w2sg0004.c | 412 ++++++++++++++++++++ 4 files changed, 455 insertions(+), 1 deletion(-) create mode 100644 Documentation/devicetree/bindings/serial/slave-w2sg0004.txt create mode 100644 drivers/tty/slaves/tty-w2sg0004.c diff --git a/Documentation/devicetree/bindings/serial/slave-w2sg0004.txt b/Documentation/devicetree/bindings/serial/slave-w2sg0004.txt new file mode 100644 index 000000000000..c9e7838b3198 --- /dev/null +++ b/Documentation/devicetree/bindings/serial/slave-w2sg0004.txt @@ -0,0 +1,35 @@ +w2sg0004 UART-attached GPS receiver + +Required properties: +- compatbile: "tty,w2sg0004" +- gpios: gpio used to toggle 'on/off' pin +- interrupts: interrupt generated by RX pin when device should + be idle +- pinctrl: "default", "idle" + "idle" setting is active when device should be off. + This can remap the RX pin to a GPIO interrupt. + +Optional properties: +- vdd-supply: regulator, e.g. to power antenna + + +The w2sg0004 uses a pin-toggle both to power-on and to +power-off, so the driver needs to detect what state it is in. +It does this by detecting characters on the RX line. +When it should be off, these can optionally be detected by a GPIO. + +The node for this device must be the child of a UART. + +Example: +&uart2 { + gps { + compatible = "tty,w2sg0004"; + vdd-supply = <&vsim>; + gpios = <&gpio5 17 0>; /* GPIO_145 */ + interrupts-extended = <&gpio5 19 0>; /* GPIO_147 */ + /* When idle, switch RX to be an interrupt */ + pinctrl-names = "default", "idle"; + pinctrl-0 = <&uart2_pins>; + pinctrl-1 = <&uart2_pins_rx_gpio>; + }; +}; diff --git a/drivers/tty/slaves/Kconfig b/drivers/tty/slaves/Kconfig index 2dd1acf80f8c..7a669faaf02d 100644 --- a/drivers/tty/slaves/Kconfig +++ b/drivers/tty/slaves/Kconfig @@ -9,4 +9,10 @@ if TTY_SLAVE config TTY_SLAVE_REGULATOR tristate "TTY slave device powered by regulator" +config TTY_SLAVE_W2SG0004 + tristate "W2SG0004 GPS on/off control" + help + Enable on/off control of W2SG0004 GPS when attached + to a UART. + endif diff --git a/drivers/tty/slaves/Makefile b/drivers/tty/slaves/Makefile index e636bf49f1cc..ba528fa27110 100644 --- a/drivers/tty/slaves/Makefile +++ b/drivers/tty/slaves/Makefile @@ -1,2 +1,3 @@ -obj-$(CONFIG_TTY_SLAVE_REGULATOR) += tty-reg.o +obj-$(CONFIG_TTY_SLAVE_REGULATOR) += tty-reg.o +obj-$(CONFIG_TTY_SLAVE_W2SG0004) += tty-w2sg0004.o diff --git a/drivers/tty/slaves/tty-w2sg0004.c b/drivers/tty/slaves/tty-w2sg0004.c new file mode 100644 index 000000000000..7c7ae479bf41 --- /dev/null +++ b/drivers/tty/slaves/tty-w2sg0004.c @@ -0,0 +1,412 @@ +/* + * tty-w2sg0004.c - tty-slave for w2sg0004 GPS device + * + * Copyright (C) 2014 NeilBrown <neil@brown.name> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * The w2sg0004 is turned 'on' or 'off' by toggling a line, which + * is normally connected to a GPIO. Thus you need to know the current + * state in order to determine how to achieve some particular state. + * The only way to detect the state is by detecting transitions on + * its TX line (our RX line). + * So this tty slave listens for 'recv' events and deduces the GPS is + * on if it has received one recently. + * If suitably configure, and if the hardware is capable, it also + * enables an interrupt (presumably via a GPIO connected to the RX + * line via pinctrl) when the tty is inactive and treat and interrupts + * as an indication that the device is 'on' and should be turned 'off'. + * + * Driver also listens for open/close and trys to turn the GPS on if it is + * off and the tty is open. On final 'close', the GPS is then turned + * off. + * + * When the device is opened, the GPIO is toggled immediately and then + * again after 2 seconds of no data. If there is still no data the + * toggle happens are 4, 8, 16 seconds etc. + * + * When the device is closed, the GPIO is toggled immediately and + * if interrupts are received after 1 second it is toggled again + * (and again and again with exponentially increasing delays while + * interrupts continue). + * + * If a regulator is configured (e.g. to power the antenna), that is + * enabled/disabled on open/close. + * + * During system suspend the GPS is turned off even if the tty is + * open. No repeat attempts are made. + * Possibly it should be possible to keep the GPS on with some + * configuration. + */ + +#include <linux/module.h> +#include <linux/slab.h> +#include <linux/err.h> +#include <linux/regulator/consumer.h> +#include <linux/gpio.h> +#include <linux/of_gpio.h> +#include <linux/interrupt.h> +#include <linux/platform_device.h> +#include <linux/tty.h> +#include <linux/delay.h> +#include <linux/pm_runtime.h> +#include <linux/rfkill.h> + +struct w2sg_data { + int gpio; + int irq; /* irq line from RX pin when pinctrl + * set to 'idle' */ + struct regulator *reg; + + unsigned long last_toggle; /* jiffies when last toggle completed. */ + unsigned long backoff; /* jiffies since last_toggle when + * we try again + */ + enum {Idle, Down, Up} state; /* state-machine state. */ + bool requested, is_on; + bool suspended; + bool reg_enabled; + + struct delayed_work work; + spinlock_t lock; + struct device *dev; + + struct rfkill *rfkill; +}; + +/* + * There seems to restrictions on how quickly we can toggle the + * on/off line. Data sheets says "two rtc ticks", whatever that means. + * If we do it too soon it doesn't work. + * So we have a state machine which uses the common work queue to ensure + * clean transitions. + * When a change is requested we record that request and only act on it + * once the previous change has completed. + * A change involves a 10ms low pulse, and a 10ms raised level. + */ + +static void toggle_work(struct work_struct *work) +{ + struct w2sg_data *data = container_of( + work, struct w2sg_data, work.work); + + spin_lock_irq(&data->lock); + switch (data->state) { + case Up: + data->state = Idle; + if (data->requested == data->is_on) + break; + if (!data->requested) + /* Assume it is off unless activity is detected */ + break; + /* Try again in a while unless we get some activity */ + dev_dbg(data->dev, "Wait %dusec until retry\n", + jiffies_to_msecs(data->backoff)); + schedule_delayed_work(&data->work, data->backoff); + break; + case Idle: + if (data->requested == data->is_on) + break; + + /* Time to toggle */ + dev_dbg(data->dev, "Starting toggle to turn %s\n", + data->requested ? "on" : "off"); + data->state = Down; + spin_unlock_irq(&data->lock); + gpio_set_value_cansleep(data->gpio, 0); + schedule_delayed_work(&data->work, + msecs_to_jiffies(10)); + return; + + case Down: + data->state = Up; + data->last_toggle = jiffies; + dev_dbg(data->dev, "Toggle completed, should be %s now.\n", + data->is_on ? "off" : "on"); + data->is_on = ! data->is_on; + spin_unlock_irq(&data->lock); + + gpio_set_value_cansleep(data->gpio, 1); + schedule_delayed_work(&data->work, + msecs_to_jiffies(10)); + return; + } + spin_unlock_irq(&data->lock); +} + +static irqreturn_t tty_w2_isr(int irq, void *dev_id) +{ + struct w2sg_data *data = dev_id; + unsigned long flags; + + spin_lock_irqsave(&data->lock, flags); + if (!data->requested && !data->is_on && data->state == Idle && + time_after(jiffies, data->last_toggle + data->backoff)) { + data->is_on = 1; + data->backoff *= 2; + dev_dbg(data->dev, "Received data, must be on. Try to turn off\n"); + if (!data->suspended) + schedule_delayed_work(&data->work, 0); + } + spin_unlock_irqrestore(&data->lock, flags); + return IRQ_HANDLED; +} + +static int tty_w2_runtime_resume(struct device *slave) +{ + struct w2sg_data *data = dev_get_drvdata(slave); + unsigned long flags; + + if (!data->reg_enabled && + data->reg && + !rfkill_blocked(data->rfkill)) + if (regulator_enable(data->reg) == 0) + data->reg_enabled = true; + + spin_lock_irqsave(&data->lock, flags); + if (!data->requested) { + dev_dbg(data->dev, "Device open - turn GPS on\n"); + data->requested = true; + data->backoff = HZ; + if (data->irq) { + disable_irq(data->irq); + pinctrl_pm_select_default_state(slave); + } + if (!data->suspended && data->state == Idle) + schedule_delayed_work(&data->work, 0); + } + spin_unlock_irqrestore(&data->lock, flags); + return 0; +} + +static int tty_w2_rfkill_set_block(void *vdata, bool blocked) +{ + struct w2sg_data *data = vdata; + + dev_dbg(data->dev, "rfkill_set_blocked %d\n", blocked); + if (blocked && data->reg_enabled) + if (regulator_disable(data->reg) == 0) + data->reg_enabled = false; + if (!blocked && + !data->reg_enabled && data->reg && + !pm_runtime_suspended(data->dev)) + if (regulator_enable(data->reg) == 0) + data->reg_enabled = true; + return 0; +} + +static struct rfkill_ops tty_w2_rfkill_ops = { + .set_block = tty_w2_rfkill_set_block, +}; + +static int tty_w2_runtime_suspend(struct device *slave) +{ + struct w2sg_data *data = dev_get_drvdata(slave); + unsigned long flags; + + dev_dbg(data->dev, "Device closed - turn GPS off\n"); + if (data->reg && data->reg_enabled) + if (regulator_disable(data->reg) == 0) + data->reg_enabled = false; + + spin_lock_irqsave(&data->lock, flags); + if (data->requested) { + data->requested = false; + data->backoff = HZ; + if (data->irq) { + pinctrl_pm_select_idle_state(slave); + enable_irq(data->irq); + } + if (!data->suspended && data->state == Idle) + schedule_delayed_work(&data->work, 0); + } + spin_unlock_irqrestore(&data->lock, flags); + return 0; +} + +static int tty_w2_suspend(struct device *dev) +{ + /* Ignore incoming data and just turn device off. + * we cannot really wait for a separate thread to + * do things, so we disable that and do it all + * here + */ + struct w2sg_data *data = dev_get_drvdata(dev); + + spin_lock_irq(&data->lock); + data->suspended = true; + spin_unlock_irq(&data->lock); + + cancel_delayed_work_sync(&data->work); + if (data->state == Down) { + dev_dbg(data->dev, "Suspending while GPIO down - raising\n"); + msleep(10); + gpio_set_value_cansleep(data->gpio, 1); + data->last_toggle = jiffies; + data->is_on = !data->is_on; + data->state = Up; + } + if (data->state == Up) { + msleep(10); + data->state = Idle; + } + if (data->is_on) { + dev_dbg(data->dev, "Suspending while GPS on: toggling\n"); + gpio_set_value_cansleep(data->gpio, 0); + msleep(10); + gpio_set_value_cansleep(data->gpio, 1); + data->is_on = 0; + } + return 0; +} + +static int tty_w2_resume(struct device *dev) +{ + struct w2sg_data *data = dev_get_drvdata(dev); + + spin_lock_irq(&data->lock); + data->suspended = false; + spin_unlock_irq(&data->lock); + schedule_delayed_work(&data->work, 0); + return 0; +} + +static const struct dev_pm_ops tty_w2_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(tty_w2_suspend, tty_w2_resume) + SET_RUNTIME_PM_OPS(tty_w2_runtime_suspend, + tty_w2_runtime_resume, + NULL) +}; + +static bool toggle_on_probe = false; + +static int tty_w2_probe(struct platform_device *pdev) +{ + struct w2sg_data *data; + struct regulator *reg; + int err; + + if (pdev->dev.parent == NULL) + return -ENODEV; + + data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + reg = devm_regulator_get(&pdev->dev, "vdd"); + if (IS_ERR(reg)) { + err = PTR_ERR(reg); + if (err != -ENODEV) + goto out; + } else + data->reg = reg; + + data->irq = platform_get_irq(pdev, 0); + if (data->irq < 0) { + err = data->irq; + goto out; + } + dev_dbg(&pdev->dev, "IRQ configured: %d\n", data->irq); + + data->last_toggle = jiffies; + data->backoff = HZ; + data->state = Idle; + data->gpio = of_get_named_gpio(pdev->dev.of_node, "gpios", 0); + if (data->gpio < 0) { + err = data->gpio; + goto out; + } + dev_dbg(&pdev->dev, "GPIO configured: %d\n", data->gpio); + spin_lock_init(&data->lock); + INIT_DELAYED_WORK(&data->work, toggle_work); + err = devm_gpio_request_one(&pdev->dev, data->gpio, + GPIOF_OUT_INIT_HIGH, + "tty-w2sg0004-on-off"); + if (err) + goto out; + + if (data->irq) { + irq_set_status_flags(data->irq, IRQ_NOAUTOEN); + err = devm_request_irq(&pdev->dev, data->irq, tty_w2_isr, + IRQF_TRIGGER_FALLING, + "tty-w2sg0004", data); + } + if (err) + goto out; + + if (data->reg) { + data->rfkill = rfkill_alloc("GPS", &pdev->dev, RFKILL_TYPE_GPS, + &tty_w2_rfkill_ops, data); + if (!data->rfkill) { + err = -ENOMEM; + goto out; + } + err = rfkill_register(data->rfkill); + if (err) { + dev_err(&pdev->dev, "Cannot register rfkill device"); + rfkill_destroy(data->rfkill); + goto out; + } + } + platform_set_drvdata(pdev, data); + data->dev = &pdev->dev; + pm_runtime_enable(&pdev->dev); + if (data->irq) { + pinctrl_pm_select_idle_state(&pdev->dev); + enable_irq(data->irq); + } + if (toggle_on_probe) { + dev_dbg(data->dev, "Performing initial toggle\n"); + gpio_set_value_cansleep(data->gpio, 0); + msleep(10); + gpio_set_value_cansleep(data->gpio, 1); + msleep(10); + } +out: + dev_dbg(data->dev, "Probed: err=%d\n", err); + return err; +} +module_param(toggle_on_probe, bool, 0); +MODULE_PARM_DESC(toggle_on_probe, "simulate power-on with GPS active"); + +static int tty_w2_remove(struct platform_device *pdev) +{ + struct w2sg_data *data = dev_get_drvdata(&pdev->dev); + if (data->rfkill) { + rfkill_unregister(data->rfkill); + rfkill_destroy(data->rfkill); + } + return 0; +} + +static struct of_device_id tty_w2_dt_ids[] = { + { .compatible = "tty,w2sg0004", }, + {} +}; + +static struct platform_driver tty_w2_driver = { + .driver.name = "tty-w2sg0004", + .driver.owner = THIS_MODULE, + .driver.pm = &tty_w2_pm_ops, + .driver.of_match_table = tty_w2_dt_ids, + .probe = tty_w2_probe, + .remove = tty_w2_remove, +}; + +static int __init tty_w2_init(void) +{ + return platform_driver_register(&tty_w2_driver); +} +module_init(tty_w2_init); + +static void __exit tty_w2_exit(void) +{ + platform_driver_unregister(&tty_w2_driver); +} +module_exit(tty_w2_exit); + +MODULE_AUTHOR("NeilBrown <neilb@suse.de>"); +MODULE_DESCRIPTION("Serial port device which turns on W2SG0004 GPS"); +MODULE_LICENSE("GPL v2"); ^ permalink raw reply related [flat|nested] 34+ messages in thread
[parent not found: <20141211215944.4127.57146.stgit-wvvUuzkyo1EYVZTmpyfIwg@public.gmane.org>]
* Re: [PATCH 3/3] TTY/slave: add driver for w2sg0004 GPS [not found] ` <20141211215944.4127.57146.stgit-wvvUuzkyo1EYVZTmpyfIwg@public.gmane.org> @ 2014-12-11 23:04 ` Sebastian Reichel 2014-12-11 23:11 ` One Thousand Gnomes 1 sibling, 0 replies; 34+ messages in thread From: Sebastian Reichel @ 2014-12-11 23:04 UTC (permalink / raw) To: NeilBrown Cc: Grant Likely, Greg Kroah-Hartman, Mark Rutland, Jiri Slaby, NeilBrown, devicetree-u79uwXL29TY76Z2rM5mHXA, linux-kernel-u79uwXL29TY76Z2rM5mHXA [-- Attachment #1: Type: text/plain, Size: 1152 bytes --] Hi, On Fri, Dec 12, 2014 at 08:59:44AM +1100, NeilBrown wrote: > This uart-attatched GPS device has a toggle which turns > both on and off. For reliable use we need to know what > start it is in. I guess you mean "what state it is in"? > So it registers with the tty for recv events when the tty > is open, and optionally configures the RX pin as a GPIO > interrupt when the tty is closed. > > If it detects data when it should be off, or a lack of data > when it should be on, it toggles the line. > > A regulator can also be configured to power the antenna. > In this case an rfkill device is created. When the rfkill > is 'blocked' or the device is otherwise powered down, > the regulator is turned off. [...] > index 000000000000..c9e7838b3198 > --- /dev/null > +++ b/Documentation/devicetree/bindings/serial/slave-w2sg0004.txt > @@ -0,0 +1,35 @@ > +w2sg0004 UART-attached GPS receiver > + > +Required properties: > +- compatbile: "tty,w2sg0004" grep tty $ grep -c tty Documentation/devicetree/bindings/vendor-prefixes.txt 0 This should be something like "wi2wi,w2sg0004" [...] -- Sebastian [-- Attachment #2: Digital signature --] [-- Type: application/pgp-signature, Size: 819 bytes --] ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH 3/3] TTY/slave: add driver for w2sg0004 GPS [not found] ` <20141211215944.4127.57146.stgit-wvvUuzkyo1EYVZTmpyfIwg@public.gmane.org> 2014-12-11 23:04 ` Sebastian Reichel @ 2014-12-11 23:11 ` One Thousand Gnomes [not found] ` <20141211231100.05782a30-qBU/x9rampVanCEyBjwyrvXRex20P6io@public.gmane.org> 1 sibling, 1 reply; 34+ messages in thread From: One Thousand Gnomes @ 2014-12-11 23:11 UTC (permalink / raw) To: NeilBrown Cc: Grant Likely, Greg Kroah-Hartman, Mark Rutland, Jiri Slaby, NeilBrown, devicetree-u79uwXL29TY76Z2rM5mHXA, linux-kernel-u79uwXL29TY76Z2rM5mHXA > +w2sg0004 UART-attached GPS receiver > + I'm wondering why it's tied to the w2sg0004 > +struct w2sg_data { > + int gpio; > + int irq; /* irq line from RX pin when pinctrl > + * set to 'idle' */ > + struct regulator *reg; > + > + unsigned long last_toggle; /* jiffies when last toggle completed. */ > + unsigned long backoff; /* jiffies since last_toggle when > + * we try again > + */ > + enum {Idle, Down, Up} state; /* state-machine state. */ > + bool requested, is_on; > + bool suspended; > + bool reg_enabled; > + > + struct delayed_work work; > + spinlock_t lock; > + struct device *dev; > + > + struct rfkill *rfkill; So its - a regulator (optional) - an irq (optional) - a gpio (could be optional) - an optional rfkill - a pulse time (10ms fixed) - a backoff time (1 second fixed) It looks identical to half a dozen other widgets that are found in Android phones. Would it perhaps be better to make the tiny tweaks to make it generic - make the timers configurable - make the pulse time or high/low selectable for on/off - make the gpio optional and just have one driver with the right DT for all similar devices? Am I missing some w2sg004 specific bits here ? I think the general model is right, and there will be other slaves that don't fit the pattern but I do think this one could be generalised. Alan -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 34+ messages in thread
[parent not found: <20141211231100.05782a30-qBU/x9rampVanCEyBjwyrvXRex20P6io@public.gmane.org>]
* Re: [PATCH 3/3] TTY/slave: add driver for w2sg0004 GPS [not found] ` <20141211231100.05782a30-qBU/x9rampVanCEyBjwyrvXRex20P6io@public.gmane.org> @ 2014-12-12 5:06 ` NeilBrown [not found] ` <20141212160607.361d20db-wvvUuzkyo1EYVZTmpyfIwg@public.gmane.org> 0 siblings, 1 reply; 34+ messages in thread From: NeilBrown @ 2014-12-12 5:06 UTC (permalink / raw) To: One Thousand Gnomes Cc: Grant Likely, Greg Kroah-Hartman, Mark Rutland, Jiri Slaby, NeilBrown, devicetree-u79uwXL29TY76Z2rM5mHXA, linux-kernel-u79uwXL29TY76Z2rM5mHXA [-- Attachment #1: Type: text/plain, Size: 2416 bytes --] On Thu, 11 Dec 2014 23:11:00 +0000 One Thousand Gnomes <gnomes-qBU/x9rampVanCEyBjwyrvXRex20P6io@public.gmane.org> wrote: > > +w2sg0004 UART-attached GPS receiver > > + > > I'm wondering why it's tied to the w2sg0004 > > > > +struct w2sg_data { > > + int gpio; > > + int irq; /* irq line from RX pin when pinctrl > > + * set to 'idle' */ > > + struct regulator *reg; > > + > > + unsigned long last_toggle; /* jiffies when last toggle completed. */ > > + unsigned long backoff; /* jiffies since last_toggle when > > + * we try again > > + */ > > + enum {Idle, Down, Up} state; /* state-machine state. */ > > + bool requested, is_on; > > + bool suspended; > > + bool reg_enabled; > > + > > + struct delayed_work work; > > + spinlock_t lock; > > + struct device *dev; > > + > > + struct rfkill *rfkill; > > So its > - a regulator (optional) > - an irq (optional) > - a gpio (could be optional) > - an optional rfkill > - a pulse time (10ms fixed) > - a backoff time (1 second fixed) > > > It looks identical to half a dozen other widgets that are found in > Android phones. Would it perhaps be better to make the tiny tweaks to > make it generic > > - make the timers configurable > - make the pulse time or high/low selectable for on/off > - make the gpio optional > > and just have one driver with the right DT for all similar devices? > > Am I missing some w2sg004 specific bits here ? There is particular behaviour that the device is both turned on and turned off by toggling a GPIO, and the only way to detect which state it is in is to watch the RX uart line (by reconfiguring it as a GPIO). I'm sure that could describe other devices, but I don't personally know of any. I want to avoid premature generalisation. When we have another device it would certainly make sense to extend this driver to support the new device. Values like the timeouts could be tied to the particular 'compatible' value. I guess the one drive could support both of my devices, as the simpler one just needs a regulator to be enabled/disabled, and this driver can do that. But then we would need a name for this driver. "generic.c" ??? > > > I think the general model is right, and there will be other slaves that > don't fit the pattern but I do think this one could be generalised. Thanks, NeilBrown > > Alan > [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 811 bytes --] ^ permalink raw reply [flat|nested] 34+ messages in thread
[parent not found: <20141212160607.361d20db-wvvUuzkyo1EYVZTmpyfIwg@public.gmane.org>]
* Re: [PATCH 3/3] TTY/slave: add driver for w2sg0004 GPS [not found] ` <20141212160607.361d20db-wvvUuzkyo1EYVZTmpyfIwg@public.gmane.org> @ 2014-12-15 11:39 ` One Thousand Gnomes 0 siblings, 0 replies; 34+ messages in thread From: One Thousand Gnomes @ 2014-12-15 11:39 UTC (permalink / raw) To: NeilBrown Cc: Grant Likely, Greg Kroah-Hartman, Mark Rutland, Jiri Slaby, NeilBrown, devicetree-u79uwXL29TY76Z2rM5mHXA, linux-kernel-u79uwXL29TY76Z2rM5mHXA > > Am I missing some w2sg004 specific bits here ? > > There is particular behaviour that the device is both turned on and turned > off by toggling a GPIO, and the only way to detect which state it is in is > to watch the RX uart line (by reconfiguring it as a GPIO). Ok so it is somewhat different to things like the Broadcom and the more usual 'wait for idle, drop power' setup. Alan -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH 3/3] TTY/slave: add driver for w2sg0004 GPS 2014-12-11 21:59 ` [PATCH 3/3] TTY/slave: add driver for w2sg0004 GPS NeilBrown [not found] ` <20141211215944.4127.57146.stgit-wvvUuzkyo1EYVZTmpyfIwg@public.gmane.org> @ 2014-12-12 12:11 ` Grant Likely 1 sibling, 0 replies; 34+ messages in thread From: Grant Likely @ 2014-12-12 12:11 UTC (permalink / raw) To: NeilBrown, Greg Kroah-Hartman, Mark Rutland, Jiri Slaby Cc: NeilBrown, devicetree, linux-kernel On Fri, 12 Dec 2014 08:59:44 +1100 , NeilBrown <neilb@suse.de> wrote: > This uart-attatched GPS device has a toggle which turns > both on and off. For reliable use we need to know what > start it is in. > > So it registers with the tty for recv events when the tty > is open, and optionally configures the RX pin as a GPIO > interrupt when the tty is closed. > > If it detects data when it should be off, or a lack of data > when it should be on, it toggles the line. > > A regulator can also be configured to power the antenna. > In this case an rfkill device is created. When the rfkill > is 'blocked' or the device is otherwise powered down, > the regulator is turned off. > > Signed-off-by: NeilBrown <neil@brown.name> > --- > .../devicetree/bindings/serial/slave-w2sg0004.txt | 35 ++ > drivers/tty/slaves/Kconfig | 6 > drivers/tty/slaves/Makefile | 3 > drivers/tty/slaves/tty-w2sg0004.c | 412 ++++++++++++++++++++ > 4 files changed, 455 insertions(+), 1 deletion(-) > create mode 100644 Documentation/devicetree/bindings/serial/slave-w2sg0004.txt > create mode 100644 drivers/tty/slaves/tty-w2sg0004.c > > diff --git a/Documentation/devicetree/bindings/serial/slave-w2sg0004.txt b/Documentation/devicetree/bindings/serial/slave-w2sg0004.txt > new file mode 100644 > index 000000000000..c9e7838b3198 > --- /dev/null > +++ b/Documentation/devicetree/bindings/serial/slave-w2sg0004.txt This isn't a binding for a serial device, it is a binding for a GPS device, which happens to be tty attached. Documentation/devicetree/bindings/gps perhaps? > @@ -0,0 +1,35 @@ > +w2sg0004 UART-attached GPS receiver > + > +Required properties: > +- compatbile: "tty,w2sg0004" 'tty' is the wrong prefix. It should be the vendor abbreviation for the GPS vendor. > +- gpios: gpio used to toggle 'on/off' pin > +- interrupts: interrupt generated by RX pin when device should > + be idle > +- pinctrl: "default", "idle" > + "idle" setting is active when device should be off. > + This can remap the RX pin to a GPIO interrupt. > + > +Optional properties: > +- vdd-supply: regulator, e.g. to power antenna > + > + > +The w2sg0004 uses a pin-toggle both to power-on and to > +power-off, so the driver needs to detect what state it is in. > +It does this by detecting characters on the RX line. > +When it should be off, these can optionally be detected by a GPIO. > + > +The node for this device must be the child of a UART. This may need some tweaking to be more portable. ie. if it is wired into a platform with a separate gpio pin also wired to the rx line so that pinctrl manipulation isn't needed. I would make the pinctrl settings optional. > + > +Example: > +&uart2 { > + gps { > + compatible = "tty,w2sg0004"; > + vdd-supply = <&vsim>; > + gpios = <&gpio5 17 0>; /* GPIO_145 */ > + interrupts-extended = <&gpio5 19 0>; /* GPIO_147 */ > + /* When idle, switch RX to be an interrupt */ > + pinctrl-names = "default", "idle"; > + pinctrl-0 = <&uart2_pins>; > + pinctrl-1 = <&uart2_pins_rx_gpio>; > + }; > +}; > diff --git a/drivers/tty/slaves/Kconfig b/drivers/tty/slaves/Kconfig > index 2dd1acf80f8c..7a669faaf02d 100644 > --- a/drivers/tty/slaves/Kconfig > +++ b/drivers/tty/slaves/Kconfig > @@ -9,4 +9,10 @@ if TTY_SLAVE > config TTY_SLAVE_REGULATOR > tristate "TTY slave device powered by regulator" > > +config TTY_SLAVE_W2SG0004 > + tristate "W2SG0004 GPS on/off control" > + help > + Enable on/off control of W2SG0004 GPS when attached > + to a UART. > + Drivers/gps maybe? Do we have any other gps drivers in-tree? > endif > diff --git a/drivers/tty/slaves/Makefile b/drivers/tty/slaves/Makefile > index e636bf49f1cc..ba528fa27110 100644 > --- a/drivers/tty/slaves/Makefile > +++ b/drivers/tty/slaves/Makefile > @@ -1,2 +1,3 @@ > > -obj-$(CONFIG_TTY_SLAVE_REGULATOR) += tty-reg.o > +obj-$(CONFIG_TTY_SLAVE_REGULATOR) += tty-reg.o > +obj-$(CONFIG_TTY_SLAVE_W2SG0004) += tty-w2sg0004.o > diff --git a/drivers/tty/slaves/tty-w2sg0004.c b/drivers/tty/slaves/tty-w2sg0004.c > new file mode 100644 > index 000000000000..7c7ae479bf41 > --- /dev/null > +++ b/drivers/tty/slaves/tty-w2sg0004.c > @@ -0,0 +1,412 @@ > +/* > + * tty-w2sg0004.c - tty-slave for w2sg0004 GPS device > + * > + * Copyright (C) 2014 NeilBrown <neil@brown.name> > + * > + * This program is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License version 2 as > + * published by the Free Software Foundation. > + * > + * The w2sg0004 is turned 'on' or 'off' by toggling a line, which > + * is normally connected to a GPIO. Thus you need to know the current > + * state in order to determine how to achieve some particular state. > + * The only way to detect the state is by detecting transitions on > + * its TX line (our RX line). > + * So this tty slave listens for 'recv' events and deduces the GPS is > + * on if it has received one recently. > + * If suitably configure, and if the hardware is capable, it also > + * enables an interrupt (presumably via a GPIO connected to the RX > + * line via pinctrl) when the tty is inactive and treat and interrupts > + * as an indication that the device is 'on' and should be turned 'off'. > + * > + * Driver also listens for open/close and trys to turn the GPS on if it is > + * off and the tty is open. On final 'close', the GPS is then turned > + * off. > + * > + * When the device is opened, the GPIO is toggled immediately and then > + * again after 2 seconds of no data. If there is still no data the > + * toggle happens are 4, 8, 16 seconds etc. > + * > + * When the device is closed, the GPIO is toggled immediately and > + * if interrupts are received after 1 second it is toggled again > + * (and again and again with exponentially increasing delays while > + * interrupts continue). > + * > + * If a regulator is configured (e.g. to power the antenna), that is > + * enabled/disabled on open/close. > + * > + * During system suspend the GPS is turned off even if the tty is > + * open. No repeat attempts are made. > + * Possibly it should be possible to keep the GPS on with some > + * configuration. > + */ > + > +#include <linux/module.h> > +#include <linux/slab.h> > +#include <linux/err.h> > +#include <linux/regulator/consumer.h> > +#include <linux/gpio.h> > +#include <linux/of_gpio.h> > +#include <linux/interrupt.h> > +#include <linux/platform_device.h> > +#include <linux/tty.h> > +#include <linux/delay.h> > +#include <linux/pm_runtime.h> > +#include <linux/rfkill.h> > + > +struct w2sg_data { > + int gpio; > + int irq; /* irq line from RX pin when pinctrl > + * set to 'idle' */ > + struct regulator *reg; > + > + unsigned long last_toggle; /* jiffies when last toggle completed. */ > + unsigned long backoff; /* jiffies since last_toggle when > + * we try again > + */ > + enum {Idle, Down, Up} state; /* state-machine state. */ > + bool requested, is_on; > + bool suspended; > + bool reg_enabled; > + > + struct delayed_work work; > + spinlock_t lock; > + struct device *dev; > + > + struct rfkill *rfkill; > +}; > + > +/* > + * There seems to restrictions on how quickly we can toggle the > + * on/off line. Data sheets says "two rtc ticks", whatever that means. > + * If we do it too soon it doesn't work. > + * So we have a state machine which uses the common work queue to ensure > + * clean transitions. > + * When a change is requested we record that request and only act on it > + * once the previous change has completed. > + * A change involves a 10ms low pulse, and a 10ms raised level. > + */ > + > +static void toggle_work(struct work_struct *work) > +{ > + struct w2sg_data *data = container_of( > + work, struct w2sg_data, work.work); > + > + spin_lock_irq(&data->lock); > + switch (data->state) { > + case Up: > + data->state = Idle; > + if (data->requested == data->is_on) > + break; > + if (!data->requested) > + /* Assume it is off unless activity is detected */ > + break; > + /* Try again in a while unless we get some activity */ > + dev_dbg(data->dev, "Wait %dusec until retry\n", > + jiffies_to_msecs(data->backoff)); > + schedule_delayed_work(&data->work, data->backoff); > + break; > + case Idle: > + if (data->requested == data->is_on) > + break; > + > + /* Time to toggle */ > + dev_dbg(data->dev, "Starting toggle to turn %s\n", > + data->requested ? "on" : "off"); > + data->state = Down; > + spin_unlock_irq(&data->lock); > + gpio_set_value_cansleep(data->gpio, 0); > + schedule_delayed_work(&data->work, > + msecs_to_jiffies(10)); > + return; > + > + case Down: > + data->state = Up; > + data->last_toggle = jiffies; > + dev_dbg(data->dev, "Toggle completed, should be %s now.\n", > + data->is_on ? "off" : "on"); > + data->is_on = ! data->is_on; > + spin_unlock_irq(&data->lock); > + > + gpio_set_value_cansleep(data->gpio, 1); > + schedule_delayed_work(&data->work, > + msecs_to_jiffies(10)); > + return; > + } > + spin_unlock_irq(&data->lock); > +} > + > +static irqreturn_t tty_w2_isr(int irq, void *dev_id) > +{ > + struct w2sg_data *data = dev_id; > + unsigned long flags; > + > + spin_lock_irqsave(&data->lock, flags); > + if (!data->requested && !data->is_on && data->state == Idle && > + time_after(jiffies, data->last_toggle + data->backoff)) { > + data->is_on = 1; > + data->backoff *= 2; > + dev_dbg(data->dev, "Received data, must be on. Try to turn off\n"); > + if (!data->suspended) > + schedule_delayed_work(&data->work, 0); > + } > + spin_unlock_irqrestore(&data->lock, flags); > + return IRQ_HANDLED; > +} > + > +static int tty_w2_runtime_resume(struct device *slave) > +{ > + struct w2sg_data *data = dev_get_drvdata(slave); > + unsigned long flags; > + > + if (!data->reg_enabled && > + data->reg && > + !rfkill_blocked(data->rfkill)) > + if (regulator_enable(data->reg) == 0) > + data->reg_enabled = true; > + > + spin_lock_irqsave(&data->lock, flags); > + if (!data->requested) { > + dev_dbg(data->dev, "Device open - turn GPS on\n"); > + data->requested = true; > + data->backoff = HZ; > + if (data->irq) { > + disable_irq(data->irq); > + pinctrl_pm_select_default_state(slave); > + } > + if (!data->suspended && data->state == Idle) > + schedule_delayed_work(&data->work, 0); > + } > + spin_unlock_irqrestore(&data->lock, flags); > + return 0; > +} > + > +static int tty_w2_rfkill_set_block(void *vdata, bool blocked) > +{ > + struct w2sg_data *data = vdata; > + > + dev_dbg(data->dev, "rfkill_set_blocked %d\n", blocked); > + if (blocked && data->reg_enabled) > + if (regulator_disable(data->reg) == 0) > + data->reg_enabled = false; > + if (!blocked && > + !data->reg_enabled && data->reg && > + !pm_runtime_suspended(data->dev)) > + if (regulator_enable(data->reg) == 0) > + data->reg_enabled = true; > + return 0; > +} > + > +static struct rfkill_ops tty_w2_rfkill_ops = { > + .set_block = tty_w2_rfkill_set_block, > +}; > + > +static int tty_w2_runtime_suspend(struct device *slave) > +{ > + struct w2sg_data *data = dev_get_drvdata(slave); > + unsigned long flags; > + > + dev_dbg(data->dev, "Device closed - turn GPS off\n"); > + if (data->reg && data->reg_enabled) > + if (regulator_disable(data->reg) == 0) > + data->reg_enabled = false; > + > + spin_lock_irqsave(&data->lock, flags); > + if (data->requested) { > + data->requested = false; > + data->backoff = HZ; > + if (data->irq) { > + pinctrl_pm_select_idle_state(slave); > + enable_irq(data->irq); > + } > + if (!data->suspended && data->state == Idle) > + schedule_delayed_work(&data->work, 0); > + } > + spin_unlock_irqrestore(&data->lock, flags); > + return 0; > +} > + > +static int tty_w2_suspend(struct device *dev) > +{ > + /* Ignore incoming data and just turn device off. > + * we cannot really wait for a separate thread to > + * do things, so we disable that and do it all > + * here > + */ > + struct w2sg_data *data = dev_get_drvdata(dev); > + > + spin_lock_irq(&data->lock); > + data->suspended = true; > + spin_unlock_irq(&data->lock); > + > + cancel_delayed_work_sync(&data->work); > + if (data->state == Down) { > + dev_dbg(data->dev, "Suspending while GPIO down - raising\n"); > + msleep(10); > + gpio_set_value_cansleep(data->gpio, 1); > + data->last_toggle = jiffies; > + data->is_on = !data->is_on; > + data->state = Up; > + } > + if (data->state == Up) { > + msleep(10); > + data->state = Idle; > + } > + if (data->is_on) { > + dev_dbg(data->dev, "Suspending while GPS on: toggling\n"); > + gpio_set_value_cansleep(data->gpio, 0); > + msleep(10); > + gpio_set_value_cansleep(data->gpio, 1); > + data->is_on = 0; > + } > + return 0; > +} > + > +static int tty_w2_resume(struct device *dev) > +{ > + struct w2sg_data *data = dev_get_drvdata(dev); > + > + spin_lock_irq(&data->lock); > + data->suspended = false; > + spin_unlock_irq(&data->lock); > + schedule_delayed_work(&data->work, 0); > + return 0; > +} > + > +static const struct dev_pm_ops tty_w2_pm_ops = { > + SET_SYSTEM_SLEEP_PM_OPS(tty_w2_suspend, tty_w2_resume) > + SET_RUNTIME_PM_OPS(tty_w2_runtime_suspend, > + tty_w2_runtime_resume, > + NULL) > +}; > + > +static bool toggle_on_probe = false; > + > +static int tty_w2_probe(struct platform_device *pdev) > +{ > + struct w2sg_data *data; > + struct regulator *reg; > + int err; > + > + if (pdev->dev.parent == NULL) > + return -ENODEV; > + > + data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); > + if (!data) > + return -ENOMEM; > + > + reg = devm_regulator_get(&pdev->dev, "vdd"); > + if (IS_ERR(reg)) { > + err = PTR_ERR(reg); > + if (err != -ENODEV) > + goto out; > + } else > + data->reg = reg; > + > + data->irq = platform_get_irq(pdev, 0); > + if (data->irq < 0) { > + err = data->irq; > + goto out; > + } > + dev_dbg(&pdev->dev, "IRQ configured: %d\n", data->irq); > + > + data->last_toggle = jiffies; > + data->backoff = HZ; > + data->state = Idle; > + data->gpio = of_get_named_gpio(pdev->dev.of_node, "gpios", 0); > + if (data->gpio < 0) { > + err = data->gpio; > + goto out; > + } > + dev_dbg(&pdev->dev, "GPIO configured: %d\n", data->gpio); > + spin_lock_init(&data->lock); > + INIT_DELAYED_WORK(&data->work, toggle_work); > + err = devm_gpio_request_one(&pdev->dev, data->gpio, > + GPIOF_OUT_INIT_HIGH, > + "tty-w2sg0004-on-off"); > + if (err) > + goto out; > + > + if (data->irq) { > + irq_set_status_flags(data->irq, IRQ_NOAUTOEN); > + err = devm_request_irq(&pdev->dev, data->irq, tty_w2_isr, > + IRQF_TRIGGER_FALLING, > + "tty-w2sg0004", data); > + } > + if (err) > + goto out; > + > + if (data->reg) { > + data->rfkill = rfkill_alloc("GPS", &pdev->dev, RFKILL_TYPE_GPS, > + &tty_w2_rfkill_ops, data); > + if (!data->rfkill) { > + err = -ENOMEM; > + goto out; > + } > + err = rfkill_register(data->rfkill); > + if (err) { > + dev_err(&pdev->dev, "Cannot register rfkill device"); > + rfkill_destroy(data->rfkill); > + goto out; > + } > + } > + platform_set_drvdata(pdev, data); > + data->dev = &pdev->dev; > + pm_runtime_enable(&pdev->dev); > + if (data->irq) { > + pinctrl_pm_select_idle_state(&pdev->dev); > + enable_irq(data->irq); > + } > + if (toggle_on_probe) { > + dev_dbg(data->dev, "Performing initial toggle\n"); > + gpio_set_value_cansleep(data->gpio, 0); > + msleep(10); > + gpio_set_value_cansleep(data->gpio, 1); > + msleep(10); > + } > +out: > + dev_dbg(data->dev, "Probed: err=%d\n", err); > + return err; > +} > +module_param(toggle_on_probe, bool, 0); > +MODULE_PARM_DESC(toggle_on_probe, "simulate power-on with GPS active"); > + > +static int tty_w2_remove(struct platform_device *pdev) > +{ > + struct w2sg_data *data = dev_get_drvdata(&pdev->dev); > + if (data->rfkill) { > + rfkill_unregister(data->rfkill); > + rfkill_destroy(data->rfkill); > + } > + return 0; > +} > + > +static struct of_device_id tty_w2_dt_ids[] = { > + { .compatible = "tty,w2sg0004", }, > + {} > +}; > + > +static struct platform_driver tty_w2_driver = { > + .driver.name = "tty-w2sg0004", > + .driver.owner = THIS_MODULE, > + .driver.pm = &tty_w2_pm_ops, > + .driver.of_match_table = tty_w2_dt_ids, > + .probe = tty_w2_probe, > + .remove = tty_w2_remove, > +}; > + > +static int __init tty_w2_init(void) > +{ > + return platform_driver_register(&tty_w2_driver); > +} > +module_init(tty_w2_init); > + > +static void __exit tty_w2_exit(void) > +{ > + platform_driver_unregister(&tty_w2_driver); > +} > +module_exit(tty_w2_exit); module_platform_driver() is your friend. :-) > + > +MODULE_AUTHOR("NeilBrown <neilb@suse.de>"); > +MODULE_DESCRIPTION("Serial port device which turns on W2SG0004 GPS"); > +MODULE_LICENSE("GPL v2"); > > ^ permalink raw reply [flat|nested] 34+ messages in thread
end of thread, other threads:[~2015-01-05 16:28 UTC | newest] Thread overview: 34+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2014-12-11 21:59 [PATCH 0/3] Add support for 'tty-slaves' described by devicetree NeilBrown 2014-12-11 21:59 ` [PATCH 2/3] TTY: add slave driver to power-on device via a regulator NeilBrown [not found] ` <20141211215944.4127.4186.stgit-wvvUuzkyo1EYVZTmpyfIwg@public.gmane.org> 2014-12-11 22:58 ` Sebastian Reichel 2014-12-12 0:46 ` Marcel Holtmann 2014-12-12 1:31 ` Sebastian Reichel 2014-12-12 5:01 ` NeilBrown 2014-12-11 23:32 ` Peter Hurley 2014-12-12 5:27 ` NeilBrown [not found] ` <20141212162714.3a2378df-wvvUuzkyo1EYVZTmpyfIwg@public.gmane.org> 2014-12-12 11:59 ` Peter Hurley 2014-12-12 12:05 ` Grant Likely 2014-12-11 21:59 ` [PATCH 1/3] TTY: add support for "tty slave" devices NeilBrown [not found] ` <20141211215943.4127.24792.stgit-wvvUuzkyo1EYVZTmpyfIwg@public.gmane.org> 2014-12-11 22:41 ` Sebastian Reichel 2014-12-11 23:18 ` Peter Hurley [not found] ` <548A264D.8070103-WaGBZJeGNqdsbIuE7sb01tBPR1lH4CV8@public.gmane.org> 2014-12-12 5:23 ` NeilBrown [not found] ` <20141212162352.66be5b5e-wvvUuzkyo1EYVZTmpyfIwg@public.gmane.org> 2014-12-12 13:02 ` Peter Hurley 2014-12-13 14:23 ` One Thousand Gnomes [not found] ` <20141213142344.61372b92-qBU/x9rampVanCEyBjwyrvXRex20P6io@public.gmane.org> 2014-12-16 16:14 ` Peter Hurley 2014-12-13 14:12 ` One Thousand Gnomes 2014-12-12 11:59 ` Grant Likely 2014-12-13 17:46 ` Sebastian Reichel 2014-12-13 22:22 ` Grant Likely 2014-12-28 14:20 ` Pavel Machek 2015-01-02 21:33 ` NeilBrown 2015-01-04 10:18 ` Pavel Machek 2015-01-05 7:09 ` NeilBrown [not found] ` <20150105200936.2ba8f596-wvvUuzkyo1EYVZTmpyfIwg@public.gmane.org> 2015-01-05 13:43 ` Pavel Machek 2015-01-05 15:41 ` One Thousand Gnomes 2015-01-05 16:28 ` Pavel Machek 2014-12-11 21:59 ` [PATCH 3/3] TTY/slave: add driver for w2sg0004 GPS NeilBrown [not found] ` <20141211215944.4127.57146.stgit-wvvUuzkyo1EYVZTmpyfIwg@public.gmane.org> 2014-12-11 23:04 ` Sebastian Reichel 2014-12-11 23:11 ` One Thousand Gnomes [not found] ` <20141211231100.05782a30-qBU/x9rampVanCEyBjwyrvXRex20P6io@public.gmane.org> 2014-12-12 5:06 ` NeilBrown [not found] ` <20141212160607.361d20db-wvvUuzkyo1EYVZTmpyfIwg@public.gmane.org> 2014-12-15 11:39 ` One Thousand Gnomes 2014-12-12 12:11 ` Grant Likely
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).