From patchwork Thu Feb 23 11:49:41 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Amit Daniel Kachhap X-Patchwork-Id: 6903 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id 3E2FF2447B for ; Thu, 23 Feb 2012 11:49:45 +0000 (UTC) Received: from mail-iy0-f180.google.com (mail-iy0-f180.google.com [209.85.210.180]) by fiordland.canonical.com (Postfix) with ESMTP id B88D9A188B7 for ; Thu, 23 Feb 2012 11:49:44 +0000 (UTC) Received: by mail-iy0-f180.google.com with SMTP id z7so1955798iab.11 for ; Thu, 23 Feb 2012 03:49:44 -0800 (PST) Received: from mr.google.com ([10.50.155.231]) by 10.50.155.231 with SMTP id vz7mr1124611igb.26.1329997784596 (num_hops = 1); Thu, 23 Feb 2012 03:49:44 -0800 (PST) Received: by 10.50.155.231 with SMTP id vz7mr973315igb.26.1329997784437; Thu, 23 Feb 2012 03:49:44 -0800 (PST) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.231.11.10 with SMTP id r10csp8940ibr; Thu, 23 Feb 2012 03:49:43 -0800 (PST) Received: by 10.204.149.198 with SMTP id u6mr402149bkv.138.1329997782517; Thu, 23 Feb 2012 03:49:42 -0800 (PST) Received: from mail-bk0-f50.google.com (mail-bk0-f50.google.com [209.85.214.50]) by mx.google.com with ESMTPS id tq1si582703bkb.64.2012.02.23.03.49.41 (version=TLSv1/SSLv3 cipher=OTHER); Thu, 23 Feb 2012 03:49:42 -0800 (PST) Received-SPF: neutral (google.com: 209.85.214.50 is neither permitted nor denied by best guess record for domain of amit.kachhap@linaro.org) client-ip=209.85.214.50; Authentication-Results: mx.google.com; spf=neutral (google.com: 209.85.214.50 is neither permitted nor denied by best guess record for domain of amit.kachhap@linaro.org) smtp.mail=amit.kachhap@linaro.org Received: by bkty15 with SMTP id y15so1227026bkt.37 for ; Thu, 23 Feb 2012 03:49:41 -0800 (PST) MIME-Version: 1.0 Received: by 10.112.103.8 with SMTP id fs8mr370450lbb.39.1329997781083; Thu, 23 Feb 2012 03:49:41 -0800 (PST) Received: by 10.112.58.162 with HTTP; Thu, 23 Feb 2012 03:49:41 -0800 (PST) In-Reply-To: References: <1329805190-8874-1-git-send-email-amit.kachhap@linaro.org> <1329805190-8874-2-git-send-email-amit.kachhap@linaro.org> Date: Thu, 23 Feb 2012 17:19:41 +0530 Message-ID: Subject: Re: [PATCH V6 1/5] ARM: exynos: Add support AFTR mode on EXYNOS4210 From: Amit Kachhap To: Rob Lee , kgene.kim@samsung.com Cc: linux-samsung-soc@vger.kernel.org, linux-arm-kernel@lists.infradead.org, patches@linaro.org X-Gm-Message-State: ALoCoQmXiDQTAaZtN0LQqnRDxvRb3V9RiVQbVqjfJCACR19nwc9L5xEGjAucFFJZZjzVA8Pq/hMf On 23 February 2012 11:54, Rob Lee wrote: >>  static struct cpuidle_state exynos4_cpuidle_set[] = { >>        [0] = { >> @@ -27,9 +47,17 @@ static struct cpuidle_state exynos4_cpuidle_set[] = { >>                .exit_latency           = 1, >>                .target_residency       = 100000, >>                .flags                  = CPUIDLE_FLAG_TIME_VALID, >> -               .name                   = "IDLE", >> +               .name                   = "C0", >>                .desc                   = "ARM clock gating(WFI)", >>        }, >> +       [1] = { >> +               .enter                  = exynos4_enter_lowpower, >> +               .exit_latency           = 300, >> +               .target_residency       = 100000, >> +               .flags                  = CPUIDLE_FLAG_TIME_VALID, >> +               .name                   = "C1", >> +               .desc                   = "ARM power down", >> +       }, >>  }; > > It looks like you could make this __initdata because your are copying > this state data over to the cpuidle_driver object during > initialization. Hi Rob, This is a good suggestion. I tested it and this works fine. Hi Mr kim, Can this change be accommodated in the current patch series as below or should i send a new patchset? Thanks, Amit Daniel > >> >>  static DEFINE_PER_CPU(struct cpuidle_device, exynos4_cpuidle_device); >> @@ -39,9 +67,100 @@ static struct cpuidle_driver exynos4_idle_driver = { >>        .owner          = THIS_MODULE, >>  }; >> >> +/* Ext-GIC nIRQ/nFIQ is the only wakeup source in AFTR */ >> +static void exynos4_set_wakeupmask(void) >> +{ >> +       __raw_writel(0x0000ff3e, S5P_WAKEUP_MASK); >> +} >> + >> +static unsigned int g_pwr_ctrl, g_diag_reg; >> + >> +static void save_cpu_arch_register(void) >> +{ >> +       /*read power control register*/ >> +       asm("mrc p15, 0, %0, c15, c0, 0" : "=r"(g_pwr_ctrl) : : "cc"); >> +       /*read diagnostic register*/ >> +       asm("mrc p15, 0, %0, c15, c0, 1" : "=r"(g_diag_reg) : : "cc"); >> +       return; >> +} >> + >> +static void restore_cpu_arch_register(void) >> +{ >> +       /*write power control register*/ >> +       asm("mcr p15, 0, %0, c15, c0, 0" : : "r"(g_pwr_ctrl) : "cc"); >> +       /*write diagnostic register*/ >> +       asm("mcr p15, 0, %0, c15, c0, 1" : : "r"(g_diag_reg) : "cc"); >> +       return; >> +} >> + >> +static int idle_finisher(unsigned long flags) >> +{ >> +       cpu_do_idle(); >> +       return 1; >> +} >> + >> +static int exynos4_enter_core0_aftr(struct cpuidle_device *dev, >> +                               struct cpuidle_driver *drv, >> +                               int index) >> +{ >> +       struct timeval before, after; >> +       int idle_time; >> +       unsigned long tmp; >> + >> +       local_irq_disable(); >> +       do_gettimeofday(&before); >> + >> +       exynos4_set_wakeupmask(); >> + >> +       /* Set value of power down register for aftr mode */ >> +       exynos4_sys_powerdown_conf(SYS_AFTR); >> + >> +       __raw_writel(virt_to_phys(s3c_cpu_resume), REG_DIRECTGO_ADDR); >> +       __raw_writel(S5P_CHECK_AFTR, REG_DIRECTGO_FLAG); >> + >> +       save_cpu_arch_register(); >> + >> +       /* Setting Central Sequence Register for power down mode */ >> +       tmp = __raw_readl(S5P_CENTRAL_SEQ_CONFIGURATION); >> +       tmp &= ~S5P_CENTRAL_LOWPWR_CFG; >> +       __raw_writel(tmp, S5P_CENTRAL_SEQ_CONFIGURATION); >> + >> +       cpu_pm_enter(); >> +       cpu_suspend(0, idle_finisher); >> + >> +       scu_enable(S5P_VA_SCU); >> +       cpu_pm_exit(); >> + >> +       restore_cpu_arch_register(); >> + >> +       /* >> +        * If PMU failed while entering sleep mode, WFI will be >> +        * ignored by PMU and then exiting cpu_do_idle(). >> +        * S5P_CENTRAL_LOWPWR_CFG bit will not be set automatically >> +        * in this situation. >> +        */ >> +       tmp = __raw_readl(S5P_CENTRAL_SEQ_CONFIGURATION); >> +       if (!(tmp & S5P_CENTRAL_LOWPWR_CFG)) { >> +               tmp |= S5P_CENTRAL_LOWPWR_CFG; >> +               __raw_writel(tmp, S5P_CENTRAL_SEQ_CONFIGURATION); >> +       } >> + >> +       /* Clear wakeup state register */ >> +       __raw_writel(0x0, S5P_WAKEUP_STAT); >> + >> +       do_gettimeofday(&after); >> + >> +       local_irq_enable(); >> +       idle_time = (after.tv_sec - before.tv_sec) * USEC_PER_SEC + >> +                   (after.tv_usec - before.tv_usec); >> + >> +       dev->last_residency = idle_time; >> +       return index; >> +} >> + >>  static int exynos4_enter_idle(struct cpuidle_device *dev, >>                                struct cpuidle_driver *drv, >> -                             int index) >> +                               int index) >>  { >>        struct timeval before, after; >>        int idle_time; >> @@ -60,6 +179,22 @@ static int exynos4_enter_idle(struct cpuidle_device *dev, >>        return index; >>  } >> >> +static int exynos4_enter_lowpower(struct cpuidle_device *dev, >> +                               struct cpuidle_driver *drv, >> +                               int index) >> +{ >> +       int new_index = index; >> + >> +       /* This mode only can be entered when other core's are offline */ >> +       if (num_online_cpus() > 1) >> +               new_index = drv->safe_state_index; >> + >> +       if (new_index == 0) >> +               return exynos4_enter_idle(dev, drv, new_index); >> +       else >> +               return exynos4_enter_core0_aftr(dev, drv, new_index); >> +} >> + >>  static int __init exynos4_init_cpuidle(void) >>  { >>        int i, max_cpuidle_state, cpu_id; >> @@ -74,19 +209,25 @@ static int __init exynos4_init_cpuidle(void) >>                memcpy(&drv->states[i], &exynos4_cpuidle_set[i], >>                                sizeof(struct cpuidle_state)); >>        } >> +       drv->safe_state_index = 0; >>        cpuidle_register_driver(&exynos4_idle_driver); >> >>        for_each_cpu(cpu_id, cpu_online_mask) { >>                device = &per_cpu(exynos4_cpuidle_device, cpu_id); >>                device->cpu = cpu_id; >> >> -               device->state_count = drv->state_count; >> +               if (cpu_id == 0) >> +                       device->state_count = (sizeof(exynos4_cpuidle_set) / >> +                                              sizeof(struct cpuidle_state)); >> +               else >> +                       device->state_count = 1;        /* Support IDLE only */ >> >>                if (cpuidle_register_device(device)) { >>                        printk(KERN_ERR "CPUidle register device failed\n,"); >>                        return -EIO; >>                } >>        } >> + >>        return 0; >>  } >>  device_initcall(exynos4_init_cpuidle); >> diff --git a/arch/arm/mach-exynos/include/mach/pmu.h b/arch/arm/mach-exynos/include/mach/pmu.h >> index 632dd56..e76b7fa 100644 >> --- a/arch/arm/mach-exynos/include/mach/pmu.h >> +++ b/arch/arm/mach-exynos/include/mach/pmu.h >> @@ -22,11 +22,13 @@ enum sys_powerdown { >>        NUM_SYS_POWERDOWN, >>  }; >> >> +extern unsigned long l2x0_regs_phys; >>  struct exynos4_pmu_conf { >>        void __iomem *reg; >>        unsigned int val[NUM_SYS_POWERDOWN]; >>  }; >> >>  extern void exynos4_sys_powerdown_conf(enum sys_powerdown mode); >> +extern void s3c_cpu_resume(void); >> >>  #endif /* __ASM_ARCH_PMU_H */ >> -- >> 1.7.1 >> >> >> _______________________________________________ >> linux-arm-kernel mailing list >> linux-arm-kernel@lists.infradead.org >> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel --- a/arch/arm/mach-exynos/cpuidle.c +++ b/arch/arm/mach-exynos/cpuidle.c @@ -41,7 +41,7 @@ static int exynos4_enter_lowpower(struct cpuidle_device *dev, struct cpuidle_driver *drv, int index); -static struct cpuidle_state exynos4_cpuidle_set[] = { +static struct cpuidle_state exynos4_cpuidle_set[] __initdata = { [0] = { .enter = exynos4_enter_idle, .exit_latency = 1,