Blame view

arch/arm/mach-omap2/serial.c 11.4 KB
1dbae815a   Tony Lindgren   [ARM] 3145/1: OMA...
1
  /*
f30c22695   Uwe Zeisberger   fix file specific...
2
   * arch/arm/mach-omap2/serial.c
1dbae815a   Tony Lindgren   [ARM] 3145/1: OMA...
3
4
5
   *
   * OMAP2 serial support.
   *
6e81176dc   Jouni Hogander   ARM: OMAP2 Provid...
6
   * Copyright (C) 2005-2008 Nokia Corporation
1dbae815a   Tony Lindgren   [ARM] 3145/1: OMA...
7
8
   * Author: Paul Mundt <paul.mundt@nokia.com>
   *
4af4016c5   Kevin Hilman   OMAP3: PM: UART: ...
9
10
   * Major rework for PM support by Kevin Hilman
   *
1dbae815a   Tony Lindgren   [ARM] 3145/1: OMA...
11
12
   * Based off of arch/arm/mach-omap/omap1/serial.c
   *
44169075e   Santosh Shilimkar   ARM: OMAP4: Add m...
13
14
15
   * Copyright (C) 2009 Texas Instruments
   * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com
   *
1dbae815a   Tony Lindgren   [ARM] 3145/1: OMA...
16
17
18
19
20
21
   * This file is subject to the terms and conditions of the GNU General Public
   * License. See the file "COPYING" in the main directory of this archive
   * for more details.
   */
  #include <linux/kernel.h>
  #include <linux/init.h>
f8ce25476   Russell King   [ARM] Move asm/ha...
22
  #include <linux/clk.h>
fced80c73   Russell King   [ARM] Convert asm...
23
  #include <linux/io.h>
e03d37d85   Santosh Shilimkar   omap3/4: uart: fi...
24
  #include <linux/delay.h>
6f251e9db   Kevin Hilman   OMAP: UART: omap_...
25
26
  #include <linux/platform_device.h>
  #include <linux/slab.h>
3244fcd22   Kevin Hilman   OMAP: UART: don't...
27
  #include <linux/pm_runtime.h>
0d8e2d0da   Paul Walmsley   OMAP2+: PM/serial...
28
  #include <linux/console.h>
6f251e9db   Kevin Hilman   OMAP: UART: omap_...
29

6f251e9db   Kevin Hilman   OMAP: UART: omap_...
30
  #include <plat/omap-serial.h>
4e65331c6   Tony Lindgren   ARM: 7159/1: OMAP...
31
  #include "common.h"
ce491cf85   Tony Lindgren   omap: headers: Mo...
32
  #include <plat/board.h>
6f251e9db   Kevin Hilman   OMAP: UART: omap_...
33
34
35
  #include <plat/dma.h>
  #include <plat/omap_hwmod.h>
  #include <plat/omap_device.h>
ec3bebc6e   Govindraj.R   ARM: OMAP2+: UART...
36
  #include <plat/omap-pm.h>
4af4016c5   Kevin Hilman   OMAP3: PM: UART: ...
37

59fb659b0   Paul Walmsley   OMAP2/3: PRCM: sp...
38
  #include "prm2xxx_3xxx.h"
4af4016c5   Kevin Hilman   OMAP3: PM: UART: ...
39
  #include "pm.h"
59fb659b0   Paul Walmsley   OMAP2/3: PRCM: sp...
40
  #include "cm2xxx_3xxx.h"
4af4016c5   Kevin Hilman   OMAP3: PM: UART: ...
41
  #include "prm-regbits-34xx.h"
4814ced51   Paul Walmsley   OMAP: control: mo...
42
  #include "control.h"
40e443993   Tony Lindgren   omap2+: Add struc...
43
  #include "mux.h"
4af4016c5   Kevin Hilman   OMAP3: PM: UART: ...
44

301fe8eee   Tony Lindgren   omap: Disable ser...
45
  /*
c86845db7   Deepak K   ARM: OMAP2+: UART...
46
47
48
49
   * NOTE: By default the serial auto_suspend timeout is disabled as it causes
   * lost characters over the serial ports. This means that the UART clocks will
   * stay on until power/autosuspend_delay is set for the uart from sysfs.
   * This also causes that any deeper omap sleep states are blocked.
301fe8eee   Tony Lindgren   omap: Disable ser...
50
   */
c86845db7   Deepak K   ARM: OMAP2+: UART...
51
  #define DEFAULT_AUTOSUSPEND_DELAY	-1
4af4016c5   Kevin Hilman   OMAP3: PM: UART: ...
52

6f251e9db   Kevin Hilman   OMAP: UART: omap_...
53
  #define MAX_UART_HWMOD_NAME_LEN		16
4af4016c5   Kevin Hilman   OMAP3: PM: UART: ...
54
55
56
  struct omap_uart_state {
  	int num;
  	int can_sleep;
4af4016c5   Kevin Hilman   OMAP3: PM: UART: ...
57

4af4016c5   Kevin Hilman   OMAP3: PM: UART: ...
58
  	struct list_head node;
6f251e9db   Kevin Hilman   OMAP: UART: omap_...
59
60
  	struct omap_hwmod *oh;
  	struct platform_device *pdev;
4af4016c5   Kevin Hilman   OMAP3: PM: UART: ...
61
  };
4af4016c5   Kevin Hilman   OMAP3: PM: UART: ...
62
  static LIST_HEAD(uart_list);
6f251e9db   Kevin Hilman   OMAP: UART: omap_...
63
  static u8 num_uarts;
8612bd22f   Govindraj.R   ARM: OMAP2+: UART...
64
  static u8 console_uart_id = -1;
08f86b3ea   Govindraj.R   ARM: OMAP2+: UART...
65
  static u8 no_console_suspend;
36fc2d15b   Govindraj.R   ARM: OMAP2+: UART...
66
  static u8 uart_debug;
1dbae815a   Tony Lindgren   [ARM] 3145/1: OMA...
67

a9e210e0b   Jon Hunter   ARM: OMAP2+: UART...
68
  #define DEFAULT_RXDMA_POLLRATE		1	/* RX DMA polling rate (us) */
c86845db7   Deepak K   ARM: OMAP2+: UART...
69
  #define DEFAULT_RXDMA_BUFSIZE		4096	/* RX DMA buffer size */
a9e210e0b   Jon Hunter   ARM: OMAP2+: UART...
70
  #define DEFAULT_RXDMA_TIMEOUT		(3 * HZ)/* RX DMA timeout (jiffies) */
c86845db7   Deepak K   ARM: OMAP2+: UART...
71
72
73
74
75
  
  static struct omap_uart_port_info omap_serial_default_info[] __initdata = {
  	{
  		.dma_enabled	= false,
  		.dma_rx_buf_size = DEFAULT_RXDMA_BUFSIZE,
a9e210e0b   Jon Hunter   ARM: OMAP2+: UART...
76
  		.dma_rx_poll_rate = DEFAULT_RXDMA_POLLRATE,
c86845db7   Deepak K   ARM: OMAP2+: UART...
77
78
79
80
  		.dma_rx_timeout = DEFAULT_RXDMA_TIMEOUT,
  		.autosuspend_timeout = DEFAULT_AUTOSUSPEND_DELAY,
  	},
  };
4af4016c5   Kevin Hilman   OMAP3: PM: UART: ...
81
  #ifdef CONFIG_PM
62f3ec5fb   Govindraj.R   ARM: OMAP2+: UART...
82
  static void omap_uart_enable_wakeup(struct platform_device *pdev, bool enable)
4af4016c5   Kevin Hilman   OMAP3: PM: UART: ...
83
  {
62f3ec5fb   Govindraj.R   ARM: OMAP2+: UART...
84
  	struct omap_device *od = to_omap_device(pdev);
4af4016c5   Kevin Hilman   OMAP3: PM: UART: ...
85

62f3ec5fb   Govindraj.R   ARM: OMAP2+: UART...
86
87
  	if (!od)
  		return;
4af4016c5   Kevin Hilman   OMAP3: PM: UART: ...
88

62f3ec5fb   Govindraj.R   ARM: OMAP2+: UART...
89
90
91
92
  	if (enable)
  		omap_hwmod_enable_wakeup(od->hwmods[0]);
  	else
  		omap_hwmod_disable_wakeup(od->hwmods[0]);
ba87a9bea   Jouni Hogander   OMAP: UART: Add s...
93
  }
94734749a   Govindraj.R   ARM: OMAP2+: UART...
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
  /*
   * Errata i291: [UART]:Cannot Acknowledge Idle Requests
   * in Smartidle Mode When Configured for DMA Operations.
   * WA: configure uart in force idle mode.
   */
  static void omap_uart_set_noidle(struct platform_device *pdev)
  {
  	struct omap_device *od = to_omap_device(pdev);
  
  	omap_hwmod_set_slave_idlemode(od->hwmods[0], HWMOD_IDLEMODE_NO);
  }
  
  static void omap_uart_set_forceidle(struct platform_device *pdev)
  {
  	struct omap_device *od = to_omap_device(pdev);
  
  	omap_hwmod_set_slave_idlemode(od->hwmods[0], HWMOD_IDLEMODE_FORCE);
  }
4af4016c5   Kevin Hilman   OMAP3: PM: UART: ...
112
  #else
62f3ec5fb   Govindraj.R   ARM: OMAP2+: UART...
113
114
  static void omap_uart_enable_wakeup(struct platform_device *pdev, bool enable)
  {}
94734749a   Govindraj.R   ARM: OMAP2+: UART...
115
116
  static void omap_uart_set_noidle(struct platform_device *pdev) {}
  static void omap_uart_set_forceidle(struct platform_device *pdev) {}
4af4016c5   Kevin Hilman   OMAP3: PM: UART: ...
117
  #endif /* CONFIG_PM */
7496ba309   Govindraj.R   ARM: OMAP2+: UART...
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
  #ifdef CONFIG_OMAP_MUX
  static struct omap_device_pad default_uart1_pads[] __initdata = {
  	{
  		.name	= "uart1_cts.uart1_cts",
  		.enable	= OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0,
  	},
  	{
  		.name	= "uart1_rts.uart1_rts",
  		.enable	= OMAP_PIN_OUTPUT | OMAP_MUX_MODE0,
  	},
  	{
  		.name	= "uart1_tx.uart1_tx",
  		.enable	= OMAP_PIN_OUTPUT | OMAP_MUX_MODE0,
  	},
  	{
  		.name	= "uart1_rx.uart1_rx",
  		.flags	= OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP,
  		.enable	= OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0,
  		.idle	= OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0,
  	},
  };
  
  static struct omap_device_pad default_uart2_pads[] __initdata = {
  	{
  		.name	= "uart2_cts.uart2_cts",
  		.enable	= OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0,
  	},
  	{
  		.name	= "uart2_rts.uart2_rts",
  		.enable	= OMAP_PIN_OUTPUT | OMAP_MUX_MODE0,
  	},
  	{
  		.name	= "uart2_tx.uart2_tx",
  		.enable	= OMAP_PIN_OUTPUT | OMAP_MUX_MODE0,
  	},
  	{
  		.name	= "uart2_rx.uart2_rx",
  		.flags	= OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP,
  		.enable	= OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0,
  		.idle	= OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0,
  	},
  };
  
  static struct omap_device_pad default_uart3_pads[] __initdata = {
  	{
  		.name	= "uart3_cts_rctx.uart3_cts_rctx",
  		.enable	= OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0,
  	},
  	{
  		.name	= "uart3_rts_sd.uart3_rts_sd",
  		.enable	= OMAP_PIN_OUTPUT | OMAP_MUX_MODE0,
  	},
  	{
  		.name	= "uart3_tx_irtx.uart3_tx_irtx",
  		.enable	= OMAP_PIN_OUTPUT | OMAP_MUX_MODE0,
  	},
  	{
  		.name	= "uart3_rx_irrx.uart3_rx_irrx",
  		.flags	= OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP,
  		.enable	= OMAP_PIN_INPUT | OMAP_MUX_MODE0,
  		.idle	= OMAP_PIN_INPUT | OMAP_MUX_MODE0,
  	},
  };
  
  static struct omap_device_pad default_omap36xx_uart4_pads[] __initdata = {
  	{
  		.name   = "gpmc_wait2.uart4_tx",
  		.enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0,
  	},
  	{
  		.name	= "gpmc_wait3.uart4_rx",
  		.flags	= OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP,
  		.enable	= OMAP_PIN_INPUT | OMAP_MUX_MODE2,
  		.idle	= OMAP_PIN_INPUT | OMAP_MUX_MODE2,
  	},
  };
  
  static struct omap_device_pad default_omap4_uart4_pads[] __initdata = {
  	{
  		.name	= "uart4_tx.uart4_tx",
  		.enable	= OMAP_PIN_OUTPUT | OMAP_MUX_MODE0,
  	},
  	{
  		.name	= "uart4_rx.uart4_rx",
  		.flags	= OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP,
  		.enable	= OMAP_PIN_INPUT | OMAP_MUX_MODE0,
  		.idle	= OMAP_PIN_INPUT | OMAP_MUX_MODE0,
  	},
  };
  
  static void omap_serial_fill_default_pads(struct omap_board_data *bdata)
  {
  	switch (bdata->id) {
  	case 0:
  		bdata->pads = default_uart1_pads;
  		bdata->pads_cnt = ARRAY_SIZE(default_uart1_pads);
  		break;
  	case 1:
  		bdata->pads = default_uart2_pads;
  		bdata->pads_cnt = ARRAY_SIZE(default_uart2_pads);
  		break;
  	case 2:
  		bdata->pads = default_uart3_pads;
  		bdata->pads_cnt = ARRAY_SIZE(default_uart3_pads);
  		break;
  	case 3:
  		if (cpu_is_omap44xx()) {
  			bdata->pads = default_omap4_uart4_pads;
  			bdata->pads_cnt =
  				ARRAY_SIZE(default_omap4_uart4_pads);
  		} else if (cpu_is_omap3630()) {
  			bdata->pads = default_omap36xx_uart4_pads;
  			bdata->pads_cnt =
  				ARRAY_SIZE(default_omap36xx_uart4_pads);
  		}
  		break;
  	default:
  		break;
  	}
  }
  #else
  static void omap_serial_fill_default_pads(struct omap_board_data *bdata) {}
  #endif
8612bd22f   Govindraj.R   ARM: OMAP2+: UART...
241
242
243
244
245
246
  char *cmdline_find_option(char *str)
  {
  	extern char *saved_command_line;
  
  	return strstr(saved_command_line, str);
  }
3e16f9253   Tony Lindgren   omap2+: Fix omap_...
247
  static int __init omap_serial_early_init(void)
1dbae815a   Tony Lindgren   [ARM] 3145/1: OMA...
248
  {
6f251e9db   Kevin Hilman   OMAP: UART: omap_...
249
250
251
252
  	do {
  		char oh_name[MAX_UART_HWMOD_NAME_LEN];
  		struct omap_hwmod *oh;
  		struct omap_uart_state *uart;
8612bd22f   Govindraj.R   ARM: OMAP2+: UART...
253
  		char uart_name[MAX_UART_HWMOD_NAME_LEN];
21b903402   Thomas Weber   OMAP2: serial.c: ...
254

6f251e9db   Kevin Hilman   OMAP: UART: omap_...
255
  		snprintf(oh_name, MAX_UART_HWMOD_NAME_LEN,
969996a57   Govindraj.R   ARM: OMAP2+: UART...
256
  			 "uart%d", num_uarts + 1);
6f251e9db   Kevin Hilman   OMAP: UART: omap_...
257
258
259
260
261
262
  		oh = omap_hwmod_lookup(oh_name);
  		if (!oh)
  			break;
  
  		uart = kzalloc(sizeof(struct omap_uart_state), GFP_KERNEL);
  		if (WARN_ON(!uart))
3e16f9253   Tony Lindgren   omap2+: Fix omap_...
263
  			return -ENODEV;
1dbae815a   Tony Lindgren   [ARM] 3145/1: OMA...
264

6f251e9db   Kevin Hilman   OMAP: UART: omap_...
265
  		uart->oh = oh;
969996a57   Govindraj.R   ARM: OMAP2+: UART...
266
  		uart->num = num_uarts++;
6f251e9db   Kevin Hilman   OMAP: UART: omap_...
267
  		list_add_tail(&uart->node, &uart_list);
8612bd22f   Govindraj.R   ARM: OMAP2+: UART...
268
269
270
271
272
  		snprintf(uart_name, MAX_UART_HWMOD_NAME_LEN,
  				"%s%d", OMAP_SERIAL_NAME, uart->num);
  
  		if (cmdline_find_option(uart_name)) {
  			console_uart_id = uart->num;
08f86b3ea   Govindraj.R   ARM: OMAP2+: UART...
273

36fc2d15b   Govindraj.R   ARM: OMAP2+: UART...
274
275
276
277
278
279
  			if (console_loglevel >= 10) {
  				uart_debug = true;
  				pr_info("%s used as console in debug mode"
  						" uart%d clocks will not be"
  						" gated", uart_name, uart->num);
  			}
08f86b3ea   Govindraj.R   ARM: OMAP2+: UART...
280
281
  			if (cmdline_find_option("no_console_suspend"))
  				no_console_suspend = true;
8612bd22f   Govindraj.R   ARM: OMAP2+: UART...
282
283
284
285
286
287
288
289
290
291
292
  			/*
  			 * omap-uart can be used for earlyprintk logs
  			 * So if omap-uart is used as console then prevent
  			 * uart reset and idle to get logs from omap-uart
  			 * until uart console driver is available to take
  			 * care for console messages.
  			 * Idling or resetting omap-uart while printing logs
  			 * early boot logs can stall the boot-up.
  			 */
  			oh->flags |= HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET;
  		}
6f251e9db   Kevin Hilman   OMAP: UART: omap_...
293
  	} while (1);
3e16f9253   Tony Lindgren   omap2+: Fix omap_...
294
295
  
  	return 0;
b3c6df3ab   Paul Walmsley   OMAP2/3 board-*.c...
296
  }
3e16f9253   Tony Lindgren   omap2+: Fix omap_...
297
  core_initcall(omap_serial_early_init);
b3c6df3ab   Paul Walmsley   OMAP2/3 board-*.c...
298

f62349ee9   Mika Westerberg   OMAP3: serial - a...
299
300
  /**
   * omap_serial_init_port() - initialize single serial port
40e443993   Tony Lindgren   omap2+: Add struc...
301
   * @bdata: port specific board data pointer
c86845db7   Deepak K   ARM: OMAP2+: UART...
302
   * @info: platform specific data pointer
f62349ee9   Mika Westerberg   OMAP3: serial - a...
303
   *
40e443993   Tony Lindgren   omap2+: Add struc...
304
   * This function initialies serial driver for given port only.
f62349ee9   Mika Westerberg   OMAP3: serial - a...
305
306
307
308
309
310
   * Platforms can call this function instead of omap_serial_init()
   * if they don't plan to use all available UARTs as serial ports.
   *
   * Don't mix calls to omap_serial_init_port() and omap_serial_init(),
   * use only one of the two.
   */
c86845db7   Deepak K   ARM: OMAP2+: UART...
311
312
  void __init omap_serial_init_port(struct omap_board_data *bdata,
  			struct omap_uart_port_info *info)
b3c6df3ab   Paul Walmsley   OMAP2/3 board-*.c...
313
  {
f62349ee9   Mika Westerberg   OMAP3: serial - a...
314
  	struct omap_uart_state *uart;
6f251e9db   Kevin Hilman   OMAP: UART: omap_...
315
  	struct omap_hwmod *oh;
3528c58eb   Kevin Hilman   OMAP: omap_device...
316
  	struct platform_device *pdev;
6f251e9db   Kevin Hilman   OMAP: UART: omap_...
317
318
319
  	void *pdata = NULL;
  	u32 pdata_size = 0;
  	char *name;
6f251e9db   Kevin Hilman   OMAP: UART: omap_...
320
  	struct omap_uart_port_info omap_up;
970a724d9   Tony Lindgren   Merge branch 'oma...
321

40e443993   Tony Lindgren   omap2+: Add struc...
322
  	if (WARN_ON(!bdata))
6f251e9db   Kevin Hilman   OMAP: UART: omap_...
323
  		return;
40e443993   Tony Lindgren   omap2+: Add struc...
324
325
326
  	if (WARN_ON(bdata->id < 0))
  		return;
  	if (WARN_ON(bdata->id >= num_uarts))
e88d556dc   Sergio Aguirre   OMAP3: serial: Ch...
327
  		return;
f62349ee9   Mika Westerberg   OMAP3: serial - a...
328

6f251e9db   Kevin Hilman   OMAP: UART: omap_...
329
  	list_for_each_entry(uart, &uart_list, node)
40e443993   Tony Lindgren   omap2+: Add struc...
330
  		if (bdata->id == uart->num)
6f251e9db   Kevin Hilman   OMAP: UART: omap_...
331
  			break;
c86845db7   Deepak K   ARM: OMAP2+: UART...
332
333
  	if (!info)
  		info = omap_serial_default_info;
f2eeeae06   Mika Westerberg   OMAP3: serial - f...
334

6f251e9db   Kevin Hilman   OMAP: UART: omap_...
335
  	oh = uart->oh;
6f251e9db   Kevin Hilman   OMAP: UART: omap_...
336
  	name = DRIVER_NAME;
c86845db7   Deepak K   ARM: OMAP2+: UART...
337
  	omap_up.dma_enabled = info->dma_enabled;
6f251e9db   Kevin Hilman   OMAP: UART: omap_...
338
  	omap_up.uartclk = OMAP24XX_BASE_BAUD * 16;
273558b3a   Govindraj.R   ARM: OMAP2+: UART...
339
  	omap_up.flags = UPF_BOOT_AUTOCONF;
ec3bebc6e   Govindraj.R   ARM: OMAP2+: UART...
340
  	omap_up.get_context_loss_count = omap_pm_get_dev_context_loss_count;
94734749a   Govindraj.R   ARM: OMAP2+: UART...
341
342
  	omap_up.set_forceidle = omap_uart_set_forceidle;
  	omap_up.set_noidle = omap_uart_set_noidle;
62f3ec5fb   Govindraj.R   ARM: OMAP2+: UART...
343
  	omap_up.enable_wakeup = omap_uart_enable_wakeup;
c86845db7   Deepak K   ARM: OMAP2+: UART...
344
345
  	omap_up.dma_rx_buf_size = info->dma_rx_buf_size;
  	omap_up.dma_rx_timeout = info->dma_rx_timeout;
a9e210e0b   Jon Hunter   ARM: OMAP2+: UART...
346
  	omap_up.dma_rx_poll_rate = info->dma_rx_poll_rate;
c86845db7   Deepak K   ARM: OMAP2+: UART...
347
  	omap_up.autosuspend_timeout = info->autosuspend_timeout;
94734749a   Govindraj.R   ARM: OMAP2+: UART...
348
349
350
351
352
353
354
355
  
  	/* Enable the MDR1 Errata i202 for OMAP2430/3xxx/44xx */
  	if (!cpu_is_omap2420() && !cpu_is_ti816x())
  		omap_up.errata |= UART_ERRATA_i202_MDR1_ACCESS;
  
  	/* Enable DMA Mode Force Idle Errata i291 for omap34xx/3630 */
  	if (cpu_is_omap34xx() || cpu_is_omap3630())
  		omap_up.errata |= UART_ERRATA_i291_DMA_FORCEIDLE;
6f251e9db   Kevin Hilman   OMAP: UART: omap_...
356
357
358
  
  	pdata = &omap_up;
  	pdata_size = sizeof(struct omap_uart_port_info);
6f251e9db   Kevin Hilman   OMAP: UART: omap_...
359
360
361
  
  	if (WARN_ON(!oh))
  		return;
3528c58eb   Kevin Hilman   OMAP: omap_device...
362
  	pdev = omap_device_build(name, uart->num, oh, pdata, pdata_size,
f718e2c03   Benoit Cousson   ARM: OMAP2+: devi...
363
  				 NULL, 0, false);
3528c58eb   Kevin Hilman   OMAP: omap_device...
364
365
  	WARN(IS_ERR(pdev), "Could not build omap_device for %s: %s.
  ",
6f251e9db   Kevin Hilman   OMAP: UART: omap_...
366
  	     name, oh->name);
08f86b3ea   Govindraj.R   ARM: OMAP2+: UART...
367
368
  	if ((console_uart_id == bdata->id) && no_console_suspend)
  		omap_device_disable_idle_on_suspend(pdev);
40e443993   Tony Lindgren   omap2+: Add struc...
369
  	oh->mux = omap_hwmod_mux_init(bdata->pads, bdata->pads_cnt);
3528c58eb   Kevin Hilman   OMAP: omap_device...
370
  	uart->pdev = pdev;
6f251e9db   Kevin Hilman   OMAP: UART: omap_...
371
372
  
  	oh->dev_attr = uart;
36fc2d15b   Govindraj.R   ARM: OMAP2+: UART...
373
374
  	if (((cpu_is_omap34xx() || cpu_is_omap44xx()) && bdata->pads)
  			&& !uart_debug)
3528c58eb   Kevin Hilman   OMAP: omap_device...
375
  		device_init_wakeup(&pdev->dev, true);
f62349ee9   Mika Westerberg   OMAP3: serial - a...
376
377
378
  }
  
  /**
c86845db7   Deepak K   ARM: OMAP2+: UART...
379
380
   * omap_serial_board_init() - initialize all supported serial ports
   * @info: platform specific data pointer
f62349ee9   Mika Westerberg   OMAP3: serial - a...
381
382
383
384
385
   *
   * Initializes all available UARTs as serial ports. Platforms
   * can call this function when they want to have default behaviour
   * for serial ports (e.g initialize them all as serial ports).
   */
c86845db7   Deepak K   ARM: OMAP2+: UART...
386
  void __init omap_serial_board_init(struct omap_uart_port_info *info)
f62349ee9   Mika Westerberg   OMAP3: serial - a...
387
  {
6f251e9db   Kevin Hilman   OMAP: UART: omap_...
388
  	struct omap_uart_state *uart;
40e443993   Tony Lindgren   omap2+: Add struc...
389
  	struct omap_board_data bdata;
f62349ee9   Mika Westerberg   OMAP3: serial - a...
390

40e443993   Tony Lindgren   omap2+: Add struc...
391
392
393
394
395
  	list_for_each_entry(uart, &uart_list, node) {
  		bdata.id = uart->num;
  		bdata.flags = 0;
  		bdata.pads = NULL;
  		bdata.pads_cnt = 0;
7496ba309   Govindraj.R   ARM: OMAP2+: UART...
396
397
398
  
  		if (cpu_is_omap44xx() || cpu_is_omap34xx())
  			omap_serial_fill_default_pads(&bdata);
c86845db7   Deepak K   ARM: OMAP2+: UART...
399
400
401
402
  		if (!info)
  			omap_serial_init_port(&bdata, NULL);
  		else
  			omap_serial_init_port(&bdata, &info[uart->num]);
40e443993   Tony Lindgren   omap2+: Add struc...
403
  	}
1dbae815a   Tony Lindgren   [ARM] 3145/1: OMA...
404
  }
c86845db7   Deepak K   ARM: OMAP2+: UART...
405
406
407
408
409
410
411
412
413
414
415
416
  
  /**
   * omap_serial_init() - initialize all supported serial ports
   *
   * Initializes all available UARTs.
   * Platforms can call this function when they want to have default behaviour
   * for serial ports (e.g initialize them all as serial ports).
   */
  void __init omap_serial_init(void)
  {
  	omap_serial_board_init(NULL);
  }