[PATCH v5 09/15] OMAP2+: UART: Add runtime pm support for omap-serial driver
From: tom.leiming@gmail.com (Ming Lei)
Date: 2011-09-22 07:48:51
Also in:
linux-omap, linux-serial
Hi, On Wed, Sep 21, 2011 at 8:13 PM, Govindraj.R [off-list ref] wrote:
Adapts omap-serial driver to use pm_runtime API's.
? ? ? ?console_unlock(); - ? ? ? if ((cpu_is_omap34xx() && bdata->pads) || - ? ? ? ? ? ? ? (pdata->wk_en && pdata->wk_mask)) + ? ? ? if ((cpu_is_omap34xx() && bdata->pads)) ? ? ? ? ? ? ? ?device_init_wakeup(&pdev->dev, true);
Just a bit curious, why doesn't the code enable wakeup at default on omap4, which will disable runtime pm of serial port on omap4. I have tested your patches on omap4 panda(enable wakeup at default manually), runtime pm of serial port 2 can work well and remote wakeup too.
quoted hunk ↗ jump to hunk
? ? ? ?kfree(pdata);diff --git a/arch/arm/plat-omap/include/plat/omap-serial.h b/arch/arm/plat-omap/include/plat/omap-serial.h index 74822b3..8ef81ce 100644 --- a/arch/arm/plat-omap/include/plat/omap-serial.h +++ b/arch/arm/plat-omap/include/plat/omap-serial.h@@ -62,6 +62,9 @@ struct omap_uart_port_info {? ? ? ?upf_t ? ? ? ? ? ? ? ? ? flags; ? ? ? ? ?/* UPF_* flags */ ? ? ? ?u32 ? ? ? ? ? ? ? ? ? ? errata; + + ? ? ? void (*enable_wakeup)(struct platform_device *, bool); + ? ? ? u32 (*get_context_loss_count)(struct device *); ?}; ?struct uart_omap_dma {@@ -113,6 +116,8 @@ struct uart_omap_port {? ? ? ?unsigned char ? ? ? ? ? msr_saved_flags; ? ? ? ?char ? ? ? ? ? ? ? ? ? ?name[20]; ? ? ? ?unsigned long ? ? ? ? ? port_activity; + ? ? ? u32 ? ? ? ? ? ? ? ? ? ? context_loss_cnt; + ? ? ? u8 ? ? ? ? ? ? ? ? ? ? ?wakeups_enabled; ?}; ?#endif /* __OMAP_SERIAL_H__ */diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c index 9a0eac2..43c33da 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c@@ -37,11 +37,14 @@?#include <linux/clk.h> ?#include <linux/serial_core.h> ?#include <linux/irq.h> +#include <linux/pm_runtime.h> ?#include <plat/dma.h> ?#include <plat/dmtimer.h> ?#include <plat/omap-serial.h> +#define OMAP_UART_AUTOSUSPEND_DELAY -1 + ?static struct uart_omap_port *ui[OMAP_MAX_HSUART_PORTS]; ?/* Forward declaration of functions */@@ -102,6 +105,8 @@ static void serial_omap_stop_rxdma(struct uart_omap_port *up)? ? ? ? ? ? ? ?omap_free_dma(up->uart_dma.rx_dma_channel); ? ? ? ? ? ? ? ?up->uart_dma.rx_dma_channel = OMAP_UART_DMA_CH_FREE; ? ? ? ? ? ? ? ?up->uart_dma.rx_dma_used = false; + ? ? ? ? ? ? ? pm_runtime_mark_last_busy(&up->pdev->dev); + ? ? ? ? ? ? ? pm_runtime_put_autosuspend(&up->pdev->dev); ? ? ? ?} ?}@@ -110,8 +115,11 @@ static void serial_omap_enable_ms(struct uart_port *port)? ? ? ?struct uart_omap_port *up = (struct uart_omap_port *)port; ? ? ? ?dev_dbg(up->port.dev, "serial_omap_enable_ms+%d\n", up->pdev->id); + + ? ? ? pm_runtime_get_sync(&up->pdev->dev); ? ? ? ?up->ier |= UART_IER_MSI; ? ? ? ?serial_out(up, UART_IER, up->ier); + ? ? ? pm_runtime_put(&up->pdev->dev); ?} ?static void serial_omap_stop_tx(struct uart_port *port)@@ -129,23 +137,32 @@ static void serial_omap_stop_tx(struct uart_port *port)? ? ? ? ? ? ? ?omap_stop_dma(up->uart_dma.tx_dma_channel); ? ? ? ? ? ? ? ?omap_free_dma(up->uart_dma.tx_dma_channel); ? ? ? ? ? ? ? ?up->uart_dma.tx_dma_channel = OMAP_UART_DMA_CH_FREE; + ? ? ? ? ? ? ? pm_runtime_mark_last_busy(&up->pdev->dev); + ? ? ? ? ? ? ? pm_runtime_put_autosuspend(&up->pdev->dev); ? ? ? ?} + ? ? ? pm_runtime_get_sync(&up->pdev->dev); ? ? ? ?if (up->ier & UART_IER_THRI) { ? ? ? ? ? ? ? ?up->ier &= ~UART_IER_THRI; ? ? ? ? ? ? ? ?serial_out(up, UART_IER, up->ier); ? ? ? ?} + + ? ? ? pm_runtime_mark_last_busy(&up->pdev->dev); + ? ? ? pm_runtime_put_autosuspend(&up->pdev->dev); ?} ?static void serial_omap_stop_rx(struct uart_port *port) ?{ ? ? ? ?struct uart_omap_port *up = (struct uart_omap_port *)port; + ? ? ? pm_runtime_get_sync(&up->pdev->dev); ? ? ? ?if (up->use_dma) ? ? ? ? ? ? ? ?serial_omap_stop_rxdma(up); ? ? ? ?up->ier &= ~UART_IER_RLSI; ? ? ? ?up->port.read_status_mask &= ~UART_LSR_DR; ? ? ? ?serial_out(up, UART_IER, up->ier); + ? ? ? pm_runtime_mark_last_busy(&up->pdev->dev); + ? ? ? pm_runtime_put_autosuspend(&up->pdev->dev); ?} ?static inline void receive_chars(struct uart_omap_port *up, int *status)@@ -262,7 +279,10 @@ static void serial_omap_start_tx(struct uart_port *port)? ? ? ?int ret = 0; ? ? ? ?if (!up->use_dma) { + ? ? ? ? ? ? ? pm_runtime_get_sync(&up->pdev->dev); ? ? ? ? ? ? ? ?serial_omap_enable_ier_thri(up); + ? ? ? ? ? ? ? pm_runtime_mark_last_busy(&up->pdev->dev); + ? ? ? ? ? ? ? pm_runtime_put_autosuspend(&up->pdev->dev); ? ? ? ? ? ? ? ?return; ? ? ? ?}@@ -272,6 +292,7 @@ static void serial_omap_start_tx(struct uart_port *port)? ? ? ?xmit = &up->port.state->xmit; ? ? ? ?if (up->uart_dma.tx_dma_channel == OMAP_UART_DMA_CH_FREE) { + ? ? ? ? ? ? ? pm_runtime_get_sync(&up->pdev->dev); ? ? ? ? ? ? ? ?ret = omap_request_dma(up->uart_dma.uart_dma_tx, ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?"UART Tx DMA", ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?(void *)uart_tx_dma_callback, up,@@ -354,9 +375,13 @@ static inline irqreturn_t serial_omap_irq(int irq, void *dev_id)? ? ? ?unsigned int iir, lsr; ? ? ? ?unsigned long flags; + ? ? ? pm_runtime_get_sync(&up->pdev->dev); ? ? ? ?iir = serial_in(up, UART_IIR); - ? ? ? if (iir & UART_IIR_NO_INT) + ? ? ? if (iir & UART_IIR_NO_INT) { + ? ? ? ? ? ? ? pm_runtime_mark_last_busy(&up->pdev->dev); + ? ? ? ? ? ? ? pm_runtime_put_autosuspend(&up->pdev->dev); ? ? ? ? ? ? ? ?return IRQ_NONE; + ? ? ? } ? ? ? ?spin_lock_irqsave(&up->port.lock, flags); ? ? ? ?lsr = serial_in(up, UART_LSR);@@ -378,6 +403,9 @@ static inline irqreturn_t serial_omap_irq(int irq, void *dev_id)? ? ? ? ? ? ? ?transmit_chars(up); ? ? ? ?spin_unlock_irqrestore(&up->port.lock, flags); + ? ? ? pm_runtime_mark_last_busy(&up->pdev->dev); + ? ? ? pm_runtime_put_autosuspend(&up->pdev->dev); + ? ? ? ?up->port_activity = jiffies; ? ? ? ?return IRQ_HANDLED; ?}@@ -388,11 +416,12 @@ static unsigned int serial_omap_tx_empty(struct uart_port *port)? ? ? ?unsigned long flags = 0; ? ? ? ?unsigned int ret = 0; + ? ? ? pm_runtime_get_sync(&up->pdev->dev); ? ? ? ?dev_dbg(up->port.dev, "serial_omap_tx_empty+%d\n", up->pdev->id); ? ? ? ?spin_lock_irqsave(&up->port.lock, flags); ? ? ? ?ret = serial_in(up, UART_LSR) & UART_LSR_TEMT ? TIOCSER_TEMT : 0; ? ? ? ?spin_unlock_irqrestore(&up->port.lock, flags); - + ? ? ? pm_runtime_put(&up->pdev->dev); ? ? ? ?return ret; ?}@@ -402,7 +431,10 @@ static unsigned int serial_omap_get_mctrl(struct uart_port *port)? ? ? ?unsigned char status; ? ? ? ?unsigned int ret = 0; + ? ? ? pm_runtime_get_sync(&up->pdev->dev); ? ? ? ?status = check_modem_status(up); + ? ? ? pm_runtime_put(&up->pdev->dev); + ? ? ? ?dev_dbg(up->port.dev, "serial_omap_get_mctrl+%d\n", up->pdev->id); ? ? ? ?if (status & UART_MSR_DCD)@@ -433,9 +465,11 @@ static void serial_omap_set_mctrl(struct uart_port *port, unsigned int mctrl)? ? ? ?if (mctrl & TIOCM_LOOP) ? ? ? ? ? ? ? ?mcr |= UART_MCR_LOOP; + ? ? ? pm_runtime_get_sync(&up->pdev->dev); ? ? ? ?up->mcr = serial_in(up, UART_MCR); ? ? ? ?up->mcr |= mcr; ? ? ? ?serial_out(up, UART_MCR, up->mcr); + ? ? ? pm_runtime_put(&up->pdev->dev); ?} ?static void serial_omap_break_ctl(struct uart_port *port, int break_state)@@ -444,6 +478,7 @@ static void serial_omap_break_ctl(struct uart_port *port, int break_state)? ? ? ?unsigned long flags = 0; ? ? ? ?dev_dbg(up->port.dev, "serial_omap_break_ctl+%d\n", up->pdev->id); + ? ? ? pm_runtime_get_sync(&up->pdev->dev); ? ? ? ?spin_lock_irqsave(&up->port.lock, flags); ? ? ? ?if (break_state == -1) ? ? ? ? ? ? ? ?up->lcr |= UART_LCR_SBC;@@ -451,6 +486,7 @@ static void serial_omap_break_ctl(struct uart_port *port, int break_state)? ? ? ? ? ? ? ?up->lcr &= ~UART_LCR_SBC; ? ? ? ?serial_out(up, UART_LCR, up->lcr); ? ? ? ?spin_unlock_irqrestore(&up->port.lock, flags); + ? ? ? pm_runtime_put(&up->pdev->dev); ?} ?static int serial_omap_startup(struct uart_port *port)@@ -469,6 +505,7 @@ static int serial_omap_startup(struct uart_port *port)? ? ? ?dev_dbg(up->port.dev, "serial_omap_startup+%d\n", up->pdev->id); + ? ? ? pm_runtime_get_sync(&up->pdev->dev); ? ? ? ?/* ? ? ? ? * Clear the FIFO buffers and disable them. ? ? ? ? * (they will be reenabled in set_termios())@@ -524,6 +561,8 @@ static int serial_omap_startup(struct uart_port *port)? ? ? ?/* Enable module level wake up */ ? ? ? ?serial_out(up, UART_OMAP_WER, OMAP_UART_WER_MOD_WKUP); + ? ? ? pm_runtime_mark_last_busy(&up->pdev->dev); + ? ? ? pm_runtime_put_autosuspend(&up->pdev->dev); ? ? ? ?up->port_activity = jiffies; ? ? ? ?return 0; ?}@@ -534,6 +573,8 @@ static void serial_omap_shutdown(struct uart_port *port)? ? ? ?unsigned long flags = 0; ? ? ? ?dev_dbg(up->port.dev, "serial_omap_shutdown+%d\n", up->pdev->id); + + ? ? ? pm_runtime_get_sync(&up->pdev->dev); ? ? ? ?/* ? ? ? ? * Disable interrupts from this port ? ? ? ? */@@ -567,6 +608,7 @@ static void serial_omap_shutdown(struct uart_port *port)? ? ? ? ? ? ? ? ? ? ? ?up->uart_dma.rx_buf_dma_phys); ? ? ? ? ? ? ? ?up->uart_dma.rx_buf = NULL; ? ? ? ?} + ? ? ? pm_runtime_put(&up->pdev->dev); ? ? ? ?free_irq(up->port.irq, up); ?}@@ -682,6 +724,7 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios,? ? ? ? * Ok, we're now changing the port state. Do it with ? ? ? ? * interrupts disabled. ? ? ? ? */ + ? ? ? pm_runtime_get_sync(&up->pdev->dev); ? ? ? ?spin_lock_irqsave(&up->port.lock, flags); ? ? ? ?/*@@ -814,6 +857,7 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios,? ? ? ?serial_omap_configure_xonxoff(up, termios); ? ? ? ?spin_unlock_irqrestore(&up->port.lock, flags); + ? ? ? pm_runtime_put(&up->pdev->dev); ? ? ? ?dev_dbg(up->port.dev, "serial_omap_set_termios+%d\n", up->pdev->id); ?}@@ -825,6 +869,8 @@ serial_omap_pm(struct uart_port *port, unsigned int state,? ? ? ?unsigned char efr; ? ? ? ?dev_dbg(up->port.dev, "serial_omap_pm+%d\n", up->pdev->id); + + ? ? ? pm_runtime_get_sync(&up->pdev->dev); ? ? ? ?serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); ? ? ? ?efr = serial_in(up, UART_EFR); ? ? ? ?serial_out(up, UART_EFR, efr | UART_EFR_ECB);@@ -834,6 +880,7 @@ serial_omap_pm(struct uart_port *port, unsigned int state,? ? ? ?serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); ? ? ? ?serial_out(up, UART_EFR, efr); ? ? ? ?serial_out(up, UART_LCR, 0); + ? ? ? pm_runtime_put(&up->pdev->dev); ?} ?static void serial_omap_release_port(struct uart_port *port)@@ -911,19 +958,26 @@ static inline void wait_for_xmitr(struct uart_omap_port *up)?static void serial_omap_poll_put_char(struct uart_port *port, unsigned char ch) ?{ ? ? ? ?struct uart_omap_port *up = (struct uart_omap_port *)port; + + ? ? ? pm_runtime_get_sync(&up->pdev->dev); ? ? ? ?wait_for_xmitr(up); ? ? ? ?serial_out(up, UART_TX, ch); + ? ? ? pm_runtime_put(&up->pdev->dev); ?} ?static int serial_omap_poll_get_char(struct uart_port *port) ?{ ? ? ? ?struct uart_omap_port *up = (struct uart_omap_port *)port; - ? ? ? unsigned int status = serial_in(up, UART_LSR); + ? ? ? unsigned int status; + ? ? ? pm_runtime_get_sync(&up->pdev->dev); + ? ? ? status = serial_in(up, UART_LSR); ? ? ? ?if (!(status & UART_LSR_DR)) ? ? ? ? ? ? ? ?return NO_POLL_CHAR; - ? ? ? return serial_in(up, UART_RX); + ? ? ? status = serial_in(up, UART_RX); + ? ? ? pm_runtime_put(&up->pdev->dev); + ? ? ? return status; ?} ?#endif /* CONFIG_CONSOLE_POLL */@@ -951,6 +1005,8 @@ serial_omap_console_write(struct console *co, const char *s,? ? ? ?unsigned int ier; ? ? ? ?int locked = 1; + ? ? ? pm_runtime_get_sync(&up->pdev->dev); + ? ? ? ?local_irq_save(flags); ? ? ? ?if (up->port.sysrq) ? ? ? ? ? ? ? ?locked = 0;@@ -983,6 +1039,8 @@ serial_omap_console_write(struct console *co, const char *s,? ? ? ?if (up->msr_saved_flags) ? ? ? ? ? ? ? ?check_modem_status(up); + ? ? ? pm_runtime_mark_last_busy(&up->pdev->dev); + ? ? ? pm_runtime_put_autosuspend(&up->pdev->dev); ? ? ? ?if (locked) ? ? ? ? ? ? ? ?spin_unlock(&up->port.lock); ? ? ? ?local_irq_restore(flags);@@ -1065,19 +1123,18 @@ static struct uart_driver serial_omap_reg = {? ? ? ?.cons ? ? ? ? ? = OMAP_CONSOLE, ?}; -static int -serial_omap_suspend(struct platform_device *pdev, pm_message_t state) +static int serial_omap_suspend(struct device *dev) ?{ - ? ? ? struct uart_omap_port *up = platform_get_drvdata(pdev); + ? ? ? struct uart_omap_port *up = dev_get_drvdata(dev); ? ? ? ?if (up) ? ? ? ? ? ? ? ?uart_suspend_port(&serial_omap_reg, &up->port); ? ? ? ?return 0; ?} -static int serial_omap_resume(struct platform_device *dev) +static int serial_omap_resume(struct device *dev) ?{ - ? ? ? struct uart_omap_port *up = platform_get_drvdata(dev); + ? ? ? struct uart_omap_port *up = dev_get_drvdata(dev); ? ? ? ?if (up) ? ? ? ? ? ? ? ?uart_resume_port(&serial_omap_reg, &up->port);@@ -1140,6 +1197,7 @@ static int serial_omap_start_rxdma(struct uart_omap_port *up)? ? ? ?int ret = 0; ? ? ? ?if (up->uart_dma.rx_dma_channel == -1) { + ? ? ? ? ? ? ? pm_runtime_get_sync(&up->pdev->dev); ? ? ? ? ? ? ? ?ret = omap_request_dma(up->uart_dma.uart_dma_rx, ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?"UART Rx DMA", ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?(void *)uart_rx_dma_callback, up,@@ -1305,6 +1363,16 @@ static int serial_omap_probe(struct platform_device *pdev)? ? ? ? ? ? ? ?up->uart_dma.rx_dma_channel = OMAP_UART_DMA_CH_FREE; ? ? ? ?} + ? ? ? pm_runtime_use_autosuspend(&pdev->dev); + ? ? ? pm_runtime_set_autosuspend_delay(&pdev->dev, + ? ? ? ? ? ? ? ? ? ? ? OMAP_UART_AUTOSUSPEND_DELAY); + + ? ? ? pm_runtime_irq_safe(&pdev->dev); + ? ? ? if (device_may_wakeup(&pdev->dev)) { + ? ? ? ? ? ? ? pm_runtime_enable(&pdev->dev); + ? ? ? ? ? ? ? pm_runtime_get_sync(&pdev->dev); + ? ? ? } + ? ? ? ?ui[pdev->id] = up; ? ? ? ?serial_omap_add_console_port(up);@@ -1312,6 +1380,7 @@ static int serial_omap_probe(struct platform_device *pdev)? ? ? ?if (ret != 0) ? ? ? ? ? ? ? ?goto do_release_region; + ? ? ? pm_runtime_put(&pdev->dev); ? ? ? ?platform_set_drvdata(pdev, up); ? ? ? ?return 0; ?err:@@ -1326,22 +1395,96 @@ static int serial_omap_remove(struct platform_device *dev)?{ ? ? ? ?struct uart_omap_port *up = platform_get_drvdata(dev); - ? ? ? platform_set_drvdata(dev, NULL); ? ? ? ?if (up) { + ? ? ? ? ? ? ? pm_runtime_disable(&up->pdev->dev); ? ? ? ? ? ? ? ?uart_remove_one_port(&serial_omap_reg, &up->port); ? ? ? ? ? ? ? ?kfree(up); ? ? ? ?} + + ? ? ? platform_set_drvdata(dev, NULL); + ? ? ? return 0; +} + +static void serial_omap_restore_context(struct uart_omap_port *up) +{ + ? ? ? serial_out(up, UART_OMAP_MDR1, up->mdr1); + ? ? ? serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); /* Config B mode */ + ? ? ? serial_out(up, UART_EFR, UART_EFR_ECB); + ? ? ? serial_out(up, UART_LCR, 0x0); /* Operational mode */ + ? ? ? serial_out(up, UART_IER, 0x0); + ? ? ? serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); /* Config B mode */ + ? ? ? serial_out(up, UART_DLL, up->dll); + ? ? ? serial_out(up, UART_DLM, up->dlh); + ? ? ? serial_out(up, UART_LCR, 0x0); /* Operational mode */ + ? ? ? serial_out(up, UART_IER, up->ier); + ? ? ? serial_out(up, UART_FCR, up->fcr); + ? ? ? serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A); + ? ? ? serial_out(up, UART_MCR, up->mcr); + ? ? ? serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); /* Config B mode */ + ? ? ? serial_out(up, UART_EFR, up->efr); + ? ? ? serial_out(up, UART_LCR, up->lcr); + ? ? ? /* UART 16x mode */ + ? ? ? serial_out(up, UART_OMAP_MDR1, up->mdr1); +} + +static int serial_omap_runtime_suspend(struct device *dev) +{ + ? ? ? struct uart_omap_port *up = dev_get_drvdata(dev); + ? ? ? struct omap_uart_port_info *pdata = dev->platform_data; + + ? ? ? if (!up) + ? ? ? ? ? ? ? return -EINVAL; + + ? ? ? if (!pdata->enable_wakeup || !pdata->get_context_loss_count) + ? ? ? ? ? ? ? return 0; + + ? ? ? if (pdata->get_context_loss_count) + ? ? ? ? ? ? ? up->context_loss_cnt = pdata->get_context_loss_count(dev); + + ? ? ? if (device_may_wakeup(dev)) { + ? ? ? ? ? ? ? if (!up->wakeups_enabled) { + ? ? ? ? ? ? ? ? ? ? ? pdata->enable_wakeup(up->pdev, true); + ? ? ? ? ? ? ? ? ? ? ? up->wakeups_enabled = true; + ? ? ? ? ? ? ? } + ? ? ? } else { + ? ? ? ? ? ? ? if (up->wakeups_enabled) { + ? ? ? ? ? ? ? ? ? ? ? pdata->enable_wakeup(up->pdev, false); + ? ? ? ? ? ? ? ? ? ? ? up->wakeups_enabled = false; + ? ? ? ? ? ? ? } + ? ? ? } + + ? ? ? return 0; +} + +static int serial_omap_runtime_resume(struct device *dev) +{ + ? ? ? struct uart_omap_port *up = dev_get_drvdata(dev); + ? ? ? struct omap_uart_port_info *pdata = dev->platform_data; + + ? ? ? if (up) { + ? ? ? ? ? ? ? if (pdata->get_context_loss_count) { + ? ? ? ? ? ? ? ? ? ? ? u32 loss_cnt = pdata->get_context_loss_count(dev); + + ? ? ? ? ? ? ? ? ? ? ? if (up->context_loss_cnt != loss_cnt) + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? serial_omap_restore_context(up); + ? ? ? ? ? ? ? } + ? ? ? } + ? ? ? ?return 0; ?} +static const struct dev_pm_ops serial_omap_dev_pm_ops = { + ? ? ? SET_SYSTEM_SLEEP_PM_OPS(serial_omap_suspend, serial_omap_resume) + ? ? ? SET_RUNTIME_PM_OPS(serial_omap_runtime_suspend, + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? serial_omap_runtime_resume, NULL) +}; + ?static struct platform_driver serial_omap_driver = { ? ? ? ?.probe ? ? ? ? ?= serial_omap_probe, ? ? ? ?.remove ? ? ? ? = serial_omap_remove, - - ? ? ? .suspend ? ? ? ?= serial_omap_suspend, - ? ? ? .resume ? ? ? ? = serial_omap_resume, ? ? ? ?.driver ? ? ? ? = { ? ? ? ? ? ? ? ?.name ? = DRIVER_NAME, + ? ? ? ? ? ? ? .pm ? ? = &serial_omap_dev_pm_ops, ? ? ? ?}, ?}; -- 1.7.4.1 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majordomo at vger.kernel.org More majordomo info at ?http://vger.kernel.org/majordomo-info.html
thanks, -- Ming Lei