diff options
Diffstat (limited to 'arch/arm/mach-omap2/serial.c')
-rw-r--r-- | arch/arm/mach-omap2/serial.c | 78 |
1 files changed, 47 insertions, 31 deletions
diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c index becf0e38ef7e..32e91a9c8b6b 100644 --- a/arch/arm/mach-omap2/serial.c +++ b/arch/arm/mach-omap2/serial.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
28 | #include <linux/serial_8250.h> | 28 | #include <linux/serial_8250.h> |
29 | #include <linux/pm_runtime.h> | 29 | #include <linux/pm_runtime.h> |
30 | #include <linux/console.h> | ||
30 | 31 | ||
31 | #ifdef CONFIG_SERIAL_OMAP | 32 | #ifdef CONFIG_SERIAL_OMAP |
32 | #include <plat/omap-serial.h> | 33 | #include <plat/omap-serial.h> |
@@ -39,11 +40,12 @@ | |||
39 | #include <plat/omap_hwmod.h> | 40 | #include <plat/omap_hwmod.h> |
40 | #include <plat/omap_device.h> | 41 | #include <plat/omap_device.h> |
41 | 42 | ||
42 | #include "prm.h" | 43 | #include "prm2xxx_3xxx.h" |
43 | #include "pm.h" | 44 | #include "pm.h" |
44 | #include "cm.h" | 45 | #include "cm2xxx_3xxx.h" |
45 | #include "prm-regbits-34xx.h" | 46 | #include "prm-regbits-34xx.h" |
46 | #include "control.h" | 47 | #include "control.h" |
48 | #include "mux.h" | ||
47 | 49 | ||
48 | #define UART_OMAP_NO_EMPTY_FIFO_READ_IP_REV 0x52 | 50 | #define UART_OMAP_NO_EMPTY_FIFO_READ_IP_REV 0x52 |
49 | #define UART_OMAP_WER 0x17 /* Wake-up enable register */ | 51 | #define UART_OMAP_WER 0x17 /* Wake-up enable register */ |
@@ -105,21 +107,16 @@ struct omap_uart_state { | |||
105 | static LIST_HEAD(uart_list); | 107 | static LIST_HEAD(uart_list); |
106 | static u8 num_uarts; | 108 | static u8 num_uarts; |
107 | 109 | ||
108 | /* | ||
109 | * Since these idle/enable hooks are used in the idle path itself | ||
110 | * which has interrupts disabled, use the non-locking versions of | ||
111 | * the hwmod enable/disable functions. | ||
112 | */ | ||
113 | static int uart_idle_hwmod(struct omap_device *od) | 110 | static int uart_idle_hwmod(struct omap_device *od) |
114 | { | 111 | { |
115 | _omap_hwmod_idle(od->hwmods[0]); | 112 | omap_hwmod_idle(od->hwmods[0]); |
116 | 113 | ||
117 | return 0; | 114 | return 0; |
118 | } | 115 | } |
119 | 116 | ||
120 | static int uart_enable_hwmod(struct omap_device *od) | 117 | static int uart_enable_hwmod(struct omap_device *od) |
121 | { | 118 | { |
122 | _omap_hwmod_enable(od->hwmods[0]); | 119 | omap_hwmod_enable(od->hwmods[0]); |
123 | 120 | ||
124 | return 0; | 121 | return 0; |
125 | } | 122 | } |
@@ -168,9 +165,9 @@ static inline void serial_write_reg(struct omap_uart_state *uart, int offset, | |||
168 | 165 | ||
169 | static inline void __init omap_uart_reset(struct omap_uart_state *uart) | 166 | static inline void __init omap_uart_reset(struct omap_uart_state *uart) |
170 | { | 167 | { |
171 | serial_write_reg(uart, UART_OMAP_MDR1, 0x07); | 168 | serial_write_reg(uart, UART_OMAP_MDR1, UART_OMAP_MDR1_DISABLE); |
172 | serial_write_reg(uart, UART_OMAP_SCR, 0x08); | 169 | serial_write_reg(uart, UART_OMAP_SCR, 0x08); |
173 | serial_write_reg(uart, UART_OMAP_MDR1, 0x00); | 170 | serial_write_reg(uart, UART_OMAP_MDR1, UART_OMAP_MDR1_16X_MODE); |
174 | } | 171 | } |
175 | 172 | ||
176 | #if defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP3) | 173 | #if defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP3) |
@@ -218,7 +215,7 @@ static void omap_uart_save_context(struct omap_uart_state *uart) | |||
218 | return; | 215 | return; |
219 | 216 | ||
220 | lcr = serial_read_reg(uart, UART_LCR); | 217 | lcr = serial_read_reg(uart, UART_LCR); |
221 | serial_write_reg(uart, UART_LCR, 0xBF); | 218 | serial_write_reg(uart, UART_LCR, UART_LCR_CONF_MODE_B); |
222 | uart->dll = serial_read_reg(uart, UART_DLL); | 219 | uart->dll = serial_read_reg(uart, UART_DLL); |
223 | uart->dlh = serial_read_reg(uart, UART_DLM); | 220 | uart->dlh = serial_read_reg(uart, UART_DLM); |
224 | serial_write_reg(uart, UART_LCR, lcr); | 221 | serial_write_reg(uart, UART_LCR, lcr); |
@@ -226,7 +223,7 @@ static void omap_uart_save_context(struct omap_uart_state *uart) | |||
226 | uart->sysc = serial_read_reg(uart, UART_OMAP_SYSC); | 223 | uart->sysc = serial_read_reg(uart, UART_OMAP_SYSC); |
227 | uart->scr = serial_read_reg(uart, UART_OMAP_SCR); | 224 | uart->scr = serial_read_reg(uart, UART_OMAP_SCR); |
228 | uart->wer = serial_read_reg(uart, UART_OMAP_WER); | 225 | uart->wer = serial_read_reg(uart, UART_OMAP_WER); |
229 | serial_write_reg(uart, UART_LCR, 0x80); | 226 | serial_write_reg(uart, UART_LCR, UART_LCR_CONF_MODE_A); |
230 | uart->mcr = serial_read_reg(uart, UART_MCR); | 227 | uart->mcr = serial_read_reg(uart, UART_MCR); |
231 | serial_write_reg(uart, UART_LCR, lcr); | 228 | serial_write_reg(uart, UART_LCR, lcr); |
232 | 229 | ||
@@ -246,32 +243,35 @@ static void omap_uart_restore_context(struct omap_uart_state *uart) | |||
246 | uart->context_valid = 0; | 243 | uart->context_valid = 0; |
247 | 244 | ||
248 | if (uart->errata & UART_ERRATA_i202_MDR1_ACCESS) | 245 | if (uart->errata & UART_ERRATA_i202_MDR1_ACCESS) |
249 | omap_uart_mdr1_errataset(uart, 0x07, 0xA0); | 246 | omap_uart_mdr1_errataset(uart, UART_OMAP_MDR1_DISABLE, 0xA0); |
250 | else | 247 | else |
251 | serial_write_reg(uart, UART_OMAP_MDR1, 0x7); | 248 | serial_write_reg(uart, UART_OMAP_MDR1, UART_OMAP_MDR1_DISABLE); |
252 | serial_write_reg(uart, UART_LCR, 0xBF); /* Config B mode */ | 249 | |
250 | serial_write_reg(uart, UART_LCR, UART_LCR_CONF_MODE_B); | ||
253 | efr = serial_read_reg(uart, UART_EFR); | 251 | efr = serial_read_reg(uart, UART_EFR); |
254 | serial_write_reg(uart, UART_EFR, UART_EFR_ECB); | 252 | serial_write_reg(uart, UART_EFR, UART_EFR_ECB); |
255 | serial_write_reg(uart, UART_LCR, 0x0); /* Operational mode */ | 253 | serial_write_reg(uart, UART_LCR, 0x0); /* Operational mode */ |
256 | serial_write_reg(uart, UART_IER, 0x0); | 254 | serial_write_reg(uart, UART_IER, 0x0); |
257 | serial_write_reg(uart, UART_LCR, 0xBF); /* Config B mode */ | 255 | serial_write_reg(uart, UART_LCR, UART_LCR_CONF_MODE_B); |
258 | serial_write_reg(uart, UART_DLL, uart->dll); | 256 | serial_write_reg(uart, UART_DLL, uart->dll); |
259 | serial_write_reg(uart, UART_DLM, uart->dlh); | 257 | serial_write_reg(uart, UART_DLM, uart->dlh); |
260 | serial_write_reg(uart, UART_LCR, 0x0); /* Operational mode */ | 258 | serial_write_reg(uart, UART_LCR, 0x0); /* Operational mode */ |
261 | serial_write_reg(uart, UART_IER, uart->ier); | 259 | serial_write_reg(uart, UART_IER, uart->ier); |
262 | serial_write_reg(uart, UART_LCR, 0x80); | 260 | serial_write_reg(uart, UART_LCR, UART_LCR_CONF_MODE_A); |
263 | serial_write_reg(uart, UART_MCR, uart->mcr); | 261 | serial_write_reg(uart, UART_MCR, uart->mcr); |
264 | serial_write_reg(uart, UART_LCR, 0xBF); /* Config B mode */ | 262 | serial_write_reg(uart, UART_LCR, UART_LCR_CONF_MODE_B); |
265 | serial_write_reg(uart, UART_EFR, efr); | 263 | serial_write_reg(uart, UART_EFR, efr); |
266 | serial_write_reg(uart, UART_LCR, UART_LCR_WLEN8); | 264 | serial_write_reg(uart, UART_LCR, UART_LCR_WLEN8); |
267 | serial_write_reg(uart, UART_OMAP_SCR, uart->scr); | 265 | serial_write_reg(uart, UART_OMAP_SCR, uart->scr); |
268 | serial_write_reg(uart, UART_OMAP_WER, uart->wer); | 266 | serial_write_reg(uart, UART_OMAP_WER, uart->wer); |
269 | serial_write_reg(uart, UART_OMAP_SYSC, uart->sysc); | 267 | serial_write_reg(uart, UART_OMAP_SYSC, uart->sysc); |
268 | |||
270 | if (uart->errata & UART_ERRATA_i202_MDR1_ACCESS) | 269 | if (uart->errata & UART_ERRATA_i202_MDR1_ACCESS) |
271 | omap_uart_mdr1_errataset(uart, 0x00, 0xA1); | 270 | omap_uart_mdr1_errataset(uart, UART_OMAP_MDR1_16X_MODE, 0xA1); |
272 | else | 271 | else |
273 | /* UART 16x mode */ | 272 | /* UART 16x mode */ |
274 | serial_write_reg(uart, UART_OMAP_MDR1, 0x00); | 273 | serial_write_reg(uart, UART_OMAP_MDR1, |
274 | UART_OMAP_MDR1_16X_MODE); | ||
275 | } | 275 | } |
276 | #else | 276 | #else |
277 | static inline void omap_uart_save_context(struct omap_uart_state *uart) {} | 277 | static inline void omap_uart_save_context(struct omap_uart_state *uart) {} |
@@ -406,7 +406,7 @@ void omap_uart_resume_idle(int num) | |||
406 | struct omap_uart_state *uart; | 406 | struct omap_uart_state *uart; |
407 | 407 | ||
408 | list_for_each_entry(uart, &uart_list, node) { | 408 | list_for_each_entry(uart, &uart_list, node) { |
409 | if (num == uart->num) { | 409 | if (num == uart->num && uart->can_sleep) { |
410 | omap_uart_enable_clocks(uart); | 410 | omap_uart_enable_clocks(uart); |
411 | 411 | ||
412 | /* Check for IO pad wakeup */ | 412 | /* Check for IO pad wakeup */ |
@@ -491,6 +491,7 @@ static void omap_uart_idle_init(struct omap_uart_state *uart) | |||
491 | u32 wk_mask = 0; | 491 | u32 wk_mask = 0; |
492 | u32 padconf = 0; | 492 | u32 padconf = 0; |
493 | 493 | ||
494 | /* XXX These PRM accesses do not belong here */ | ||
494 | uart->wk_en = OMAP34XX_PRM_REGADDR(mod, PM_WKEN1); | 495 | uart->wk_en = OMAP34XX_PRM_REGADDR(mod, PM_WKEN1); |
495 | uart->wk_st = OMAP34XX_PRM_REGADDR(mod, PM_WKST1); | 496 | uart->wk_st = OMAP34XX_PRM_REGADDR(mod, PM_WKST1); |
496 | switch (uart->num) { | 497 | switch (uart->num) { |
@@ -694,16 +695,16 @@ void __init omap_serial_early_init(void) | |||
694 | 695 | ||
695 | /** | 696 | /** |
696 | * omap_serial_init_port() - initialize single serial port | 697 | * omap_serial_init_port() - initialize single serial port |
697 | * @port: serial port number (0-3) | 698 | * @bdata: port specific board data pointer |
698 | * | 699 | * |
699 | * This function initialies serial driver for given @port only. | 700 | * This function initialies serial driver for given port only. |
700 | * Platforms can call this function instead of omap_serial_init() | 701 | * Platforms can call this function instead of omap_serial_init() |
701 | * if they don't plan to use all available UARTs as serial ports. | 702 | * if they don't plan to use all available UARTs as serial ports. |
702 | * | 703 | * |
703 | * Don't mix calls to omap_serial_init_port() and omap_serial_init(), | 704 | * Don't mix calls to omap_serial_init_port() and omap_serial_init(), |
704 | * use only one of the two. | 705 | * use only one of the two. |
705 | */ | 706 | */ |
706 | void __init omap_serial_init_port(int port) | 707 | void __init omap_serial_init_port(struct omap_board_data *bdata) |
707 | { | 708 | { |
708 | struct omap_uart_state *uart; | 709 | struct omap_uart_state *uart; |
709 | struct omap_hwmod *oh; | 710 | struct omap_hwmod *oh; |
@@ -721,13 +722,15 @@ void __init omap_serial_init_port(int port) | |||
721 | struct omap_uart_port_info omap_up; | 722 | struct omap_uart_port_info omap_up; |
722 | #endif | 723 | #endif |
723 | 724 | ||
724 | if (WARN_ON(port < 0)) | 725 | if (WARN_ON(!bdata)) |
726 | return; | ||
727 | if (WARN_ON(bdata->id < 0)) | ||
725 | return; | 728 | return; |
726 | if (WARN_ON(port >= num_uarts)) | 729 | if (WARN_ON(bdata->id >= num_uarts)) |
727 | return; | 730 | return; |
728 | 731 | ||
729 | list_for_each_entry(uart, &uart_list, node) | 732 | list_for_each_entry(uart, &uart_list, node) |
730 | if (port == uart->num) | 733 | if (bdata->id == uart->num) |
731 | break; | 734 | break; |
732 | 735 | ||
733 | oh = uart->oh; | 736 | oh = uart->oh; |
@@ -799,6 +802,8 @@ void __init omap_serial_init_port(int port) | |||
799 | WARN(IS_ERR(od), "Could not build omap_device for %s: %s.\n", | 802 | WARN(IS_ERR(od), "Could not build omap_device for %s: %s.\n", |
800 | name, oh->name); | 803 | name, oh->name); |
801 | 804 | ||
805 | oh->mux = omap_hwmod_mux_init(bdata->pads, bdata->pads_cnt); | ||
806 | |||
802 | uart->irq = oh->mpu_irqs[0].irq; | 807 | uart->irq = oh->mpu_irqs[0].irq; |
803 | uart->regshift = 2; | 808 | uart->regshift = 2; |
804 | uart->mapbase = oh->slaves[0]->addr->pa_start; | 809 | uart->mapbase = oh->slaves[0]->addr->pa_start; |
@@ -807,6 +812,8 @@ void __init omap_serial_init_port(int port) | |||
807 | 812 | ||
808 | oh->dev_attr = uart; | 813 | oh->dev_attr = uart; |
809 | 814 | ||
815 | console_lock(); /* in case the earlycon is on the UART */ | ||
816 | |||
810 | /* | 817 | /* |
811 | * Because of early UART probing, UART did not get idled | 818 | * Because of early UART probing, UART did not get idled |
812 | * on init. Now that omap_device is ready, ensure full idle | 819 | * on init. Now that omap_device is ready, ensure full idle |
@@ -831,6 +838,8 @@ void __init omap_serial_init_port(int port) | |||
831 | omap_uart_block_sleep(uart); | 838 | omap_uart_block_sleep(uart); |
832 | uart->timeout = DEFAULT_TIMEOUT; | 839 | uart->timeout = DEFAULT_TIMEOUT; |
833 | 840 | ||
841 | console_unlock(); | ||
842 | |||
834 | if ((cpu_is_omap34xx() && uart->padconf) || | 843 | if ((cpu_is_omap34xx() && uart->padconf) || |
835 | (uart->wk_en && uart->wk_mask)) { | 844 | (uart->wk_en && uart->wk_mask)) { |
836 | device_init_wakeup(&od->pdev.dev, true); | 845 | device_init_wakeup(&od->pdev.dev, true); |
@@ -843,7 +852,7 @@ void __init omap_serial_init_port(int port) | |||
843 | } | 852 | } |
844 | 853 | ||
845 | /** | 854 | /** |
846 | * omap_serial_init() - intialize all supported serial ports | 855 | * omap_serial_init() - initialize all supported serial ports |
847 | * | 856 | * |
848 | * Initializes all available UARTs as serial ports. Platforms | 857 | * Initializes all available UARTs as serial ports. Platforms |
849 | * can call this function when they want to have default behaviour | 858 | * can call this function when they want to have default behaviour |
@@ -852,7 +861,14 @@ void __init omap_serial_init_port(int port) | |||
852 | void __init omap_serial_init(void) | 861 | void __init omap_serial_init(void) |
853 | { | 862 | { |
854 | struct omap_uart_state *uart; | 863 | struct omap_uart_state *uart; |
864 | struct omap_board_data bdata; | ||
855 | 865 | ||
856 | list_for_each_entry(uart, &uart_list, node) | 866 | list_for_each_entry(uart, &uart_list, node) { |
857 | omap_serial_init_port(uart->num); | 867 | bdata.id = uart->num; |
868 | bdata.flags = 0; | ||
869 | bdata.pads = NULL; | ||
870 | bdata.pads_cnt = 0; | ||
871 | omap_serial_init_port(&bdata); | ||
872 | |||
873 | } | ||
858 | } | 874 | } |