diff options
-rw-r--r-- | arch/arm/mach-omap2/serial.c | 118 | ||||
-rw-r--r-- | drivers/tty/serial/omap-serial.c | 24 |
2 files changed, 24 insertions, 118 deletions
diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c index 2456cfdad78c..64b0d11ddc49 100644 --- a/arch/arm/mach-omap2/serial.c +++ b/arch/arm/mach-omap2/serial.c | |||
@@ -41,8 +41,6 @@ | |||
41 | #include "control.h" | 41 | #include "control.h" |
42 | #include "mux.h" | 42 | #include "mux.h" |
43 | 43 | ||
44 | #define UART_OMAP_WER 0x17 /* Wake-up enable register */ | ||
45 | |||
46 | #define UART_ERRATA_i202_MDR1_ACCESS (0x1 << 1) | 44 | #define UART_ERRATA_i202_MDR1_ACCESS (0x1 << 1) |
47 | 45 | ||
48 | /* | 46 | /* |
@@ -66,60 +64,16 @@ struct omap_uart_state { | |||
66 | 64 | ||
67 | int clocked; | 65 | int clocked; |
68 | 66 | ||
69 | int regshift; | ||
70 | void __iomem *membase; | ||
71 | resource_size_t mapbase; | ||
72 | |||
73 | struct list_head node; | 67 | struct list_head node; |
74 | struct omap_hwmod *oh; | 68 | struct omap_hwmod *oh; |
75 | struct platform_device *pdev; | 69 | struct platform_device *pdev; |
76 | 70 | ||
77 | u32 errata; | 71 | u32 errata; |
78 | #if defined(CONFIG_ARCH_OMAP3) && defined(CONFIG_PM) | ||
79 | int context_valid; | ||
80 | |||
81 | /* Registers to be saved/restored for OFF-mode */ | ||
82 | u16 dll; | ||
83 | u16 dlh; | ||
84 | u16 ier; | ||
85 | u16 sysc; | ||
86 | u16 scr; | ||
87 | u16 wer; | ||
88 | u16 mcr; | ||
89 | #endif | ||
90 | }; | 72 | }; |
91 | 73 | ||
92 | static LIST_HEAD(uart_list); | 74 | static LIST_HEAD(uart_list); |
93 | static u8 num_uarts; | 75 | static u8 num_uarts; |
94 | 76 | ||
95 | static inline unsigned int __serial_read_reg(struct uart_port *up, | ||
96 | int offset) | ||
97 | { | ||
98 | offset <<= up->regshift; | ||
99 | return (unsigned int)__raw_readb(up->membase + offset); | ||
100 | } | ||
101 | |||
102 | static inline unsigned int serial_read_reg(struct omap_uart_state *uart, | ||
103 | int offset) | ||
104 | { | ||
105 | offset <<= uart->regshift; | ||
106 | return (unsigned int)__raw_readb(uart->membase + offset); | ||
107 | } | ||
108 | |||
109 | static inline void __serial_write_reg(struct uart_port *up, int offset, | ||
110 | int value) | ||
111 | { | ||
112 | offset <<= up->regshift; | ||
113 | __raw_writeb(value, up->membase + offset); | ||
114 | } | ||
115 | |||
116 | static inline void serial_write_reg(struct omap_uart_state *uart, int offset, | ||
117 | int value) | ||
118 | { | ||
119 | offset <<= uart->regshift; | ||
120 | __raw_writeb(value, uart->membase + offset); | ||
121 | } | ||
122 | |||
123 | /* | 77 | /* |
124 | * Internal UARTs need to be initialized for the 8250 autoconfig to work | 78 | * Internal UARTs need to be initialized for the 8250 autoconfig to work |
125 | * properly. Note that the TX watermark initialization may not be needed | 79 | * properly. Note that the TX watermark initialization may not be needed |
@@ -170,75 +124,6 @@ static void omap_uart_mdr1_errataset(struct omap_uart_state *uart, u8 mdr1_val, | |||
170 | } | 124 | } |
171 | } | 125 | } |
172 | 126 | ||
173 | static void omap_uart_save_context(struct omap_uart_state *uart) | ||
174 | { | ||
175 | u16 lcr = 0; | ||
176 | |||
177 | if (!enable_off_mode) | ||
178 | return; | ||
179 | |||
180 | lcr = serial_read_reg(uart, UART_LCR); | ||
181 | serial_write_reg(uart, UART_LCR, UART_LCR_CONF_MODE_B); | ||
182 | uart->dll = serial_read_reg(uart, UART_DLL); | ||
183 | uart->dlh = serial_read_reg(uart, UART_DLM); | ||
184 | serial_write_reg(uart, UART_LCR, lcr); | ||
185 | uart->ier = serial_read_reg(uart, UART_IER); | ||
186 | uart->sysc = serial_read_reg(uart, UART_OMAP_SYSC); | ||
187 | uart->scr = serial_read_reg(uart, UART_OMAP_SCR); | ||
188 | uart->wer = serial_read_reg(uart, UART_OMAP_WER); | ||
189 | serial_write_reg(uart, UART_LCR, UART_LCR_CONF_MODE_A); | ||
190 | uart->mcr = serial_read_reg(uart, UART_MCR); | ||
191 | serial_write_reg(uart, UART_LCR, lcr); | ||
192 | |||
193 | uart->context_valid = 1; | ||
194 | } | ||
195 | |||
196 | static void omap_uart_restore_context(struct omap_uart_state *uart) | ||
197 | { | ||
198 | u16 efr = 0; | ||
199 | |||
200 | if (!enable_off_mode) | ||
201 | return; | ||
202 | |||
203 | if (!uart->context_valid) | ||
204 | return; | ||
205 | |||
206 | uart->context_valid = 0; | ||
207 | |||
208 | if (uart->errata & UART_ERRATA_i202_MDR1_ACCESS) | ||
209 | omap_uart_mdr1_errataset(uart, UART_OMAP_MDR1_DISABLE, 0xA0); | ||
210 | else | ||
211 | serial_write_reg(uart, UART_OMAP_MDR1, UART_OMAP_MDR1_DISABLE); | ||
212 | |||
213 | serial_write_reg(uart, UART_LCR, UART_LCR_CONF_MODE_B); | ||
214 | efr = serial_read_reg(uart, UART_EFR); | ||
215 | serial_write_reg(uart, UART_EFR, UART_EFR_ECB); | ||
216 | serial_write_reg(uart, UART_LCR, 0x0); /* Operational mode */ | ||
217 | serial_write_reg(uart, UART_IER, 0x0); | ||
218 | serial_write_reg(uart, UART_LCR, UART_LCR_CONF_MODE_B); | ||
219 | serial_write_reg(uart, UART_DLL, uart->dll); | ||
220 | serial_write_reg(uart, UART_DLM, uart->dlh); | ||
221 | serial_write_reg(uart, UART_LCR, 0x0); /* Operational mode */ | ||
222 | serial_write_reg(uart, UART_IER, uart->ier); | ||
223 | serial_write_reg(uart, UART_LCR, UART_LCR_CONF_MODE_A); | ||
224 | serial_write_reg(uart, UART_MCR, uart->mcr); | ||
225 | serial_write_reg(uart, UART_LCR, UART_LCR_CONF_MODE_B); | ||
226 | serial_write_reg(uart, UART_EFR, efr); | ||
227 | serial_write_reg(uart, UART_LCR, UART_LCR_WLEN8); | ||
228 | serial_write_reg(uart, UART_OMAP_SCR, uart->scr); | ||
229 | serial_write_reg(uart, UART_OMAP_WER, uart->wer); | ||
230 | serial_write_reg(uart, UART_OMAP_SYSC, uart->sysc); | ||
231 | |||
232 | if (uart->errata & UART_ERRATA_i202_MDR1_ACCESS) | ||
233 | omap_uart_mdr1_errataset(uart, UART_OMAP_MDR1_16X_MODE, 0xA1); | ||
234 | else | ||
235 | /* UART 16x mode */ | ||
236 | serial_write_reg(uart, UART_OMAP_MDR1, | ||
237 | UART_OMAP_MDR1_16X_MODE); | ||
238 | } | ||
239 | #else | ||
240 | static inline void omap_uart_save_context(struct omap_uart_state *uart) {} | ||
241 | static inline void omap_uart_restore_context(struct omap_uart_state *uart) {} | ||
242 | #endif /* CONFIG_PM && CONFIG_ARCH_OMAP3 */ | 127 | #endif /* CONFIG_PM && CONFIG_ARCH_OMAP3 */ |
243 | 128 | ||
244 | static inline void omap_uart_enable_clocks(struct omap_uart_state *uart) | 129 | static inline void omap_uart_enable_clocks(struct omap_uart_state *uart) |
@@ -621,9 +506,6 @@ void __init omap_serial_init_port(struct omap_board_data *bdata) | |||
621 | omap_device_disable_idle_on_suspend(pdev); | 506 | omap_device_disable_idle_on_suspend(pdev); |
622 | oh->mux = omap_hwmod_mux_init(bdata->pads, bdata->pads_cnt); | 507 | oh->mux = omap_hwmod_mux_init(bdata->pads, bdata->pads_cnt); |
623 | 508 | ||
624 | uart->regshift = 2; | ||
625 | uart->mapbase = oh->slaves[0]->addr->pa_start; | ||
626 | uart->membase = omap_hwmod_get_mpu_rt_va(oh); | ||
627 | uart->pdev = pdev; | 509 | uart->pdev = pdev; |
628 | 510 | ||
629 | oh->dev_attr = uart; | 511 | oh->dev_attr = uart; |
diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c index f16ef4b9363d..a834e913a6e4 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c | |||
@@ -1408,6 +1408,25 @@ static int serial_omap_remove(struct platform_device *dev) | |||
1408 | return 0; | 1408 | return 0; |
1409 | } | 1409 | } |
1410 | 1410 | ||
1411 | static void serial_omap_restore_context(struct uart_omap_port *up) | ||
1412 | { | ||
1413 | serial_out(up, UART_OMAP_MDR1, UART_OMAP_MDR1_DISABLE); | ||
1414 | serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); /* Config B mode */ | ||
1415 | serial_out(up, UART_EFR, UART_EFR_ECB); | ||
1416 | serial_out(up, UART_LCR, 0x0); /* Operational mode */ | ||
1417 | serial_out(up, UART_IER, 0x0); | ||
1418 | serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); /* Config B mode */ | ||
1419 | serial_out(up, UART_LCR, 0x0); /* Operational mode */ | ||
1420 | serial_out(up, UART_IER, up->ier); | ||
1421 | serial_out(up, UART_FCR, up->fcr); | ||
1422 | serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A); | ||
1423 | serial_out(up, UART_MCR, up->mcr); | ||
1424 | serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); /* Config B mode */ | ||
1425 | serial_out(up, UART_EFR, up->efr); | ||
1426 | serial_out(up, UART_LCR, up->lcr); | ||
1427 | serial_out(up, UART_OMAP_MDR1, UART_OMAP_MDR1_16X_MODE); | ||
1428 | } | ||
1429 | |||
1411 | #ifdef CONFIG_PM_RUNTIME | 1430 | #ifdef CONFIG_PM_RUNTIME |
1412 | static int serial_omap_runtime_suspend(struct device *dev) | 1431 | static int serial_omap_runtime_suspend(struct device *dev) |
1413 | { | 1432 | { |
@@ -1416,6 +1435,11 @@ static int serial_omap_runtime_suspend(struct device *dev) | |||
1416 | 1435 | ||
1417 | static int serial_omap_runtime_resume(struct device *dev) | 1436 | static int serial_omap_runtime_resume(struct device *dev) |
1418 | { | 1437 | { |
1438 | struct uart_omap_port *up = dev_get_drvdata(dev); | ||
1439 | |||
1440 | if (up) | ||
1441 | serial_omap_restore_context(up); | ||
1442 | |||
1419 | return 0; | 1443 | return 0; |
1420 | } | 1444 | } |
1421 | #endif | 1445 | #endif |