aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-omap2/serial.c118
-rw-r--r--drivers/tty/serial/omap-serial.c24
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
92static LIST_HEAD(uart_list); 74static LIST_HEAD(uart_list);
93static u8 num_uarts; 75static u8 num_uarts;
94 76
95static 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
102static 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
109static 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
116static 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
173static 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
196static 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
240static inline void omap_uart_save_context(struct omap_uart_state *uart) {}
241static 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
244static inline void omap_uart_enable_clocks(struct omap_uart_state *uart) 129static 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
1411static 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
1412static int serial_omap_runtime_suspend(struct device *dev) 1431static 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
1417static int serial_omap_runtime_resume(struct device *dev) 1436static 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