[PATCH 3/3] OMAP: UART: use atomic idle notifiers

Govindraj govindraj.ti at gmail.com
Fri Oct 22 08:54:29 EDT 2010


Thanks Kevin,

works fine tested on 3630sdp/zoom3 board.

Tested-by: Govindraj.R <govindraj.raja at ti.com>

Regards,
Govindraj.R

On Thu, Oct 21, 2010 at 5:01 AM, Kevin Hilman
<khilman at deeprootsystems.com> wrote:
> Convert UART idle management routines from custom hooks in the core
> idle path to use new idle notifiers.
>
> Signed-off-by: Kevin Hilman <khilman at deeprootsystems.com>
> ---
>  arch/arm/mach-omap2/pm24xx.c             |    9 +---
>  arch/arm/mach-omap2/pm34xx.c             |    8 ---
>  arch/arm/mach-omap2/serial.c             |   71 +++++++++++++++++++----------
>  arch/arm/plat-omap/include/plat/serial.h |    2 -
>  4 files changed, 47 insertions(+), 43 deletions(-)
>
> diff --git a/arch/arm/mach-omap2/pm24xx.c b/arch/arm/mach-omap2/pm24xx.c
> index cb1b333..47644d2 100644
> --- a/arch/arm/mach-omap2/pm24xx.c
> +++ b/arch/arm/mach-omap2/pm24xx.c
> @@ -40,6 +40,7 @@
>  #include <plat/sram.h>
>  #include <plat/dma.h>
>  #include <plat/board.h>
> +#include <plat/common.h>
>
>  #include "prm.h"
>  #include "prm-regbits-24xx.h"
> @@ -120,19 +121,11 @@ static void omap2_enter_full_retention(void)
>        if (omap_irq_pending())
>                goto no_sleep;
>
> -       omap_uart_prepare_idle(0);
> -       omap_uart_prepare_idle(1);
> -       omap_uart_prepare_idle(2);
> -
>        /* Jump to SRAM suspend code */
>        omap2_sram_suspend(sdrc_read_reg(SDRC_DLLA_CTRL),
>                           OMAP_SDRC_REGADDR(SDRC_DLLA_CTRL),
>                           OMAP_SDRC_REGADDR(SDRC_POWER));
>
> -       omap_uart_resume_idle(2);
> -       omap_uart_resume_idle(1);
> -       omap_uart_resume_idle(0);
> -
>  no_sleep:
>        if (omap2_pm_debug) {
>                unsigned long long tmp;
> diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
> index 4674748..eaed95d 100644
> --- a/arch/arm/mach-omap2/pm34xx.c
> +++ b/arch/arm/mach-omap2/pm34xx.c
> @@ -390,8 +390,6 @@ void omap_sram_idle(void)
>
>        /* PER */
>        if (per_next_state < PWRDM_POWER_ON) {
> -               omap_uart_prepare_idle(2);
> -               omap_uart_prepare_idle(3);
>                omap2_gpio_prepare_for_idle(per_next_state);
>                if (per_next_state == PWRDM_POWER_OFF)
>                                omap3_per_save_context();
> @@ -399,8 +397,6 @@ void omap_sram_idle(void)
>
>        /* CORE */
>        if (core_next_state < PWRDM_POWER_ON) {
> -               omap_uart_prepare_idle(0);
> -               omap_uart_prepare_idle(1);
>                if (core_next_state == PWRDM_POWER_OFF) {
>                        omap3_core_save_context();
>                        omap3_prcm_save_context();
> @@ -445,8 +441,6 @@ void omap_sram_idle(void)
>                        omap3_sram_restore_context();
>                        omap2_sms_restore_context();
>                }
> -               omap_uart_resume_idle(0);
> -               omap_uart_resume_idle(1);
>                if (core_next_state == PWRDM_POWER_OFF)
>                        prm_clear_mod_reg_bits(OMAP3430_AUTO_OFF_MASK,
>                                               OMAP3430_GR_MOD,
> @@ -459,8 +453,6 @@ void omap_sram_idle(void)
>                omap2_gpio_resume_after_idle();
>                if (per_prev_state == PWRDM_POWER_OFF)
>                        omap3_per_restore_context();
> -               omap_uart_resume_idle(2);
> -               omap_uart_resume_idle(3);
>        }
>
>        /* Disable IO-PAD and IO-CHAIN wakeup */
> diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c
> index becf0e3..8a619ff 100644
> --- a/arch/arm/mach-omap2/serial.c
> +++ b/arch/arm/mach-omap2/serial.c
> @@ -73,6 +73,7 @@ struct omap_uart_state {
>        u32 padconf;
>        u32 dma_enabled;
>
> +       struct powerdomain *pwrdm;
>        struct clk *ick;
>        struct clk *fck;
>        int clocked;
> @@ -389,39 +390,31 @@ static void omap_uart_idle_timer(unsigned long data)
>        omap_uart_allow_sleep(uart);
>  }
>
> -void omap_uart_prepare_idle(int num)
> +static void omap_uart_prepare_idle(struct omap_uart_state *uart)
>  {
> -       struct omap_uart_state *uart;
> -
> -       list_for_each_entry(uart, &uart_list, node) {
> -               if (num == uart->num && uart->can_sleep) {
> -                       omap_uart_disable_clocks(uart);
> -                       return;
> -               }
> -       }
> +       if (uart->can_sleep &&
> +           pwrdm_read_next_pwrst(uart->pwrdm) < PWRDM_POWER_ON)
> +               omap_uart_disable_clocks(uart);
>  }
>
> -void omap_uart_resume_idle(int num)
> +static void omap_uart_resume_idle(struct omap_uart_state *uart)
>  {
> -       struct omap_uart_state *uart;
> +       if (uart->can_sleep &&
> +           pwrdm_read_next_pwrst(uart->pwrdm) < PWRDM_POWER_ON) {
> +               omap_uart_enable_clocks(uart);
>
> -       list_for_each_entry(uart, &uart_list, node) {
> -               if (num == uart->num) {
> -                       omap_uart_enable_clocks(uart);
> -
> -                       /* Check for IO pad wakeup */
> -                       if (cpu_is_omap34xx() && uart->padconf) {
> -                               u16 p = omap_ctrl_readw(uart->padconf);
> -
> -                               if (p & OMAP3_PADCONF_WAKEUPEVENT0)
> -                                       omap_uart_block_sleep(uart);
> -                       }
> +               /* Check for IO pad wakeup */
> +               if (cpu_is_omap34xx() && uart->padconf) {
> +                       u16 p = omap_ctrl_readw(uart->padconf);
>
> -                       /* Check for normal UART wakeup */
> -                       if (__raw_readl(uart->wk_st) & uart->wk_mask)
> +                       if (p & OMAP3_PADCONF_WAKEUPEVENT0)
>                                omap_uart_block_sleep(uart);
> -                       return;
>                }
> +
> +               /* Check for normal UART wakeup */
> +               if (__raw_readl(uart->wk_st) & uart->wk_mask)
> +                       omap_uart_block_sleep(uart);
> +               return;
>        }
>  }
>
> @@ -474,6 +467,27 @@ static irqreturn_t omap_uart_interrupt(int irq, void *dev_id)
>        return IRQ_NONE;
>  }
>
> +static int omap_uart_idle_notifier(struct notifier_block *n,
> +                                  unsigned long val,
> +                                  void *p)
> +{
> +       struct omap_uart_state *uart;
> +
> +       if (val == OMAP_IDLE_START)
> +               list_for_each_entry(uart, &uart_list, node)
> +                       omap_uart_prepare_idle(uart);
> +       else
> +               list_for_each_entry(uart, &uart_list, node)
> +                       omap_uart_resume_idle(uart);
> +
> +       return 0;
> +}
> +
> +static bool omap_uart_notifier_enabled;
> +static struct notifier_block omap_uart_notifier = {
> +       .notifier_call = omap_uart_idle_notifier,
> +};
> +
>  static void omap_uart_idle_init(struct omap_uart_state *uart)
>  {
>        int ret;
> @@ -549,6 +563,11 @@ static void omap_uart_idle_init(struct omap_uart_state *uart)
>        ret = request_threaded_irq(uart->irq, NULL, omap_uart_interrupt,
>                                   IRQF_SHARED, "serial idle", (void *)uart);
>        WARN_ON(ret);
> +
> +       if (!omap_uart_notifier_enabled) {
> +               omap_idle_notifier_register(&omap_uart_notifier);
> +               omap_uart_notifier_enabled = true;
> +       }
>  }
>
>  void omap_uart_enable_irqs(int enable)
> @@ -731,6 +750,8 @@ void __init omap_serial_init_port(int port)
>                        break;
>
>        oh = uart->oh;
> +       uart->pwrdm = omap_hwmod_get_pwrdm(oh);
> +       WARN_ON(!uart->pwrdm);
>        uart->dma_enabled = 0;
>  #ifndef CONFIG_SERIAL_OMAP
>        name = "serial8250";
> diff --git a/arch/arm/plat-omap/include/plat/serial.h b/arch/arm/plat-omap/include/plat/serial.h
> index 19145f5..d3ee47b 100644
> --- a/arch/arm/plat-omap/include/plat/serial.h
> +++ b/arch/arm/plat-omap/include/plat/serial.h
> @@ -99,8 +99,6 @@ extern void omap_serial_init_port(int port);
>  extern int omap_uart_can_sleep(void);
>  extern void omap_uart_check_wakeup(void);
>  extern void omap_uart_prepare_suspend(void);
> -extern void omap_uart_prepare_idle(int num);
> -extern void omap_uart_resume_idle(int num);
>  extern void omap_uart_enable_irqs(int enable);
>  #endif
>
> --
> 1.7.2.1
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>



More information about the linux-arm-kernel mailing list