diff options
Diffstat (limited to 'drivers/tty/serial/of_serial.c')
-rw-r--r-- | drivers/tty/serial/of_serial.c | 67 |
1 files changed, 59 insertions, 8 deletions
diff --git a/drivers/tty/serial/of_serial.c b/drivers/tty/serial/of_serial.c index 56982da4a9e9..22f06a6479e6 100644 --- a/drivers/tty/serial/of_serial.c +++ b/drivers/tty/serial/of_serial.c @@ -9,6 +9,7 @@ * 2 of the License, or (at your option) any later version. * */ +#include <linux/console.h> #include <linux/module.h> #include <linux/slab.h> #include <linux/delay.h> @@ -101,6 +102,10 @@ static int of_platform_serial_setup(struct platform_device *ofdev, if (of_property_read_u32(np, "fifo-size", &prop) == 0) port->fifosize = prop; + /* Check for a fixed line number */ + if ((ret = of_alias_get_id(np, "serial")) >= 0) + port->line = ret; + port->irq = irq_of_parse_and_map(np, 0); port->iotype = UPIO_MEM; if (of_property_read_u32(np, "reg-io-width", &prop) == 0) { @@ -129,8 +134,15 @@ static int of_platform_serial_setup(struct platform_device *ofdev, port->dev = &ofdev->dev; - if (type == PORT_TEGRA) + switch (type) { + case PORT_TEGRA: port->handle_break = tegra_serial_handle_break; + break; + + case PORT_RT2880: + port->iotype = UPIO_AU; + break; + } return 0; out: @@ -241,13 +253,48 @@ static int of_platform_serial_remove(struct platform_device *ofdev) } #ifdef CONFIG_PM_SLEEP -static int of_serial_suspend(struct device *dev) +#ifdef CONFIG_SERIAL_8250 +static void of_serial_suspend_8250(struct of_serial_info *info) { - struct of_serial_info *info = dev_get_drvdata(dev); + struct uart_8250_port *port8250 = serial8250_get_port(info->line); + struct uart_port *port = &port8250->port; serial8250_suspend_port(info->line); - if (info->clk) + if (info->clk && (!uart_console(port) || console_suspend_enabled)) clk_disable_unprepare(info->clk); +} + +static void of_serial_resume_8250(struct of_serial_info *info) +{ + struct uart_8250_port *port8250 = serial8250_get_port(info->line); + struct uart_port *port = &port8250->port; + + if (info->clk && (!uart_console(port) || console_suspend_enabled)) + clk_prepare_enable(info->clk); + + serial8250_resume_port(info->line); +} +#else +static inline void of_serial_suspend_8250(struct of_serial_info *info) +{ +} + +static inline void of_serial_resume_8250(struct of_serial_info *info) +{ +} +#endif + +static int of_serial_suspend(struct device *dev) +{ + struct of_serial_info *info = dev_get_drvdata(dev); + + switch(info->type) { + case PORT_8250 ... PORT_MAX_8250: + of_serial_suspend_8250(info); + break; + default: + break; + } return 0; } @@ -256,10 +303,13 @@ static int of_serial_resume(struct device *dev) { struct of_serial_info *info = dev_get_drvdata(dev); - if (info->clk) - clk_prepare_enable(info->clk); - - serial8250_resume_port(info->line); + switch(info->type) { + case PORT_8250 ... PORT_MAX_8250: + of_serial_resume_8250(info); + break; + default: + break; + } return 0; } @@ -278,6 +328,7 @@ static struct of_device_id of_platform_serial_table[] = { { .compatible = "ns16850", .data = (void *)PORT_16850, }, { .compatible = "nvidia,tegra20-uart", .data = (void *)PORT_TEGRA, }, { .compatible = "nxp,lpc3220-uart", .data = (void *)PORT_LPC3220, }, + { .compatible = "ralink,rt2880-uart", .data = (void *)PORT_RT2880, }, { .compatible = "altr,16550-FIFO32", .data = (void *)PORT_ALTR_16550_F32, }, { .compatible = "altr,16550-FIFO64", |