[PATCH v2] OMAP2+: UART: Add mechanism to probe uart pins and configure rx wakeup

Russ Dill russ.dill at gmail.com
Fri May 11 04:34:17 EDT 2012


On Thu, May 10, 2012 at 6:05 AM, Govindraj.R <govindraj.raja at ti.com> wrote:
> From: "Govindraj.R" <govindraj.raja at ti.com>
>
> 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 was 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 at ti.com>
> Cc: Kevin Hilman <khilman at ti.com>
> Cc: Russ Dill <russ.dill at gmail.com>
> Cc: Tony Lindgren <tony at atomide.com>
> Cc: Paul Walmsley <paul at pwsan.com>
> Cc: Ameya Palande <ameya.palande at ti.com>
> Signed-off-by: Govindraj.R <govindraj.raja at ti.com>
> ---
>
> Patching of all board files would be difficult as even I am not aware of all
> omap-board schematics and uart port usage. So individual board file can be
> enabled accordingly for uart usage by calling omap_serial_init_port call
> with right mux data.
>
> for testing: Patch based on v3.4-rc6
> (tested on beagle-xm for off mode rx wakeup)
> Patch targeted for v3.5
>
>  arch/arm/mach-omap2/mux.c    |    3 +-
>  arch/arm/mach-omap2/mux.h    |   10 ++++++
>  arch/arm/mach-omap2/serial.c |   65 +++++++++++++++++++++++++++++++++++++++--
>  3 files changed, 72 insertions(+), 6 deletions(-)
>
> diff --git a/arch/arm/mach-omap2/mux.c b/arch/arm/mach-omap2/mux.c
> index 65c3391..d937ddd 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,
>        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)
>  {
> diff --git a/arch/arm/mach-omap2/mux.h b/arch/arm/mach-omap2/mux.h
> index 69fe060..68927f1 100644
> --- a/arch/arm/mach-omap2/mux.h
> +++ b/arch/arm/mach-omap2/mux.h
> @@ -225,8 +225,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;
> diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c
> index 9fc2f44..c097317 100644
> --- a/arch/arm/mach-omap2/serial.c
> +++ b/arch/arm/mach-omap2/serial.c
> @@ -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,68 @@ 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 (!(rx_mode & 0x07) && !(tx_mode & 0x07))
> +                       omap_serial_fill_uart_tx_rx_pads(bdata, uart);

I realize the comment makes it clear, but it'd probably be better to
just make the code clear. I noticed mux.h has a OMAP_MODE_GPIO(x)
macro for testing if a mux is in mode4. Perhaps its time to start
expanding on that, at least with a macro like:

#define OMAP_MUX_MODE(x) ((x) & OMAP_MUX_MODE7)

So you can do a OMAP_MUX_MODE(rx_mode) == OMAP_MUX_MODE0

> +       }
>  }
>  #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
>
>  char *cmdline_find_option(char *str)
> @@ -295,8 +353,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);
> --
> 1.7.9
>



More information about the linux-arm-kernel mailing list