On Fri, Nov 22, 2019 at 02:18:19PM +0000, Akash Asthana wrote: > Add system wakeup capability over UART RX line for wakeup capable UART. > When system is suspended, RX line act as an interrupt to wakeup system > for any communication requests from peer. > > Signed-off-by: Akash Asthana <akashast@xxxxxxxxxxxxxx> > --- > Changes in V6: > - Rebased on top of tty-next branch. > - As per stephen's comment mark devices runtime status as active > irrespective of wakeup feature. > > Changes in V5: > - No change. > > Changes in V4: > - As per Greg's comment, removed extra dev_err logging. > - As per Stephen's comment, using common code that manage wakeirq irqs for > devices. Using dev_pm_set_dedicated_wake_irq API that will take care of > requesting and attaching wakeup irqs for devices. Also, it sets wakeirq > status to WAKE_IRQ_DEDICATED_ALLOCATED as a result enabling/disabling of > wake irq will be managed by suspend/resume framework so, removed the code > for enabling and disabling of wake irq from the driver. > > Changes in V3: > - As per Stephen's comment, using platform_get_irq_optional API to get wakeup > IRQ for device. > > Changes in V2: > - As per Stephen's comment, splitted V1 patch into 2 seperate patch. > a) Clean up of core IRQ registration b) Add wakeup feature. > > drivers/tty/serial/qcom_geni_serial.c | 28 ++++++++++++++++++++++++++++ > 1 file changed, 28 insertions(+) > > diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qcom_geni_serial.c > index 634054a..b952509 100644 > --- a/drivers/tty/serial/qcom_geni_serial.c > +++ b/drivers/tty/serial/qcom_geni_serial.c > @@ -14,6 +14,8 @@ > #include <linux/of.h> > #include <linux/of_device.h> > #include <linux/platform_device.h> > +#include <linux/pm_runtime.h> > +#include <linux/pm_wakeirq.h> > #include <linux/qcom-geni-se.h> > #include <linux/serial.h> > #include <linux/serial_core.h> > @@ -116,6 +118,7 @@ struct qcom_geni_serial_port { > bool brk; > > unsigned int tx_remaining; > + int wakeup_irq; > }; > > static const struct uart_ops qcom_geni_console_pops; > @@ -1302,6 +1305,9 @@ static int qcom_geni_serial_probe(struct platform_device *pdev) > return irq; > uport->irq = irq; > > + if (!console) > + port->wakeup_irq = platform_get_irq_optional(pdev, 1); > + > uport->private_data = drv; > platform_set_drvdata(pdev, port); > port->handle_rx = console ? handle_rx_console : handle_rx_uart; > @@ -1321,6 +1327,24 @@ static int qcom_geni_serial_probe(struct platform_device *pdev) > return ret; > } > > + /* > + * Set pm_runtime status as ACTIVE so that wakeup_irq gets > + * enabled/disabled from dev_pm_arm_wake_irq during system nit: remove one of the two blanks before/after 'during'. > + * suspend/resume respectively. > + */ > + pm_runtime_set_active(&pdev->dev); > + > + if (port->wakeup_irq > 0) { > + device_init_wakeup(&pdev->dev, true); > + ret = dev_pm_set_dedicated_wake_irq(&pdev->dev, > + port->wakeup_irq); > + if (ret) { > + device_init_wakeup(&pdev->dev, false); > + uart_remove_one_port(drv, uport); > + return ret; > + } > + } > + > return ret; > } > > @@ -1330,6 +1354,10 @@ static int qcom_geni_serial_remove(struct platform_device *pdev) > struct uart_driver *drv = port->uport.private_data; > > uart_remove_one_port(drv, &port->uport); > + > + device_init_wakeup(&pdev->dev, false); > + dev_pm_clear_wake_irq(&pdev->dev); > + > return 0; > } Reviewed-by: Matthias Kaehlcke <mka@xxxxxxxxxxxx>