* [PATCH] serdev: Add support for wakeup-source @ 2025-02-13 14:34 Loic Poulain 2025-03-21 13:24 ` Neeraj Sanjay Kale 2025-04-08 13:09 ` Rob Herring 0 siblings, 2 replies; 4+ messages in thread From: Loic Poulain @ 2025-02-13 14:34 UTC (permalink / raw) To: robh; +Cc: jirislaby, gregkh, linux-serial, Loic Poulain This brings support for dedicated interrupt as wakeup source into the serdev core, similarly to the I2C bus, and aligned with the documentation: Documentation/devicetree/bindings/power/wakeup-source.txt As an example, this can be used for bluetooth serial devices with dedicated controller-to-host wakeup pin. Signed-off-by: Loic Poulain <loic.poulain@linaro.org> --- drivers/tty/serdev/core.c | 48 +++++++++++++++++++++++++++++++++++++-- include/linux/serdev.h | 1 + 2 files changed, 47 insertions(+), 2 deletions(-) diff --git a/drivers/tty/serdev/core.c b/drivers/tty/serdev/core.c index ebf0bbc2cff2..2d016fa546ca 100644 --- a/drivers/tty/serdev/core.c +++ b/drivers/tty/serdev/core.c @@ -13,8 +13,10 @@ #include <linux/module.h> #include <linux/of.h> #include <linux/of_device.h> +#include <linux/of_irq.h> #include <linux/pm_domain.h> #include <linux/pm_runtime.h> +#include <linux/pm_wakeirq.h> #include <linux/property.h> #include <linux/sched.h> #include <linux/serdev.h> @@ -164,6 +166,9 @@ int serdev_device_open(struct serdev_device *serdev) goto err_close; } + if (serdev->wakeup_source) + device_wakeup_enable(&serdev->dev); + return 0; err_close: @@ -181,6 +186,9 @@ void serdev_device_close(struct serdev_device *serdev) if (!ctrl || !ctrl->ops->close) return; + if (serdev->wakeup_source) + device_wakeup_disable(&serdev->dev); + pm_runtime_put(&ctrl->dev); ctrl->ops->close(ctrl); @@ -406,18 +414,52 @@ int serdev_device_break_ctl(struct serdev_device *serdev, int break_state) } EXPORT_SYMBOL_GPL(serdev_device_break_ctl); +static int serdev_wakeup_attach(struct device *dev) +{ + int wakeirq; + + if (!of_property_read_bool(dev->of_node, "wakeup-source")) + return 0; + + to_serdev_device(dev)->wakeup_source = true; + + device_set_wakeup_capable(dev, true); + + wakeirq = of_irq_get_byname(dev->of_node, "wakeup"); + if (wakeirq == -EPROBE_DEFER) + return -EPROBE_DEFER; + else if (wakeirq > 0) + return dev_pm_set_dedicated_wake_irq(dev, wakeirq); + + return 0; +} + +static void serdev_wakeup_detach(struct device *dev) +{ + device_init_wakeup(dev, false); + dev_pm_clear_wake_irq(dev); +} + static int serdev_drv_probe(struct device *dev) { const struct serdev_device_driver *sdrv = to_serdev_device_driver(dev->driver); int ret; - ret = dev_pm_domain_attach(dev, true); + ret = serdev_wakeup_attach(dev); if (ret) return ret; + ret = dev_pm_domain_attach(dev, true); + if (ret) { + serdev_wakeup_detach(dev); + return ret; + } + ret = sdrv->probe(to_serdev_device(dev)); - if (ret) + if (ret) { dev_pm_domain_detach(dev, true); + serdev_wakeup_detach(dev); + } return ret; } @@ -429,6 +471,8 @@ static void serdev_drv_remove(struct device *dev) sdrv->remove(to_serdev_device(dev)); dev_pm_domain_detach(dev, true); + + serdev_wakeup_detach(dev); } static const struct bus_type serdev_bus_type = { diff --git a/include/linux/serdev.h b/include/linux/serdev.h index ff78efc1f60d..2b3ee7b2c141 100644 --- a/include/linux/serdev.h +++ b/include/linux/serdev.h @@ -47,6 +47,7 @@ struct serdev_device { const struct serdev_device_ops *ops; struct completion write_comp; struct mutex write_lock; + bool wakeup_source; }; static inline struct serdev_device *to_serdev_device(struct device *d) -- 2.34.1 ^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH] serdev: Add support for wakeup-source 2025-02-13 14:34 [PATCH] serdev: Add support for wakeup-source Loic Poulain @ 2025-03-21 13:24 ` Neeraj Sanjay Kale 2025-04-07 13:29 ` Neeraj Sanjay Kale 2025-04-08 13:09 ` Rob Herring 1 sibling, 1 reply; 4+ messages in thread From: Neeraj Sanjay Kale @ 2025-03-21 13:24 UTC (permalink / raw) To: Loic Poulain Cc: robh, jirislaby, gregkh, linux-serial, manjeet.gupta, amitkumar.karwar Hi Loic, Thank you for the patch. I have verified this patch with btnxpuart driver and I am able to wakeup the host with a GPIO interrupt signal from BT controller. Tested-by: Neeraj Sanjay Kale <neeraj.sanjaykale@nxp.com> Thanks, Neeraj On Thu, Feb 13, 2025 at 03:34:30PM +0100, Loic Poulain wrote: > This brings support for dedicated interrupt as wakeup source into the > serdev core, similarly to the I2C bus, and aligned with the documentation: > Documentation/devicetree/bindings/power/wakeup-source.txt > > As an example, this can be used for bluetooth serial devices with dedicated > controller-to-host wakeup pin. > > Signed-off-by: Loic Poulain <loic.poulain@linaro.org> > --- > drivers/tty/serdev/core.c | 48 +++++++++++++++++++++++++++++++++++++-- > include/linux/serdev.h | 1 + > 2 files changed, 47 insertions(+), 2 deletions(-) > > diff --git a/drivers/tty/serdev/core.c b/drivers/tty/serdev/core.c > index ebf0bbc2cff2..2d016fa546ca 100644 > --- a/drivers/tty/serdev/core.c > +++ b/drivers/tty/serdev/core.c > @@ -13,8 +13,10 @@ > #include <linux/module.h> > #include <linux/of.h> > #include <linux/of_device.h> > +#include <linux/of_irq.h> > #include <linux/pm_domain.h> > #include <linux/pm_runtime.h> > +#include <linux/pm_wakeirq.h> > #include <linux/property.h> > #include <linux/sched.h> > #include <linux/serdev.h> > @@ -164,6 +166,9 @@ int serdev_device_open(struct serdev_device *serdev) > goto err_close; > } > > + if (serdev->wakeup_source) > + device_wakeup_enable(&serdev->dev); > + > return 0; > > err_close: > @@ -181,6 +186,9 @@ void serdev_device_close(struct serdev_device *serdev) > if (!ctrl || !ctrl->ops->close) > return; > > + if (serdev->wakeup_source) > + device_wakeup_disable(&serdev->dev); > + > pm_runtime_put(&ctrl->dev); > > ctrl->ops->close(ctrl); > @@ -406,18 +414,52 @@ int serdev_device_break_ctl(struct serdev_device *serdev, int break_state) > } > EXPORT_SYMBOL_GPL(serdev_device_break_ctl); > > +static int serdev_wakeup_attach(struct device *dev) > +{ > + int wakeirq; > + > + if (!of_property_read_bool(dev->of_node, "wakeup-source")) > + return 0; > + > + to_serdev_device(dev)->wakeup_source = true; > + > + device_set_wakeup_capable(dev, true); > + > + wakeirq = of_irq_get_byname(dev->of_node, "wakeup"); > + if (wakeirq == -EPROBE_DEFER) > + return -EPROBE_DEFER; > + else if (wakeirq > 0) > + return dev_pm_set_dedicated_wake_irq(dev, wakeirq); > + > + return 0; > +} > + > +static void serdev_wakeup_detach(struct device *dev) > +{ > + device_init_wakeup(dev, false); > + dev_pm_clear_wake_irq(dev); > +} > + > static int serdev_drv_probe(struct device *dev) > { > const struct serdev_device_driver *sdrv = to_serdev_device_driver(dev->driver); > int ret; > > - ret = dev_pm_domain_attach(dev, true); > + ret = serdev_wakeup_attach(dev); > if (ret) > return ret; > > + ret = dev_pm_domain_attach(dev, true); > + if (ret) { > + serdev_wakeup_detach(dev); > + return ret; > + } > + > ret = sdrv->probe(to_serdev_device(dev)); > - if (ret) > + if (ret) { > dev_pm_domain_detach(dev, true); > + serdev_wakeup_detach(dev); > + } > > return ret; > } > @@ -429,6 +471,8 @@ static void serdev_drv_remove(struct device *dev) > sdrv->remove(to_serdev_device(dev)); > > dev_pm_domain_detach(dev, true); > + > + serdev_wakeup_detach(dev); > } > > static const struct bus_type serdev_bus_type = { > diff --git a/include/linux/serdev.h b/include/linux/serdev.h > index ff78efc1f60d..2b3ee7b2c141 100644 > --- a/include/linux/serdev.h > +++ b/include/linux/serdev.h > @@ -47,6 +47,7 @@ struct serdev_device { > const struct serdev_device_ops *ops; > struct completion write_comp; > struct mutex write_lock; > + bool wakeup_source; > }; > > static inline struct serdev_device *to_serdev_device(struct device *d) > -- > 2.34.1 > ^ permalink raw reply [flat|nested] 4+ messages in thread
* RE: [PATCH] serdev: Add support for wakeup-source 2025-03-21 13:24 ` Neeraj Sanjay Kale @ 2025-04-07 13:29 ` Neeraj Sanjay Kale 0 siblings, 0 replies; 4+ messages in thread From: Neeraj Sanjay Kale @ 2025-04-07 13:29 UTC (permalink / raw) To: robh@kernel.org, jirislaby@kernel.org, gregkh@linuxfoundation.org Cc: linux-serial@vger.kernel.org, Manjeet Gupta, Amitkumar Karwar, Sherry Sun, Loic Poulain Hello maintainers, This patch is in review for quite some time, and it's an important feature which we would like to have support for, in the NXP BT UART driver. If there are no further review comments, can you please help approve this? Thanks, Neeraj > Hi Loic, > > Thank you for the patch. > > I have verified this patch with btnxpuart driver and I am able to wakeup the > host with a GPIO interrupt signal from BT controller. > > Tested-by: Neeraj Sanjay Kale <neeraj.sanjaykale@nxp.com> > > Thanks, > Neeraj > > On Thu, Feb 13, 2025 at 03:34:30PM +0100, Loic Poulain wrote: > > This brings support for dedicated interrupt as wakeup source into the > > serdev core, similarly to the I2C bus, and aligned with the documentation: > > Documentation/devicetree/bindings/power/wakeup-source.txt > > > > As an example, this can be used for bluetooth serial devices with > > dedicated controller-to-host wakeup pin. > > > > Signed-off-by: Loic Poulain <loic.poulain@linaro.org> > > --- > > drivers/tty/serdev/core.c | 48 > +++++++++++++++++++++++++++++++++++++-- > > include/linux/serdev.h | 1 + > > 2 files changed, 47 insertions(+), 2 deletions(-) > > > > diff --git a/drivers/tty/serdev/core.c b/drivers/tty/serdev/core.c > > index ebf0bbc2cff2..2d016fa546ca 100644 > > --- a/drivers/tty/serdev/core.c > > +++ b/drivers/tty/serdev/core.c > > @@ -13,8 +13,10 @@ > > #include <linux/module.h> > > #include <linux/of.h> > > #include <linux/of_device.h> > > +#include <linux/of_irq.h> > > #include <linux/pm_domain.h> > > #include <linux/pm_runtime.h> > > +#include <linux/pm_wakeirq.h> > > #include <linux/property.h> > > #include <linux/sched.h> > > #include <linux/serdev.h> > > @@ -164,6 +166,9 @@ int serdev_device_open(struct serdev_device > *serdev) > > goto err_close; > > } > > > > + if (serdev->wakeup_source) > > + device_wakeup_enable(&serdev->dev); > > + > > return 0; > > > > err_close: > > @@ -181,6 +186,9 @@ void serdev_device_close(struct serdev_device > *serdev) > > if (!ctrl || !ctrl->ops->close) > > return; > > > > + if (serdev->wakeup_source) > > + device_wakeup_disable(&serdev->dev); > > + > > pm_runtime_put(&ctrl->dev); > > > > ctrl->ops->close(ctrl); > > @@ -406,18 +414,52 @@ int serdev_device_break_ctl(struct serdev_device > > *serdev, int break_state) } > > EXPORT_SYMBOL_GPL(serdev_device_break_ctl); > > > > +static int serdev_wakeup_attach(struct device *dev) { > > + int wakeirq; > > + > > + if (!of_property_read_bool(dev->of_node, "wakeup-source")) > > + return 0; > > + > > + to_serdev_device(dev)->wakeup_source = true; > > + > > + device_set_wakeup_capable(dev, true); > > + > > + wakeirq = of_irq_get_byname(dev->of_node, "wakeup"); > > + if (wakeirq == -EPROBE_DEFER) > > + return -EPROBE_DEFER; > > + else if (wakeirq > 0) > > + return dev_pm_set_dedicated_wake_irq(dev, wakeirq); > > + > > + return 0; > > +} > > + > > +static void serdev_wakeup_detach(struct device *dev) { > > + device_init_wakeup(dev, false); > > + dev_pm_clear_wake_irq(dev); > > +} > > + > > static int serdev_drv_probe(struct device *dev) { > > const struct serdev_device_driver *sdrv = > to_serdev_device_driver(dev->driver); > > int ret; > > > > - ret = dev_pm_domain_attach(dev, true); > > + ret = serdev_wakeup_attach(dev); > > if (ret) > > return ret; > > > > + ret = dev_pm_domain_attach(dev, true); > > + if (ret) { > > + serdev_wakeup_detach(dev); > > + return ret; > > + } > > + > > ret = sdrv->probe(to_serdev_device(dev)); > > - if (ret) > > + if (ret) { > > dev_pm_domain_detach(dev, true); > > + serdev_wakeup_detach(dev); > > + } > > > > return ret; > > } > > @@ -429,6 +471,8 @@ static void serdev_drv_remove(struct device *dev) > > sdrv->remove(to_serdev_device(dev)); > > > > dev_pm_domain_detach(dev, true); > > + > > + serdev_wakeup_detach(dev); > > } > > > > static const struct bus_type serdev_bus_type = { diff --git > > a/include/linux/serdev.h b/include/linux/serdev.h index > > ff78efc1f60d..2b3ee7b2c141 100644 > > --- a/include/linux/serdev.h > > +++ b/include/linux/serdev.h > > @@ -47,6 +47,7 @@ struct serdev_device { > > const struct serdev_device_ops *ops; > > struct completion write_comp; > > struct mutex write_lock; > > + bool wakeup_source; > > }; > > > > static inline struct serdev_device *to_serdev_device(struct device > > *d) > > -- > > 2.34.1 > > ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] serdev: Add support for wakeup-source 2025-02-13 14:34 [PATCH] serdev: Add support for wakeup-source Loic Poulain 2025-03-21 13:24 ` Neeraj Sanjay Kale @ 2025-04-08 13:09 ` Rob Herring 1 sibling, 0 replies; 4+ messages in thread From: Rob Herring @ 2025-04-08 13:09 UTC (permalink / raw) To: Loic Poulain; +Cc: jirislaby, gregkh, linux-serial On Thu, Feb 13, 2025 at 8:34 AM Loic Poulain <loic.poulain@linaro.org> wrote: > > This brings support for dedicated interrupt as wakeup source into the > serdev core, similarly to the I2C bus, and aligned with the documentation: > Documentation/devicetree/bindings/power/wakeup-source.txt Don't add new references to old documentation. The difference I think is I2C has some defined mechanisms for wakeup. We don't have anything in platform devices, SPI, etc., so why serdev? A "wakeup" IRQ is also a suggestion more than a hard requirement of how wakeup is implemented. Rob ^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2025-04-08 13:09 UTC | newest] Thread overview: 4+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2025-02-13 14:34 [PATCH] serdev: Add support for wakeup-source Loic Poulain 2025-03-21 13:24 ` Neeraj Sanjay Kale 2025-04-07 13:29 ` Neeraj Sanjay Kale 2025-04-08 13:09 ` Rob Herring
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox