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>
This commit is contained in:
Govindraj.R 2012-06-05 04:04:11 -07:00 коммит произвёл Tony Lindgren
Родитель 4d04317f6e
Коммит 91930652a2
3 изменённых файлов: 75 добавлений и 6 удалений

Просмотреть файл

@ -217,8 +217,7 @@ static int __init _omap_mux_get_by_name(struct omap_mux_partition *partition,
return -ENODEV;
}
static int __init
omap_mux_get_by_name(const char *muxname,
int __init omap_mux_get_by_name(const char *muxname,
struct omap_mux_partition **found_partition,
struct omap_mux **found_mux)
{

Просмотреть файл

@ -59,6 +59,7 @@
#define OMAP_PIN_OFF_WAKEUPENABLE OMAP_WAKEUP_EN
#define OMAP_MODE_GPIO(x) (((x) & OMAP_MUX_MODE7) == OMAP_MUX_MODE4)
#define OMAP_MODE_UART(x) (((x) & OMAP_MUX_MODE7) == OMAP_MUX_MODE0)
/* Flags for omapX_mux_init */
#define OMAP_PACKAGE_MASK 0xffff
@ -225,8 +226,18 @@ omap_hwmod_mux_init(struct omap_device_pad *bpads, int nr_pads);
*/
void omap_hwmod_mux(struct omap_hwmod_mux_info *hmux, u8 state);
int omap_mux_get_by_name(const char *muxname,
struct omap_mux_partition **found_partition,
struct omap_mux **found_mux);
#else
static inline int omap_mux_get_by_name(const char *muxname,
struct omap_mux_partition **found_partition,
struct omap_mux **found_mux)
{
return 0;
}
static inline int omap_mux_init_gpio(int gpio, int val)
{
return 0;

Просмотреть файл

@ -57,6 +57,7 @@ struct omap_uart_state {
struct list_head node;
struct omap_hwmod *oh;
struct omap_device_pad default_omap_uart_pads[2];
};
static LIST_HEAD(uart_list);
@ -126,11 +127,70 @@ static void omap_uart_set_smartidle(struct platform_device *pdev) {}
#endif /* CONFIG_PM */
#ifdef CONFIG_OMAP_MUX
static void omap_serial_fill_default_pads(struct omap_board_data *bdata)
#define OMAP_UART_DEFAULT_PAD_NAME_LEN 28
static char rx_pad_name[OMAP_UART_DEFAULT_PAD_NAME_LEN],
tx_pad_name[OMAP_UART_DEFAULT_PAD_NAME_LEN] __initdata;
static void __init
omap_serial_fill_uart_tx_rx_pads(struct omap_board_data *bdata,
struct omap_uart_state *uart)
{
uart->default_omap_uart_pads[0].name = rx_pad_name;
uart->default_omap_uart_pads[0].flags = OMAP_DEVICE_PAD_REMUX |
OMAP_DEVICE_PAD_WAKEUP;
uart->default_omap_uart_pads[0].enable = OMAP_PIN_INPUT |
OMAP_MUX_MODE0;
uart->default_omap_uart_pads[0].idle = OMAP_PIN_INPUT | OMAP_MUX_MODE0;
uart->default_omap_uart_pads[1].name = tx_pad_name;
uart->default_omap_uart_pads[1].enable = OMAP_PIN_OUTPUT |
OMAP_MUX_MODE0;
bdata->pads = uart->default_omap_uart_pads;
bdata->pads_cnt = ARRAY_SIZE(uart->default_omap_uart_pads);
}
static void __init omap_serial_check_wakeup(struct omap_board_data *bdata,
struct omap_uart_state *uart)
{
struct omap_mux_partition *tx_partition = NULL, *rx_partition = NULL;
struct omap_mux *rx_mux = NULL, *tx_mux = NULL;
char *rx_fmt, *tx_fmt;
int uart_nr = bdata->id + 1;
if (bdata->id != 2) {
rx_fmt = "uart%d_rx.uart%d_rx";
tx_fmt = "uart%d_tx.uart%d_tx";
} else {
rx_fmt = "uart%d_rx_irrx.uart%d_rx_irrx";
tx_fmt = "uart%d_tx_irtx.uart%d_tx_irtx";
}
snprintf(rx_pad_name, OMAP_UART_DEFAULT_PAD_NAME_LEN, rx_fmt,
uart_nr, uart_nr);
snprintf(tx_pad_name, OMAP_UART_DEFAULT_PAD_NAME_LEN, tx_fmt,
uart_nr, uart_nr);
if (omap_mux_get_by_name(rx_pad_name, &rx_partition, &rx_mux) >= 0 &&
omap_mux_get_by_name
(tx_pad_name, &tx_partition, &tx_mux) >= 0) {
u16 tx_mode, rx_mode;
tx_mode = omap_mux_read(tx_partition, tx_mux->reg_offset);
rx_mode = omap_mux_read(rx_partition, rx_mux->reg_offset);
/*
* Check if uart is used in default tx/rx mode i.e. in mux mode0
* if yes then configure rx pin for wake up capability
*/
if (OMAP_MODE_UART(rx_mode) && OMAP_MODE_UART(tx_mode))
omap_serial_fill_uart_tx_rx_pads(bdata, uart);
}
}
#else
static void omap_serial_fill_default_pads(struct omap_board_data *bdata) {}
static void __init omap_serial_check_wakeup(struct omap_board_data *bdata,
struct omap_uart_state *uart)
{
}
#endif
static char *cmdline_find_option(char *str)
@ -287,8 +347,7 @@ void __init omap_serial_board_init(struct omap_uart_port_info *info)
bdata.pads = NULL;
bdata.pads_cnt = 0;
if (cpu_is_omap44xx() || cpu_is_omap34xx())
omap_serial_fill_default_pads(&bdata);
omap_serial_check_wakeup(&bdata, uart);
if (!info)
omap_serial_init_port(&bdata, NULL);