diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-12-03 14:09:14 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-12-03 14:09:14 -0800 |
commit | 537bd0a159a041fad72d257d755205cef77582e1 (patch) | |
tree | f7e226de10589b8dfd162b80d4859dd5c00ac62e /drivers/tty/serial/qcom_geni_serial.c | |
parent | Merge tag 'pci-v5.5-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci (diff) | |
parent | Revert "serial/8250: Add support for NI-Serial PXI/PXIe+485 devices" (diff) | |
download | linux-dev-537bd0a159a041fad72d257d755205cef77582e1.tar.xz linux-dev-537bd0a159a041fad72d257d755205cef77582e1.zip |
Merge tag 'tty-5.5-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty
Pull tty/serial updates from Greg KH:
"Here is the "big" tty and serial driver patches for 5.5-rc1.
It's a bit later in the merge window than normal as I wanted to make
sure some last-minute patches applied to it were all sane. They seem
to be :)
There's a lot of little stuff in here, for the tty core, and for lots
of serial drivers:
- reverts of uartlite serial driver patches that were wrong
- msm-serial driver fixes
- serial core updates and fixes
- tty core fixes
- serial driver dma mapping api changes
- lots of other tiny fixes and updates for serial drivers
All of these have been in linux-next for a while with no reported
issues"
* tag 'tty-5.5-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty: (58 commits)
Revert "serial/8250: Add support for NI-Serial PXI/PXIe+485 devices"
vcs: prevent write access to vcsu devices
tty: vt: keyboard: reject invalid keycodes
tty: don't crash in tty_init_dev when missing tty_port
serial: stm32: fix clearing interrupt error flags
tty: Fix Kconfig indentation, continued
serial: serial_core: Perform NULL checks for break_ctl ops
tty: remove unused argument from tty_open_by_driver()
tty: Fix Kconfig indentation
{tty: serial, nand: onenand}: samsung: rename to fix build warning
serial: ifx6x60: add missed pm_runtime_disable
serial: pl011: Fix DMA ->flush_buffer()
Revert "serial-uartlite: Move the uart register"
Revert "serial-uartlite: Add get serial id if not provided"
Revert "serial-uartlite: Do not use static struct uart_driver out of probe()"
Revert "serial-uartlite: Add runtime support"
Revert "serial-uartlite: Change logic how console_port is setup"
Revert "serial-uartlite: Use allocated structure instead of static ones"
tty: serial: msm_serial: Use dma_request_chan() directly for channel request
tty: serial: tegra: Use dma_request_chan() directly for channel request
...
Diffstat (limited to 'drivers/tty/serial/qcom_geni_serial.c')
-rw-r--r-- | drivers/tty/serial/qcom_geni_serial.c | 68 |
1 files changed, 57 insertions, 11 deletions
diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qcom_geni_serial.c index 14c6306bc462..ff63728a95f4 100644 --- a/drivers/tty/serial/qcom_geni_serial.c +++ b/drivers/tty/serial/qcom_geni_serial.c @@ -9,10 +9,12 @@ #include <linux/console.h> #include <linux/io.h> #include <linux/iopoll.h> +#include <linux/irq.h> #include <linux/module.h> #include <linux/of.h> #include <linux/of_device.h> #include <linux/platform_device.h> +#include <linux/pm_wakeirq.h> #include <linux/qcom-geni-se.h> #include <linux/serial.h> #include <linux/serial_core.h> @@ -115,6 +117,7 @@ struct qcom_geni_serial_port { bool brk; unsigned int tx_remaining; + int wakeup_irq; }; static const struct uart_ops qcom_geni_console_pops; @@ -754,6 +757,15 @@ 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; @@ -830,7 +842,7 @@ static void qcom_geni_serial_shutdown(struct uart_port *uport) if (uart_console(uport)) console_stop(uport->cons); - free_irq(uport->irq, uport); + disable_irq(uport->irq); spin_lock_irqsave(&uport->lock, flags); qcom_geni_serial_stop_tx(uport); qcom_geni_serial_stop_rx(uport); @@ -890,21 +902,14 @@ static int qcom_geni_serial_startup(struct uart_port *uport) int ret; struct qcom_geni_serial_port *port = to_dev_port(uport, uport); - scnprintf(port->name, sizeof(port->name), - "qcom_serial_%s%d", - (uart_console(uport) ? "console" : "uart"), uport->line); - if (!port->setup) { ret = qcom_geni_serial_port_setup(uport); if (ret) return ret; } + enable_irq(uport->irq); - ret = request_irq(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; + return 0; } static unsigned long get_clk_cfg(unsigned long clk_freq) @@ -1297,11 +1302,44 @@ 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); irq = platform_get_irq(pdev, 0); if (irq < 0) return irq; uport->irq = irq; + 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(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; @@ -1324,7 +1362,12 @@ 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; - return uart_suspend_port(uport->private_data, uport); + uart_suspend_port(uport->private_data, uport); + + if (port->wakeup_irq > 0) + enable_irq(port->wakeup_irq); + + return 0; } static int __maybe_unused qcom_geni_serial_sys_resume(struct device *dev) @@ -1332,6 +1375,9 @@ 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); } |