aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorGovindraj.R <govindraj.raja@ti.com>2012-06-05 07:04:11 -0400
committerTony Lindgren <tony@atomide.com>2012-06-05 07:04:11 -0400
commit91930652a23de0873a157aa1d9962cb878d64451 (patch)
tree88b6a5b85302b875e33b30f6ffa8975a14bcad78 /arch
parent4d04317f6efab7359ae56e50cc9c60e9804b5015 (diff)
OMAP2+: UART: Add mechanism to probe uart pins and configure rx wakeup
The commit (bce492c0 ARM: OMAP2+: UART: Fix incorrect population of default uart pads) removed default uart pads that where getting populated and which was making rx pin wakeup capable. If uart pads were used in different mode by any other module then it would fail since the default pads took over all the uart pins forcefully. With removal of default pads the rx_pad wakeup for console uart while waking up from off mode is broken. Utilise the mux api available to probe the availability of mux pins in uart mode and probe for availability of uart pin in mux mode0 if uart is available as uart pin itself then configure rx pin as wakeup capable. This patch itself doesn't cater to all boards. Boards using uart rx wakeup mechanism should ensure the usage of omap_serial_init_port by configuring required uart ports and pass necessary mux data, till then this probing of uart pins can cater to enabling of rx pad wakeup to most of the boards. This patch can also throw some boot warning from _omap_mux_get_by_name if pin is requested for availability is not present while dynamically probing the uart pins availability such boot warnings can be addressed only when board files are patched with omap_serial_init_port calls passing the right pads needed for a given port. Discussion Threads for reference: http://www.spinics.net/lists/linux-omap/msg69859.html http://www.spinics.net/lists/linux-omap/msg68659.html Cc: Felipe Balbi <balbi@ti.com> Cc: Kevin Hilman <khilman@ti.com> Cc: Russ Dill <russ.dill@gmail.com> Cc: Paul Walmsley <paul@pwsan.com> Cc: Ameya Palande <ameya.palande@ti.com> Signed-off-by: Govindraj.R <govindraj.raja@ti.com> [tony@atomide.com: updated to fix compile when CONFIG_OMAP_MUX is not set] Signed-off-by: Tony Lindgren <tony@atomide.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/mach-omap2/mux.c3
-rw-r--r--arch/arm/mach-omap2/mux.h11
-rw-r--r--arch/arm/mach-omap2/serial.c67
3 files changed, 75 insertions, 6 deletions
diff --git a/arch/arm/mach-omap2/mux.c b/arch/arm/mach-omap2/mux.c
index 80e55c5c9998..4b46b91cca5c 100644
--- a/arch/arm/mach-omap2/mux.c
+++ b/arch/arm/mach-omap2/mux.c
@@ -217,8 +217,7 @@ static int __init _omap_mux_get_by_name(struct omap_mux_partition *partition,
217 return -ENODEV; 217 return -ENODEV;
218} 218}
219 219
220static int __init 220int __init omap_mux_get_by_name(const char *muxname,
221omap_mux_get_by_name(const char *muxname,
222 struct omap_mux_partition **found_partition, 221 struct omap_mux_partition **found_partition,
223 struct omap_mux **found_mux) 222 struct omap_mux **found_mux)
224{ 223{
diff --git a/arch/arm/mach-omap2/mux.h b/arch/arm/mach-omap2/mux.h
index 69fe060a0b75..471e62a74a16 100644
--- a/arch/arm/mach-omap2/mux.h
+++ b/arch/arm/mach-omap2/mux.h
@@ -59,6 +59,7 @@
59#define OMAP_PIN_OFF_WAKEUPENABLE OMAP_WAKEUP_EN 59#define OMAP_PIN_OFF_WAKEUPENABLE OMAP_WAKEUP_EN
60 60
61#define OMAP_MODE_GPIO(x) (((x) & OMAP_MUX_MODE7) == OMAP_MUX_MODE4) 61#define OMAP_MODE_GPIO(x) (((x) & OMAP_MUX_MODE7) == OMAP_MUX_MODE4)
62#define OMAP_MODE_UART(x) (((x) & OMAP_MUX_MODE7) == OMAP_MUX_MODE0)
62 63
63/* Flags for omapX_mux_init */ 64/* Flags for omapX_mux_init */
64#define OMAP_PACKAGE_MASK 0xffff 65#define OMAP_PACKAGE_MASK 0xffff
@@ -225,8 +226,18 @@ omap_hwmod_mux_init(struct omap_device_pad *bpads, int nr_pads);
225 */ 226 */
226void omap_hwmod_mux(struct omap_hwmod_mux_info *hmux, u8 state); 227void omap_hwmod_mux(struct omap_hwmod_mux_info *hmux, u8 state);
227 228
229int omap_mux_get_by_name(const char *muxname,
230 struct omap_mux_partition **found_partition,
231 struct omap_mux **found_mux);
228#else 232#else
229 233
234static inline int omap_mux_get_by_name(const char *muxname,
235 struct omap_mux_partition **found_partition,
236 struct omap_mux **found_mux)
237{
238 return 0;
239}
240
230static inline int omap_mux_init_gpio(int gpio, int val) 241static inline int omap_mux_init_gpio(int gpio, int val)
231{ 242{
232 return 0; 243 return 0;
diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c
index 292d4aaca068..c1b93c752d70 100644
--- a/arch/arm/mach-omap2/serial.c
+++ b/arch/arm/mach-omap2/serial.c
@@ -57,6 +57,7 @@ struct omap_uart_state {
57 57
58 struct list_head node; 58 struct list_head node;
59 struct omap_hwmod *oh; 59 struct omap_hwmod *oh;
60 struct omap_device_pad default_omap_uart_pads[2];
60}; 61};
61 62
62static LIST_HEAD(uart_list); 63static LIST_HEAD(uart_list);
@@ -126,11 +127,70 @@ static void omap_uart_set_smartidle(struct platform_device *pdev) {}
126#endif /* CONFIG_PM */ 127#endif /* CONFIG_PM */
127 128
128#ifdef CONFIG_OMAP_MUX 129#ifdef CONFIG_OMAP_MUX
129static void omap_serial_fill_default_pads(struct omap_board_data *bdata) 130
131#define OMAP_UART_DEFAULT_PAD_NAME_LEN 28
132static char rx_pad_name[OMAP_UART_DEFAULT_PAD_NAME_LEN],
133 tx_pad_name[OMAP_UART_DEFAULT_PAD_NAME_LEN] __initdata;
134
135static void __init
136omap_serial_fill_uart_tx_rx_pads(struct omap_board_data *bdata,
137 struct omap_uart_state *uart)
138{
139 uart->default_omap_uart_pads[0].name = rx_pad_name;
140 uart->default_omap_uart_pads[0].flags = OMAP_DEVICE_PAD_REMUX |
141 OMAP_DEVICE_PAD_WAKEUP;
142 uart->default_omap_uart_pads[0].enable = OMAP_PIN_INPUT |
143 OMAP_MUX_MODE0;
144 uart->default_omap_uart_pads[0].idle = OMAP_PIN_INPUT | OMAP_MUX_MODE0;
145 uart->default_omap_uart_pads[1].name = tx_pad_name;
146 uart->default_omap_uart_pads[1].enable = OMAP_PIN_OUTPUT |
147 OMAP_MUX_MODE0;
148 bdata->pads = uart->default_omap_uart_pads;
149 bdata->pads_cnt = ARRAY_SIZE(uart->default_omap_uart_pads);
150}
151
152static void __init omap_serial_check_wakeup(struct omap_board_data *bdata,
153 struct omap_uart_state *uart)
130{ 154{
155 struct omap_mux_partition *tx_partition = NULL, *rx_partition = NULL;
156 struct omap_mux *rx_mux = NULL, *tx_mux = NULL;
157 char *rx_fmt, *tx_fmt;
158 int uart_nr = bdata->id + 1;
159
160 if (bdata->id != 2) {
161 rx_fmt = "uart%d_rx.uart%d_rx";
162 tx_fmt = "uart%d_tx.uart%d_tx";
163 } else {
164 rx_fmt = "uart%d_rx_irrx.uart%d_rx_irrx";
165 tx_fmt = "uart%d_tx_irtx.uart%d_tx_irtx";
166 }
167
168 snprintf(rx_pad_name, OMAP_UART_DEFAULT_PAD_NAME_LEN, rx_fmt,
169 uart_nr, uart_nr);
170 snprintf(tx_pad_name, OMAP_UART_DEFAULT_PAD_NAME_LEN, tx_fmt,
171 uart_nr, uart_nr);
172
173 if (omap_mux_get_by_name(rx_pad_name, &rx_partition, &rx_mux) >= 0 &&
174 omap_mux_get_by_name
175 (tx_pad_name, &tx_partition, &tx_mux) >= 0) {
176 u16 tx_mode, rx_mode;
177
178 tx_mode = omap_mux_read(tx_partition, tx_mux->reg_offset);
179 rx_mode = omap_mux_read(rx_partition, rx_mux->reg_offset);
180
181 /*
182 * Check if uart is used in default tx/rx mode i.e. in mux mode0
183 * if yes then configure rx pin for wake up capability
184 */
185 if (OMAP_MODE_UART(rx_mode) && OMAP_MODE_UART(tx_mode))
186 omap_serial_fill_uart_tx_rx_pads(bdata, uart);
187 }
131} 188}
132#else 189#else
133static void omap_serial_fill_default_pads(struct omap_board_data *bdata) {} 190static void __init omap_serial_check_wakeup(struct omap_board_data *bdata,
191 struct omap_uart_state *uart)
192{
193}
134#endif 194#endif
135 195
136static char *cmdline_find_option(char *str) 196static char *cmdline_find_option(char *str)
@@ -287,8 +347,7 @@ void __init omap_serial_board_init(struct omap_uart_port_info *info)
287 bdata.pads = NULL; 347 bdata.pads = NULL;
288 bdata.pads_cnt = 0; 348 bdata.pads_cnt = 0;
289 349
290 if (cpu_is_omap44xx() || cpu_is_omap34xx()) 350 omap_serial_check_wakeup(&bdata, uart);
291 omap_serial_fill_default_pads(&bdata);
292 351
293 if (!info) 352 if (!info)
294 omap_serial_init_port(&bdata, NULL); 353 omap_serial_init_port(&bdata, NULL);