tty: serial: qcom_geni_serial: Wakeup IRQ cleanup
This patch is the continuation of below mentioned commits which adds wakeup feature over the UART RX line. 1)commit3e4aaea7a0
("tty: serial: qcom_geni_serial: IRQ cleanup")[v2] 2)commit8b7103f319
("tty: serial: qcom_geni_serial: Wakeup over UART RX")[v2] The following cleanup is done based on upstream comment received on subsequent versions of the above-mentioned commits to simplifying the code. - Use devm_kasprintf API in place of scnprintf. - Use 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. We can remove the code for enabling and disabling of wake irq from the this driver. - Use platform_get_irq_optional API to get optional wakeup IRQ for device. - Move ISR registration later in probe after uart port gets register with serial core. Patch link: - https://patchwork.kernel.org/patch/11189717/ (v3) - https://patchwork.kernel.org/patch/11227435/ (v4) - https://patchwork.kernel.org/patch/11241669/ (v5) - https://patchwork.kernel.org/patch/11258045/ (v6) Signed-off-by: Akash Asthana <akashast@codeaurora.org> Reviewed-by: Matthias Kaehlcke <mka@chromium.org> Reviewed-by: Stephen Boyd <swboyd@chromium.org> Link: https://lore.kernel.org/r/1578321905-25843-2-git-send-email-akashast@codeaurora.org Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
b209713199
commit
f3974413cf
@ -10,6 +10,7 @@
|
||||
#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>
|
||||
@ -99,7 +100,7 @@
|
||||
struct qcom_geni_serial_port {
|
||||
struct uart_port uport;
|
||||
struct geni_se se;
|
||||
char name[20];
|
||||
const char *name;
|
||||
u32 tx_fifo_depth;
|
||||
u32 tx_fifo_width;
|
||||
u32 rx_fifo_depth;
|
||||
@ -753,15 +754,6 @@ out_write_wakeup:
|
||||
uart_write_wakeup(uport);
|
||||
}
|
||||
|
||||
static irqreturn_t qcom_geni_serial_wakeup_isr(int isr, void *dev)
|
||||
{
|
||||
struct uart_port *uport = dev;
|
||||
|
||||
pm_wakeup_event(uport->dev, 2000);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static irqreturn_t qcom_geni_serial_isr(int isr, void *dev)
|
||||
{
|
||||
u32 m_irq_en;
|
||||
@ -1298,51 +1290,59 @@ static int qcom_geni_serial_probe(struct platform_device *pdev)
|
||||
port->rx_fifo_depth = DEF_FIFO_DEPTH_WORDS;
|
||||
port->tx_fifo_width = DEF_FIFO_WIDTH_BITS;
|
||||
|
||||
scnprintf(port->name, sizeof(port->name), "qcom_geni_serial_%s%d",
|
||||
(uart_console(uport) ? "console" : "uart"), uport->line);
|
||||
port->name = devm_kasprintf(uport->dev, GFP_KERNEL,
|
||||
"qcom_geni_serial_%s%d",
|
||||
uart_console(uport) ? "console" : "uart", uport->line);
|
||||
if (!port->name)
|
||||
return -ENOMEM;
|
||||
|
||||
irq = platform_get_irq(pdev, 0);
|
||||
if (irq < 0)
|
||||
return irq;
|
||||
uport->irq = irq;
|
||||
uport->has_sysrq = IS_ENABLED(CONFIG_SERIAL_QCOM_GENI_CONSOLE);
|
||||
|
||||
irq_set_status_flags(uport->irq, IRQ_NOAUTOEN);
|
||||
ret = devm_request_irq(uport->dev, uport->irq, qcom_geni_serial_isr,
|
||||
IRQF_TRIGGER_HIGH, port->name, uport);
|
||||
if (ret) {
|
||||
dev_err(uport->dev, "Failed to get IRQ ret %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
if (!console)
|
||||
port->wakeup_irq = platform_get_irq_optional(pdev, 1);
|
||||
|
||||
if (!console) {
|
||||
port->wakeup_irq = platform_get_irq(pdev, 1);
|
||||
if (port->wakeup_irq < 0) {
|
||||
dev_err(&pdev->dev, "Failed to get wakeup IRQ %d\n",
|
||||
port->wakeup_irq);
|
||||
} else {
|
||||
irq_set_status_flags(port->wakeup_irq, IRQ_NOAUTOEN);
|
||||
ret = devm_request_irq(uport->dev, port->wakeup_irq,
|
||||
qcom_geni_serial_wakeup_isr,
|
||||
IRQF_TRIGGER_FALLING, "uart_wakeup", uport);
|
||||
if (ret) {
|
||||
dev_err(uport->dev, "Failed to register wakeup IRQ ret %d\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
device_init_wakeup(&pdev->dev, true);
|
||||
ret = dev_pm_set_wake_irq(&pdev->dev, port->wakeup_irq);
|
||||
if (unlikely(ret))
|
||||
dev_err(uport->dev, "%s:Failed to set IRQ wake:%d\n",
|
||||
__func__, ret);
|
||||
}
|
||||
}
|
||||
uport->private_data = drv;
|
||||
platform_set_drvdata(pdev, port);
|
||||
port->handle_rx = console ? handle_rx_console : handle_rx_uart;
|
||||
if (!console)
|
||||
device_create_file(uport->dev, &dev_attr_loopback);
|
||||
return uart_add_one_port(drv, uport);
|
||||
|
||||
ret = uart_add_one_port(drv, uport);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
irq_set_status_flags(uport->irq, IRQ_NOAUTOEN);
|
||||
ret = devm_request_irq(uport->dev, uport->irq, qcom_geni_serial_isr,
|
||||
IRQF_TRIGGER_HIGH, port->name, uport);
|
||||
if (ret) {
|
||||
dev_err(uport->dev, "Failed to get IRQ ret %d\n", ret);
|
||||
uart_remove_one_port(drv, uport);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set pm_runtime status as ACTIVE so that wakeup_irq gets
|
||||
* enabled/disabled from dev_pm_arm_wake_irq during system
|
||||
* 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 0;
|
||||
}
|
||||
|
||||
static int qcom_geni_serial_remove(struct platform_device *pdev)
|
||||
@ -1350,7 +1350,10 @@ static int qcom_geni_serial_remove(struct platform_device *pdev)
|
||||
struct qcom_geni_serial_port *port = platform_get_drvdata(pdev);
|
||||
struct uart_driver *drv = port->uport.private_data;
|
||||
|
||||
dev_pm_clear_wake_irq(&pdev->dev);
|
||||
device_init_wakeup(&pdev->dev, false);
|
||||
uart_remove_one_port(drv, &port->uport);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1359,12 +1362,7 @@ static int __maybe_unused qcom_geni_serial_sys_suspend(struct device *dev)
|
||||
struct qcom_geni_serial_port *port = dev_get_drvdata(dev);
|
||||
struct uart_port *uport = &port->uport;
|
||||
|
||||
uart_suspend_port(uport->private_data, uport);
|
||||
|
||||
if (port->wakeup_irq > 0)
|
||||
enable_irq(port->wakeup_irq);
|
||||
|
||||
return 0;
|
||||
return uart_suspend_port(uport->private_data, uport);
|
||||
}
|
||||
|
||||
static int __maybe_unused qcom_geni_serial_sys_resume(struct device *dev)
|
||||
@ -1372,9 +1370,6 @@ static int __maybe_unused qcom_geni_serial_sys_resume(struct device *dev)
|
||||
struct qcom_geni_serial_port *port = dev_get_drvdata(dev);
|
||||
struct uart_port *uport = &port->uport;
|
||||
|
||||
if (port->wakeup_irq > 0)
|
||||
disable_irq(port->wakeup_irq);
|
||||
|
||||
return uart_resume_port(uport->private_data, uport);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user